如果我们使用顺序机器(不可能进行并行比较),按顺序进行比较,并且我们希望在排序32个随机元素时最大限度地减少处理器时钟周期的数量,我们是否应该使用分类网络或自适应排序算法?
对于n = 32个元素,还没有最佳网络。实际上,如果我们想要最小化CPU时钟周期的数量,最好将32个元素分成4个n = 8的子列表,并在每个子列表上应用最优的排序网络,然后将列表合并在一起?
我们显然在这里使用“平均性能”,因为如果给出已经排序的列表,自适应算法会很幸运。
处理数字我们有以下内容:
对大小为n的列表进行排序:
n = 2的最小比较数为1.
n = 4的最小比较数为5。
n = 8的最小比较数为19。
合并两个大小为n的列表:
合并两个n = 2的列表是2 * n - 1 = 3个比较
合并两个n = 4的列表是2 * n - 1 = 7个比较
合并两个n = 8的列表是2 * n - 1 = 15个比较。
合并两个n = 16的列表是2 * n - 1 = 31个比较。
如果我们将n = 32除以16个n = 2个子列表,则进行比较总数:
如果我们将n = 32分成8个n = 4个子列表,则总比较次数:
如果我们将n = 32分成四个n = 8个子列表,则总比较次数:
现在有人可能认为将n = 32个元素划分为n = 2或n = 4个子列表会更好,因为比较总数较小。但是,mergin要求将数组的部分存储在“不合适的地方”,这可能会抵消较少比较的好处?
我的直觉告诉我,平均而言,非自适应排序网络在总比较方面类似于算法,但排序网络由于开销较少而获胜,我是对的吗?
我试图平均在不到1200个时钟周期内对n = 32个元素进行排序。我正在使用一个简单的 256字* 16位内存和只有四个寄存器工作on a simple sequential machine,因此网络/算法必须简单,快速且不需要大量空间。 ALU仅具有加,减,一位移位,一位旋转,AND和OR功能。内存和ALU操作各占一个时钟周期。
答案 0 :(得分:1)
堆排序是nlogn。索引计算是微不足道的 - 要比较的项目总是具有n,2n + {1,2}的索引,使得它在您的架构中具有计算效率。
堆排序的主力基本上是例程:
while(true){
r=(i+1)*2; l=r-1;
if (*l > * i) {
if (*r > *l) swap(i,r);
else swap(i,l);
}
else {
if (*r >* i) swap(i,r);
else break;
}
}
交换操作必须作为副作用还将地址i
更新为l
或r
。
与教科书解决方案不同,我们不检查子项的地址是否有效,但我们交换空间以加速在数组末尾分配32个零的缓冲区。一旦i
不大于任何一个子节点,遍历到堆的底部就会结束。