堆排序

时间复杂度:平均时间复杂度O(nlogn),最坏时间复杂度O(n*n)
空间复杂度:O(1)

   public void heapSort(int[] list) {

        // 循环建立初始堆

        for (int i = list.length / 2; i >= 0; i--) {

            HeapAdjust(list, i, list.length - 1);

        }


        // 进行n-1次循环,完成排序

        for (int i = list.length - 1; i > 0; i--) {

            // 最后一个元素和第一元素进行交换

            int temp = list[i];

            list[i] = list[0];

            list[0] = temp;


            // 筛选 R[0] 结点,得到i-1个结点的堆
  
            HeapAdjust(list, 0, i);

        }

    }

    public void HeapAdjust(int[] array, int parent, int length) {


        int temp = array[parent]; // temp保存当前父节点

        int child = 2 * parent + 1; // 先获得左孩子 ,从0开始标记左孩子就是2*i+1,从1标记是2*i


        while (child < length) {
            // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点

            if (child + 1 < length && array[child] < array[child + 1]) {

                child++;

            }


            // 如果父结点的值已经大于孩子结点的值,则直接结束
            if (temp >= array[child]) {
                break;
            }


            // 把孩子结点的值赋给父结点

            array[parent] = array[child];


            // 选取孩子结点的左孩子结点,继续向下筛选

            parent = child;

            child = 2 * child + 1;

        }


        array[parent] = temp;

      

    }

原文链接:
https://blog.csdn.net/sun_ru/article/details/52004044

给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。 首先根据该数组元素构建一个完全二叉树,得到

在这里插入图片描述
然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:

在这里插入图片描述
20和16交换后导致16不满足堆的性质,因此需重新调整

在这里插入图片描述
这样就得到了初始堆。

先进行一次调整时其成为大顶堆,

即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了
在这里插入图片描述
此时3位于堆顶不满堆的性质,则需调整继续调整

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值