然后是不断的内部归并,直至排序完毕
第一趟归并(8个初始归并段 → 4个归并段)
第二趟归并(4段 → 2段)
第三趟归并 (2段 → 1段,排序结束)
根据上式,不难想到从减少归并趟数入手来优化算法执行效率
例如,使用4路归并:
第一趟结束后就可以将整个序列分为两个大的归并段:
这时只需在进行一次2路归并就完成了排序,归并趟数减到了两次
从上面的逻辑树还可以看出,减少初始归并段个数r也能减少归并趟数:
tips:关于多路归并与多路平衡归并的概念辨析
”k路平衡归并的问题是随着k增加,每次归并时从k个元素中选取最小元素的比较次数(k-1)也会增加 “
只不过这里的分支结点并不记录关键字的值,而是记录其所属归并段:
当冠军产生后,其所属归并段的下一个元素(6)将加入进来,这时就可以利用之前生成的败者树信息减少比较次数
叶子结点实际上是虚拟的,k路归并的败者树可以用一个长k的数组表示
”增大初始归并段长度(减少初始归并段个数)“
在下面这个用例中,如果按照之前说的”老办法“操作,假设WA只能存放三个记录,那么每个初始归并段也只能有3个记录,对应会产生8个初始归并段
使用置换-选择排序可以产生更少的初始归并段:
置换-选择排序的结果如下,显然归并段的个数r得以减少
因此,要使磁盘的I/O次数减少 → 使归并树的WPL最小 → 哈夫曼树
以初始归并段作为叶子节点,按照构造哈夫曼树的方法(每次取权值最小的两个结点)可以得到如下结果:
k路归并的思路也类似,每次选取k个最小的结点“连接”:
如果初始归并段的个数不足以构造严格的k叉哈夫曼树,则需要增设权值为0的“虚结点”:
得到结果如下:
“如何知道需要添加几个虚段?”
? 2021/7/3
原文:https://www.cnblogs.com/potofsalt/p/14966136.html