ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

锦标赛排序(树形选择排序)

2022-09-04 11:34:30  阅读:149  来源: 互联网

标签:结点 idx 锦标赛 树形 数组 排序 节点


1.介绍

  树形选择排序(Tree Selection Sort),又称锦标赛排序(Tournament Sort),是一种按照锦标赛思想进行选择排序的不稳定排序。

2.实现原理

  如图所示,给定有8个元素的数组,对该数组进行从小到大的排序。

  第一步,如图所示,根据数组建立一颗满二叉树(胜者树),用于进行‘锦标赛事’的多层次比较。所有的数组元素如同打锦标赛一样全部位于二叉树的叶子节点上,因为是满二叉树,所以所有的数组元素都位于最底层,请读者自行思考。元素数量不足时,用空节点补齐。

  第二步,如图所示,像锦标赛一样,让相邻节点相互‘pk’,把数值较小的节点“晋升”到其父节点上,注意,这一排序目标是从小到大,因此是较小的移到父节点,反之,则是较大的移到父节点。

  如此一来,聪明的读者一定可以自己推出第一次打完锦标赛时树的样子了,如图所示,显而易见,树的根节点的值最小,就像锦标赛中冠军一定是本赛季最强的一个道理。

  选出最小值后,将该叶子节点删除(设为无穷大),接着继续打锦标赛(选手们不累吗),当然选手们并不用那么辛苦,我们不必对整棵树进行操作,因为第二小的值一定是在和第一小的值对峙时败下阵来的,因此第二小的数一定在第一小的晋升的路上,所以只需在这条路上再选出一个第一小的数就行了(图就不画了,太难受了)。

  重复上述步骤n轮你就成功的排好序了,Oh Yeah!

3.算法复杂度分析

  创建和填充二叉树仅需O(n),后继每一轮进行局部刷新二叉树需要O(logn),共进行n-1轮,因此总的时间复杂度为:O(nlogn);

  由于二叉树的结点数量和数组元素个数成正比,所以空间复杂度为O(n)。相对于选择排序,锦标赛排序有效地降低了时间复杂度,但使用的辅助存储空间较多,和∞的比较多余。

  实际编程时,除叶子结点外,并不需要在其它结点保存刷新的元素值,可以使用辅助数组idx[]保存刷新的元素值的原始下标位置即可。如图所示,数组idx[]初始化时,idx[8]=0表示结点8的值为a[0],idx[9]=1表示结点9的值为a[1]......

假设现在更新结点7的值,因为左子结点的编号为14(即7<<1),右子结点的编号为15(即(7<<1)+1),它们指向的元素值分别为27和49,所以idx[7]的值应为6,即a[6]的值。

 

\完结撒花!!!/

 

等等……是不是漏了些什么……

  

 4.参考程序

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f
 3 using namespace std;
 4 int a[1000100],idx[1000100];
 5 int siz = 1;
 6 void Adjust(int p,int Ls,int Rs){
 7     idx[p] = a[idx[Ls]]<a[idx[Rs]]?idx[Ls]:idx[Rs];
 8 }
 9 int main(){
10     int n;
11     cin>>n;
12     while (siz<n){
13         siz<<=1; //siz*=2;
14     }
15     for (int i=0;i<n;i++){
16         cin>>a[i];
17         idx[i+siz] = i; //辅助数组记录数组下标 
18     }
19     for (int i=n;i<siz;i++){
20         a[i] = INF; //空节点设为无穷大( 
21         idx[i+siz] = i;
22     }
23     for (int i = siz-1;i;i--)
24         Adjust(i,i<<1,(i<<1)+1); //节点,左儿子,右儿子下标 
25     for (int i=0;i<n;i++){
26         cout<<a[idx[1]]<<' '; //输出 
27         a[idx[1]] = INF;
28         for (int j=(idx[1]+siz)>>1;j;j>>=1){
29             Adjust(j,j<<1,(j<<1)+1);
30         }
31     }
32     return 0;
33 }

 

标签:结点,idx,锦标赛,树形,数组,排序,节点
来源: https://www.cnblogs.com/reasa/p/16654283.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有