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

简介: 算法介绍算法描述图片演示算法分析代码实现

算法介绍


     树形选择排序(Tree Selection Sort),又称锦标赛排序(Tournament Sort),是一种按锦标赛的思想进行选择排序的方法。简单选择排序花费的时间主要在比较上,每次都会进行很多重复的比较,造成浪费时间。锦标赛排序就是通过记录比较结果,减少比较次数,从而降低时间复杂度。


算法描述


     首先对n个记录的关键字进行两两比较,然后再对胜者进行两两比较,如此重复,直至选出最小关键字的记录为止。这个过程可用一棵有n个叶子结点的完全二叉树描述。


图片演示


用锦标赛排序对下图序列排序。



两两比较构造完全二叉树。



选出最小值,并修改该叶节点关键字为∞。



重复上述过程,直至叶节点全为∞,排序完成。



算法分析


 时间复杂度:O(NlogN)


 空间复杂度:O(N)


 稳定性:稳定(依赖于具体实现)


 缺点:辅助存储空间较多,和∞的比较多余。


 为了弥补这些缺点,威洛姆斯(J·willioms)在1964年提出了另一种形式的选择排序——堆排序。


代码实现

// Java
class TreeSelectionSort {
  public static void treeSelectionSort(int[] data) {
  //长度小于2,无需排序
        if(data.length < 2) {
            return;
        }
        int leafCount = 1;    //满二叉树的叶子节点数,非完全二叉树叶子节点数
        //计算出满二叉树的叶子节点数,节点数大于等于数据队列的长度
        while (leafCount < data.length) {
            leafCount *= 2;
        }
        int[] tree = new int[leafCount * 2];  //树,tree[0]不存储数据
        //data里面的值赋值到树叶子节点
        for (int i = 0; i < data.length; ++i) {
            tree[tree.length - i - 1] = data[i];
        }
        //初始化还没有赋值的树叶子结点,赋值叶子节点最小值
        for (int i = data.length; i < leafCount; ++i) {
            tree[tree.length - i - 1] = Integer.MIN_VALUE;
        }
        //初始化,构建整棵树
        for (int i = tree.length - 1; i > 1; i -= 2) {
            tree[i / 2] = Math.max(tree[i], tree[i - 1]);
        }
        data[data.length - 1] = tree[1];   //将树根节点赋值于data
        int maxIndex;   //堆最大值所对应的叶子节点的下标
        //继续寻找剩下的最大值,逆向存储,升序排序
        for (int i = data.length - 2; i >= 0; --i) {
            maxIndex = tree.length - 1;  //默认堆最后一个位置
            //寻找树根值所在的叶子节点的位置
            while (tree[maxIndex] != tree[1]) {
                --maxIndex;
            }
            tree[maxIndex]=Integer.MIN_VALUE; //该叶子节点赋值最小值
            //调整树,根节点值最大
           while(maxIndex > 1) {
                //左叶子结点
                if (maxIndex % 2 == 0) {
                    tree[maxIndex / 2] = Math.max(tree[maxIndex] ,
                              tree[maxIndex + 1]);
                } else {
                    tree[maxIndex / 2] = Math.max(tree[maxIndex] ,
                              tree[maxIndex - 1]);
                }
                maxIndex /= 2;//指向父节点
            }
            data[i] = tree[1];   //将树根节点赋值于data
        }
    }
}

————————————————

版权声明:本文为CSDN博主「Acx7」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Acx77/article/details/116852010

相关文章
|
5月前
|
搜索推荐
【海贼王的数据航海】排序——直接选择排序|堆排序
【海贼王的数据航海】排序——直接选择排序|堆排序
24 0
|
5月前
|
搜索推荐
【海贼王的数据航海】排序——概念|直接插入排序|希尔排序
【海贼王的数据航海】排序——概念|直接插入排序|希尔排序
29 0
|
6月前
|
搜索推荐
排序——交换排序
排序——交换排序
49 0
|
算法
排序篇(三)----交换排序
排序篇(三)----交换排序
42 0
|
算法 搜索推荐 C语言
【排序】排序这样写才对Ⅱ -冒泡排序与快速排序Ⅰ
常见的排序算法有这些.将会分成几个章节讲完,感兴趣的uu们可以关注下我的排序专栏,方便和后期观看.
84 0
[leetcode 324] 摆动排序 II 思维+排序
[leetcode 324] 摆动排序 II 思维+排序
77 0
|
算法
排序(3)之交换排序
今天小编给大家带来交换排序的内容,对于交换排序中的快速排序在理解上会相对困难一点,小编这里会配合图片给大家细细讲解。那么现在就开始我们今天的主题。
79 0
|
算法 搜索推荐
|
算法 API 索引
算法排序6——快速排序(分治思想)
对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理
129 0
算法排序6——快速排序(分治思想)
|
机器学习/深度学习 算法 API
算法排序5——归并排序&分治思想
算法排序5——归并排序&分治思想
116 0
算法排序5——归并排序&分治思想