これが私がこれまでに持っているものです。ビット配列を使用してパーティションテストの結果を保持し、その場で宛先を計算するサイクルソートのバージョン。これは、N個の比較、<N個のスワップ、および正確に2Nビットの割り当てられたストレージを備えた安定したバイナリパーティションを実行します。
int getDest(int i, BitArray p, int nz)
{ bool b=BitArrayGet(p,i);
int below = BitArrayCount1sBelow(p,i); //1s below
return (b)?(nz+below):i-below;
}
int BinaryCycleSort(Item* a, int n, BitArray p)
{
int i, numZeros = n-BitArrayCount1sBelow(p,n);
BitArray final = BitArrayNew(n);
for (i=0;i<numZeros;i++)
if (!BitArrayGet(final,i))
{ int dest= GetDest(i,p,numZeros);
while (dest!=i)
{ SwapItem(a+i,a+dest);
BitArraySet(final,dest);
dest = getDest(dest,p,numZeros);
}
BitArraySet(final,dest);
}
return numZeros;
}
int BinaryPartition(Item* a, int n, Predicate pPred)
{
int i;
BitArray p = BitArrayNew(n);
for (i=0;i<n;i++)
if (pPred(a+i)) BitArraySet(p,i);
return BinaryCycleSort(a,n,p);
}
これらのヘルパーの使用:
typedef uint32_t BitStore;
typedef BitStore* BitArray;
BitArray BitArrayNew(int N); //returns array of N bits, all cleared
void BitArraySet(BitArray ba, int i); //sets ba[i] to 1
bool BitArrayGet(BitArray ba, int i); //returns ba[i]
int BitArrayCount1sBelow(BitArray ba, int i) //counts 1s in ba[0..i)
明らかに、これは一定のスペースではありません。しかし、これは最終的な目標の構成要素として使用される可能性があると思います。配列全体は、Bビットの固定サイズのBitArrayを使用してN/Bブロックに分割できます。安定したマージを実行しながら、それらの同じビットを再利用する方法はありますか?