败者树的建立图解_第六章-外排序算法(2012).ppt

示例 如果做5路归并,让 k = 5,则有 (11-1)/(5-1) = 2,表示有2个度为5的内结点; 但是, u = (11-1) mod (5-1) =2 ≠0,表示有度小于5的结点; 这样就需要加一些空叶结点及一个内结点,内结点在归并树中代替了一个叶结点的位置,故一个叶结点参加这个内结点下的归并,需要增加的空初始归并段数为 k-u-1=5-2-1 = 2 应当补充2个空归并段。则归并树如图所示。 1 3 5 9 7 9 54 20 16 13 38 30 24 166 0 0 五路最佳归并树 它的带权路径长度WPL = (38+20+24+30)*1 + (13+16+7+9)*2 + (1+3+5)*3 = 229。 总读写次数为 :2*WPL=458. 小结 外排序算法是一种涉及外存读写的归并排序过程。 使用败者树进行k路平衡归并时每次比较记录数为[Log2k]。 选择置换可以生成不等长(可以比内存更大)的初始归并段。 对不等长的初始归并段采用最佳归并树进行归并,总读写次数最少。 败者树排序示例 (j) 输出21后调整  (k) 输出29后调整 (l) 输出32后调整 败者树排序示例 (m) 输出44后调整     (n) 输出56后调整, ∞升到loser[0] k 路平衡归并排序算法: void kwaymerge ( Element *r ) { r = new Element[k]; //创建对象数组  int *key = new int[k+1]; //创建外结点数组  int *loser = new int[k]; //创建败者树数组  for ( int i = 0; i < k; i++ ) { //传送参选关键码  InputRecord ( r[i] );  key[i] = r[i].key; } for ( i = 0; i < k; i++)   loser[i] = k;  key[k] = MaxNum; //初始化 for ( i = k-1; i>=0; i-- ) //调整形成败者树  adjust ( key, loser, k, i );  while ( key[loser[0]] != MaxNum ) { //选归并段   q = loser[0]; //最小对象的段号   OutputRecord ( r[q] ); //输出    InputRecord ( r[q] ); //从该段补入对象   key[q] = r[q].key;    adjust ( key, loser, k, q ); //调整  } Output end of run marker; //输出段结束标志 } 自某叶结点key[q]到败者树根结点的调整算法: void adjust ( int key[ ]; int loser[ ]; const int k; const int q ) {//q指示败者树的某外结点key[q], 从该结点起到根//结点进行比较, 将最小 key 对象所在归并段的段//号记入loser[0]。k是外结点key[0..k-1]的个数。 for ( int t = (k+q) / 2; t > 0; t /= 2 ) // t是q的双亲  if ( key[loser[t]] < key[q]) { //败者记入loser[t], 胜者记入q    int temp = q;   q = loser[t];    loser[t] = temp;  } //q与loser[t]交换 loser[0] = q;} 注 意 归并路数 k 的选择不是越大越好。归并路数 k增大时,相应地需要增加输入缓冲区个数。如果可供使用的内存空间不变,势必要减少每个输入缓冲区的容量,使得内外存交换数据的次数增大。 初始归并段的生成 为了减少读写磁盘次数,除增加归并路数 k 外,还可减少初始归并段个数 m。在总对象数n 一定时,要减少 m,必须增大初始归并段长度。 如果规定每个初始归并段等长,则此长度应根据生成它的内存工作区空间大小而定,因而m的减少也就受到了限制。 为了突破这个限制,可采用败者树来生成初始归并段。在使用同样大的内存工作区的情况下,可以生成平均比原来等长情况下大一倍的初始归并段,从而减少参加多路平衡归并排序的初始归并段个数,降低归并趟数。 选择和置换方法 选择和置换的步骤如下:(1) 从输入文件FI中把 k 个对象读入内存中,并构造败者树。(内存中存放对象的数组r可容纳的对象个数为 k ) (2) 利用败者树在 r 中选择一个关键码最小的对象r[q],其

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值