这是我目前的进展。这是一个
循环排序的版本,它使用
位数组来保存分区测试的结果,并动态计算目标位置。它执行稳定的二进制分区,需要N次比较,< N次交换,并且需要精确分配2N个
位的存储空间。
int getDest(int i, BitArray p, int nz)
{ bool b=BitArrayGet(p,i);
int below = BitArrayCount1sBelow(p,i);
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);
void BitArraySet(BitArray ba, int i);
bool BitArrayGet(BitArray ba, int i);
int BitArrayCount1sBelow(BitArray ba, int i)
显然这不是常数空间。但我认为这可能被用作最终目标的构建块。整个数组可以使用大小为B位的固定大小BitArray分成N/B块。在执行稳定合并时,是否有一些方法可以重复使用相同的位?