java数据结构与算法:堆排序

思路:

  1. 把数组构建成二叉堆;
  2. 大根堆根节点为最大值,删除根节点,堆大小减一,把删除的元素放在空出来的堆数组位置,即把最大值放在了数组的末尾;
  3. 重复删除根节点,即找到了第二大、第三大…的元素,直到堆的长度减小到0,即可实现堆排序,时间复杂度为O(N log N)
  4. 用大根堆实现从小到大排序,用小根堆实现从大到小排序。
package com.mindle.heap;

import java.util.Arrays;

public class HeapSort<AnyType extends Comparable<? super AnyType>> {

    public static final int UP = 0; // 从小到大排序
    public static final int DOWN = 1; // 从大到小排序

    /**
     * 用堆排序算法将数组排序
     * 
     * @param array
     *            数组
     * @param size
     *            数组大小
     * @param mode
     *            排序顺序
     */
    public void heapSort(AnyType[] array, int size, int mode) {

        switch (mode) {
        case UP:
            buildHeap1(array, size);
            for (int i = size; i > 0; i--)
                deleteMax(array, i);
            break;
        case DOWN:
            buildHeap2(array, size);
            for (int i = size; i > 0; i--)
                deleteMin(array, i);
            break;
        default:
            break;
        }
    }

    /**
     * 大根堆的下滤
     * 
     * @param array
     *            数组
     * @param size
     *            数组大小
     * @param index
     *            下滤元素的索引号
     */
    private void percolateDown1(AnyType[] array, int size, int index) {
        AnyType temp = array[index];
        int child;

        for (; index <= size / 2 - 1; index = child) {
            child = index * 2 + 1; // 左孩子
            if (child != size - 1 && array[child + 1].compareTo(array[child]) > 0)
                child++;

            if (array[child].compareTo(temp) > 0)
                array[index] = array[child];
            else
                break;
        }

        array[index] = temp;
    }

    /**
     * 小根堆的下滤
     * 
     * @param array
     *            数组
     * @param size
     *            数组大小
     * @param index
     *            下滤元素的索引号
     */
    private void percolateDown2(AnyType[] array, int size, int index) {
        AnyType temp = array[index];
        int child;

        for (; index <= size / 2 - 1; index = child) {
            child = index * 2 + 1; // 左孩子
            if (child != size - 1 && array[child + 1].compareTo(array[child]) < 0)
                child++;

            if (array[child].compareTo(temp) < 0)
                array[index] = array[child];
            else
                break;
        }

        array[index] = temp;
    }

    /**
     * 删除大根堆的根元素,把删除的元素放到堆数组的末尾
     * 
     * @param array
     *            数组
     * @param size
     *            数组大小
     * @return
     */
    private AnyType deleteMax(AnyType[] array, int size) {
        AnyType maxItem = array[0];
        array[0] = array[--size];
        array[size] = maxItem;
        if (size != 0)
            percolateDown1(array, size, 0);

        return maxItem;

    }

    /**
     * 删除小根堆的根元素,把删除的元素放到堆数组的末尾
     * 
     * @param array
     *            数组
     * @param size
     *            数组大小
     * @return
     */
    private AnyType deleteMin(AnyType[] array, int size) {
        AnyType minItem = array[0];
        array[0] = array[--size];
        array[size] = minItem;
        if (size != 0)
            percolateDown2(array, size, 0);

        return minItem;

    }

    /**
     * 构建大根堆堆
     * 
     * @param array
     *            数组
     * @param size
     *            数组大小
     */
    private void buildHeap1(AnyType[] array, int size) {
        for (int i = size / 2 - 1; i >= 0; i--)
            percolateDown1(array, size, i);
    }

    /**
     * 构建小根堆
     * 
     * @param array
     *            数组
     * @param size
     *            数组大小
     */
    private void buildHeap2(AnyType[] array, int size) {
        for (int i = size / 2 - 1; i >= 0; i--)
            percolateDown2(array, size, i);
    }

    // 测试
    public static void main(String[] args) throws Exception {
        Integer[] data = { 7, 8, 9, 4, 6, 1, 2, 3, 5, 17, 14, 11, 12, 15, 18, 13, 16, 19 };
        System.out.println(Arrays.toString(data));
        HeapSort<Integer> heapSort = new HeapSort<>();
        heapSort.heapSort(data, data.length, DOWN);
        System.out.println(Arrays.toString(data));
        heapSort.heapSort(data, data.length, UP);
        System.out.println(Arrays.toString(data));
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值