算法:树形选择排序

Posted 小白学算法

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法:树形选择排序相关的知识,希望对你有一定的参考价值。

1
算法描述

     树形选择排序也叫锦标赛排序,我们可以类比比赛过程。有n个待排序的元素,把它们两两一组进行比较,取出较小的,然后在这n/2个较小者中再两两一组进行比较,取出较小的,重复上述步骤,直到取出最小元素。
     这个过程用一棵满二叉树表示,在选出最小关元素后,将这个元素对应的叶子节点的值置为∞,然后把不为∞的兄弟节点移到父节点的位置。一直重复这个过程就可以了

1
算法实现
 1public class Sort {
2    /* 对a[]按升序排列 */
3    public static void treeSelectSort(int[] a) {
4        int len = a.length;// 数组长度
5        int nodeSize = len * 2 - 1; // 对一个满二叉树,节点总数 = 叶子节点数*2-1
6        int[] tree = new int[nodeSize + 1]; // 这里将用数组表示二叉树的存储结构
7        /* 填充叶子节点 */
8        for (int i = len - 1, j = 0; i >= 0; i--, j++) {
9            tree[nodeSize - j] = a[i];
10        }
11        /* 填充其他节点 */
12        for (int i = nodeSize - len; i > 0; i--) {
13            tree[i] = tree[i * 2] < tree[i * 2 + 1] ? tree[i * 2] : tree[i * 2 + 1];
14        }
15        /* 将每次找出的最小元素移走 */
16        int index = 0;// 数组a的索引
17        int minIndex = 0;// 最小值的索引
18        while (index < len) {
19            int min = tree[1]; // 这是tree的根节点,也是最小元素
20            a[index++] = tree[1]; // 将tree中最小的元素取到a[0]中
21            minIndex = nodeSize;
22            /* 从最后的叶子节点开始,直到找到最小值的索引 */
23            while (tree[minIndex] != min) {
24                minIndex--;
25            }
26            tree[minIndex] = Integer.MAX_VALUE; // 将这个最小元素置为最大
27            /* 如果这个节点还有父节点,那么就将它的兄弟节点升到父亲节点位置 */
28            while (minIndex > 1) {// 根结点的索引是1
29                if (minIndex % 2 == 0) {// 这个节点是左节点
30                    tree[minIndex / 2] = tree[minIndex] < tree[minIndex + 1] ? tree[minIndex] : tree[minIndex + 1];
31                    minIndex = minIndex / 2;
32                } else {// 这个节点是右节点
33                    tree[minIndex / 2] = tree[minIndex] < tree[minIndex - 1] ? tree[minIndex] : tree[minIndex - 1];
34                    minIndex = minIndex / 2;
35                }
36            }
37        }
38    }/* treeSelectSort */
39    public static void main(String[] args) {
40        int[] a = { 12, 34, 23, 38, 65, 97, 76, 13 };
41        Sort.treeSelectSort(a);
42        for (int i : a) {
43            System.out.print(i + "  ");
44        }
45    }
46}
3
算法分析

    含有n个叶子节点的完全二叉树的深度为h= [log2n] +1,因此在树形选择排序中,每选出一个最小元素需要进行 [log2n] 次比较(在h深度元素比较一次,在h-1深度比较一次,到h-2深度比较,直到根节点),移动元素的次数小于等于比较次数,所以算法的时间复杂度为 O(nlog2n )。与简单选择排序算法相比,降低了比较次数的数量级,增加了n-1个额外的存储空间存放中间比较结果。


4
算法优化

    主要要解决树形选择排序占用空间比较大的问题,可以采用堆排序,将空间复杂度缩小为1


以上是关于算法:树形选择排序的主要内容,如果未能解决你的问题,请参考以下文章

算法:树形选择排序

Python | 选择排序之树形选择排序

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

常见的排序算法

[golang] 数据结构-树形选择排序(锦标赛排序)

C语言排序