堆排序Heapsort的Java代码

Heapsort排序思路

将整个数组看做一个二叉树heap, 下标0为堆顶层, 下标1, 2为次顶层, 而后每层就是"3,4,5,6", "7, 8, 9, 10, 11, 12, 13, 14", ..., 对于其中的每个非叶子节点, 其子节点的下标为 2 * pos + 1 和 2 * pos + 2java

循环进行如下工做:数组

  1. 标记当前堆的右边界
  2. 将堆初始化为大顶堆
  3. 将堆顶置换到右边界, 同时将右边界左移一位(即将堆缩小一格)

将堆初始化为大顶堆的处理this

  1. 从最后一个非叶子节点开始, 其下标为  length / 2 - 1, length为当前的堆大小, 往前挨个处理
  2. 检查节点值, 对节点与其子节点的值大小i进行比较, 若是子节点值比当前节点大, 将最大值的那个子节点换上来
  3. 若是发生了交换, 那么要对发生交换的这个子节点位置也进行检查, 若是还有交换, 则继续往下查, 直到达到叶子节点

 

public class DemoHeapSort {
    // 待排序的数组
    private int[] ints;
    // 当前堆的右边界(下标)
    private int limit;

    public DemoHeapSort(int ... ints) {
        this.ints = ints;
        this.limit = ints.length - 1;
    }

    public void sortAll() {
        while (limit > 0) {
            resort();
            swap(0, limit);
            limit--;
        }
    }

    public void resort() {
        // 起点pos为当前堆length / 2 - 1
        for (int i = (limit + 1) / 2 - 1; i >= 0; i--) {
            int pos = i;
            while (true) {
                pos = check(pos);
                if (pos == 0) {
                    break;
                }
            }
        }
    }

    /**
     * 检查pos位置, 自上而下判断是否都知足大顶堆的要求
     * 其左右子节点的下标为 2*pos+1 和 2*pos+2
     *
     * @param pos 当前要检查的下标
     * @return 若是无调整, 则返回0, 若是有调整, 则返回被调整的子节点下标
     */
    private int check(int pos) {
        int posLeft = 2 * pos + 1;
        int posRight = 2 * pos + 2;
        if (posLeft > limit) { // 没有子节点
            return 0;
        }
        if (posRight > limit) { // 仅有左节点
            if (ints[pos] < ints[posLeft]) {
                swap(pos, posLeft);
                return posLeft;
            } else {
                return 0;
            }
        }
        // 左右节点都有
        if (ints[posLeft] > ints[posRight]) {
            if (ints[pos] < ints[posLeft]) {
                swap(pos, posLeft);
                return posLeft;
            } else {
                return 0;
            }
        } else {
            if (ints[pos] < ints[posRight]) {
                swap(pos, posRight);
                return posRight;
            } else {
                return 0;
            }
        }
    }

    public void print() {
        for (int a : ints) {
            System.out.printf("%3d", a);
        }
        System.out.print("\n");
    }

    private void swap(int a, int b) {
        int tmp = ints[a];
        ints[a] = ints[b];
        ints[b] = tmp;
    }

    public static void main(String[] args) {
        DemoHeapSort hs = new DemoHeapSort(10, 97, 9, 1,63, 64, 8, 17, 33, 7, 21, 0, 7, 75, 13, 18, 2, 99, 87);
        hs.sortAll();
        hs.print();
    }
}

.3d

相关文章
相关标签/搜索