2018-09-19 树形选择排序

一,树形选择排序思想

树形选择排序是模拟锦标赛而发明的一种排序方法,又可以称为锦标赛排序。
下边以一个具体例子来说明整个排序过程


2.png

下边java代码实现:
用数组来存储二叉树.

import java.util.Arrays;

public class TreeSelectSort {

    /**
     * 树形选择排序
     */
    public static void treeSelectSort(Object[] a) {
        int len = a.length;
        int treeSize = 2 * len - 1; // 完全二叉树的节点数
        int ai = 0; // 待排序数组a的元素索引指针。
        Object[] tree = new Object[treeSize]; // 临时的树存储空间
        
        // 由后向前填充此树, 索引从0开始
        for (int i = len-1, j=0; i >= 0; --i,j++) { //填充最后一层叶子节点
            tree[treeSize-1-j] = a[i];
        }
        
        for (int i = treeSize-1; i > 0; i-=2) { // 填充非叶子节点(比较叶子节点大小,然后填入到父节点)
            tree[(i-1)/2] = ((Comparable)tree[i-1]).compareTo(tree[i]) < 0 ? tree[i-1] : tree[i];
        }
        
        // 不断移走最小节点
        int minIndex;
        while (ai < len) {
            Object min = tree[0];   // 最小值
            a[ai++] = min;
            minIndex = treeSize - 1;
            // 找到最小值的索引
            while (((Comparable)tree[minIndex]).compareTo(min) != 0) {
                minIndex--;
            }
            // 将最小值设置为最大(设置为Integer.MAX_VALUE)
            tree[minIndex] = Integer.MAX_VALUE; //设置一个最大值标志
            // 找到其兄弟节点
            while (minIndex > 0) {  // 如果其还有父节点
                if (minIndex % 2 == 0) { //如果为右节点,跟其左节点作比较,取最小值
                    tree[(minIndex-1)/2] = ((Comparable)tree[minIndex]).compareTo(tree[minIndex-1]) > 0 ? tree[minIndex-1] : tree[minIndex];
                    minIndex = (minIndex - 1) / 2; //设置为父节点的索引,继续向上比对
                } else {    //如果为做节点
                    tree[minIndex/2] = ((Comparable)tree[minIndex]).compareTo(tree[minIndex+1]) > 0 ? tree[minIndex+1] : tree[minIndex];
                    minIndex = minIndex / 2; // 设置为父节点的索引,继续向上比对
                }
            }
        }
    }
    
    public static void main(String[] args) {
        Integer[] data = {49,38,65,94,76,13,27,48,63,90};
        treeSelectSort(data);
        System.out.println(Arrays.toString(data));
    }
}

推荐阅读更多精彩内容