简介
树形排序也被称为锦标赛排序
步骤
1、把n个对象的排序码进行两两比较,得到n/2个排序的优胜者,作为第一步比较的结果留下来
2、然后对这n/2个对象再进行排序码的两两比较,…,如此重复,直到选出一个排序码最小的对象为止。
3、构建一颗包含n个结点的完全二叉树,当二叉树不满(叶子结点个数为奇数),用关键字为∞的结点填满,选出的最小关键字就是这棵树的根节点。在输出了最小关键字之后,为了选择次小关键字,把最小关键字的叶子节点置为∞。
4、继续将叶子结点和其兄弟节点的关键字比较,修改从该叶子节点到根节点上各结点的值,则根节点的值被修改为次小的关键字,直到左右的结点输出为止。
代码
void treeSelectSort(int *a,int len)
if(len%2==1){
a[len] = 10000;//当二叉树不满,用关键字为无穷的结点填满
len++;
}
int treeSize = 2 * len - 1; //完全二叉树的节点数
int low = 1;
int tree[treeSize+1];//临时的树存储空间
//由后向前填充此树,索引从1开始 ,这样在之后给父节点赋值的时候,就不需要分左右节点了
for(int i = len,j=0 ;i >= 1; --i,j++){
//用数组的值来填充叶子节点
tree[treeSize-j] = a[i];
}
for(int i = treeSize+1;i>1;i-=2){
//填充非叶子非根节点
tree[i/2] = tree[i-1]<tree[i]?tree[i-1]:tree[i]; //从后向前找出较小值作为父节点的值
}
int treeMin;
while(low<= len){
int min = tree[1]; //最小值
//把最小值存入数组中
a[low++] = min;//此处是a[low] = min,low++
treeMin = treeSize;
//从后往前找到最小值的索引
while(tree[treeMin]!=min){
treeMin--;
}
tree[treeMin] = 10000;//找到之后把叶子节点置为无穷大
//找到其兄弟节点,把该节点到通往根节点的路径的值都进行更改
while(treeMin> 1){ //如果其还有父节点
tree[treeMin/2] = tree[treeMin]<tree[treeMin+1]? tree[treeMin]:tree[treeMin+1];
treeMin = treeMin/2;
}
}
}
}