选择排序
①简单选择排序。
②树形选择排序。←this
③堆排序。
树形选择排序(Tree Selection Sort),又称锦标赛排序(Tournament Sort)是一种按照锦标赛的思想进行选择排序的方法。
描述过程:首先对n个记录的关键字进行两两比较,然后在其中[n/2](取上界)个较大(小)者之间再进行两两比较,选出最大(小)关键字的记录为止。取出最大(小)关键字,将其设为INF,重复上面,选出次大(小)关键字。(咋感觉这么像线段树呢。。。)
时间复杂度为O(nlogn)
10
10 9
0 10 9 6
0 0 0 10 9 8 3 6
0 0 0 0 0 0 10 4 7 9 8 1 2 3 6 5(←倒着的原始数组)
输出10后
9
0 9
0 0 9 6
0 0 0 0 9 8 3 6
0 0 0 0 0 0 0 4 7 9 8 1 2 3 6 5
输出10,9后8
0 8
0 0 8 6
0 0 0 0 0 8 3 6
0 0 0 0 0 0 0 4 7 0 8 1 2 3 6 5
下面代码用的是每次找出最大值
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int N=10; void print(int *tree){ int altm=0; for(int j=1;j<6;j++){ int tm=1; for(int i=1;i<j;i++) tm*=2; for(int i=1;i<=tm;++i) { printf("%d ",tree[altm+i]); } printf("\n");altm+=tm; } } void TreeSelectionSort(int *mData) { int MinValue = 0; int tree[N*4]; // 树的大小 int max,maxIndex,treeSize; int i,n = N,baseSize = 1; while (baseSize < n) baseSize *= 2; treeSize = baseSize * 2 - 1; //printf("treeSize:%d,baseSize:%d\n",treeSize,baseSize); for (i = 0; i < n; i++){//将要排的数字填到树上 tree[treeSize - i] = mData[i]; } for (; i < baseSize; i++){//其余的地方都填上最小值 tree[treeSize - i] = MinValue; } // 构造一棵树,大的值向上构造 for (i = treeSize; i > 1; i -= 2) { tree[i / 2] = (tree[i] > tree[i - 1] ? tree[i] : tree[i - 1]); } n -= 1; while (n != -1) { max = tree[1]; //树顶为最大值 mData[n--] = max; //从大到小倒着贴到原数组上 maxIndex = treeSize; //最大值下标 //print(tree);//打印树 while (tree[maxIndex] != max){ maxIndex--; }//找最大值下标 tree[maxIndex] = MinValue; while (maxIndex > 1){ if (maxIndex % 2 == 0){ tree[maxIndex / 2] = (tree[maxIndex] > tree[maxIndex + 1] ? tree[maxIndex] : tree[maxIndex + 1]); }else{ tree[maxIndex / 2] = (tree[maxIndex] > tree[maxIndex - 1] ? tree[maxIndex] : tree[maxIndex - 1]); } maxIndex /= 2; } } } int main() { int a[N]={5,6,3,2,1,8,9,7,4,10}; TreeSelectionSort(a); for(int i=0;i<N;i++){ printf("%d ",a[i]); } return 0; }
