heap sort algorithm 堆排序算法 java实现

2 篇文章 0 订阅
2 篇文章 0 订阅

heapsort

堆排序

堆排序原理

利用最大堆顶部是最大值的特性,将最大堆顶部的值与最后一个元素交换,将最大值放在末位

假设数组[13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
代码如下

public static void main(String[] args) {
        int[] sort = new int[]{13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
        buildMaxHeapify(sort);
        heapSort(sort);
        System.out.println(Arrays.toString(sort));
}

初始化最大堆,堆的上一层数据是大于下一层的数据的
代码如下

static void buildMaxHeapify(int[] data) {
        //没有子节点的才需要创建最大堆,从最后一个的父节点开始
        int startIndex = getParentIndex(data.length - 1);
        //从尾端开始创建最大堆,每次都是正确的堆
        for (int i = startIndex; i >= 0; i--) {
            maxHeapify(data, data.length, i);
        }
    }
static void maxHeapify(int[] data, int heapSize, int index) {
        //当前点与左右子节点比较
        int left = getChildLeftIndex(index);
        int right = getChildRightIndex(index);
        //记录最大节点位置
        int largest = index;
        //如果当前节点小于左节点,最大值则为左节点
        if (left < heapSize && data[index] < data[left]) {
            largest = left;
        }
        //如果当前节点小于右节点,最大值则为右节点
        if (right < heapSize && data[largest] < data[right]) {
            largest = right;
        }
        //得到最大值后可能需要交换,如果交换了,其子节点可能就不是最大堆了,需要重新调整
        if (largest != index) {
            int temp = data[index];
            data[index] = data[largest];
            data[largest] = temp;
            maxHeapify(data, heapSize, largest);
        }
    }

                          13
            12                          11
      10          9                 8         7
  6        5    4   3             2   1     0

第一层为13

第二层为12 11

第三层为10 9 8 7

第四层为6 5 4 3 2 1 0

上层数据必须大于下层数据

初始化最大堆之后,开始从数组的末位循环,每次将堆长度减1,
并将堆的最后一位和首位交换,交换完之后,再次生成最大堆,
此时堆顶又是最大值,再与之前交换值的位置的前一个位置值做交换。

代码如下

static void heapSort(int[] data) {
        //末尾与头交换,交换后调整最大堆
        for (int i = data.length - 1; i > 0; i--) {
            int temp = data[0];
            data[0] = data[i];
            data[i] = temp;
            maxHeapify(data, i, 0);
        }
    }

以下是堆得获取堆的左节点右节点以及父节点的代码

 /**
     * 父节点位置
     *
     * @param current 当前节点位置
     * @return
     */
    static int getParentIndex(int current) {
        return (current - 1) >> 1;
    }

    /**
     * 左子节点位置,注意括号,加法优先级更高
     *
     * @param current 当前节点位置
     * @return
     */
    static int getChildLeftIndex(int current) {
        return (current << 1) + 1;
    }

    /**
     * 右子节点位置
     *
     * @param current 当前节点位置
     * @return
     */
    static int getChildRightIndex(int current) {
        return (current << 1) + 2;
    }

注:后续会更新算法有关的代码

github地址为 https://github.com/liqingsanijn/algorithm

本篇文章的代码

github地址为 https://github.com/liqingsanijn/heapsort/

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值