轻松简单的堆排序讲解

堆排序

基本介绍

1、堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。

2、堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆。每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆
注意 : 没有要求结点的左孩子的值和右孩子的值的大小关系。
在这里插入图片描述
映射到数组
在这里插入图片描述在这里插入图片描述

基本思想

1、将待排序序列构造成一个大顶堆

2、此时,整个序列的最大值就是堆顶的根节点。

3、将其与末尾元素进行交换,此时末尾就为最大值。

4、然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

图解

1、从最后一个非叶子结点(arr.length/2-1)开始,此时值为6,从下至上,从左至右进行判断,此时[6,5,9]构成一棵局部树,从中找出最大值9>6,所以9与6互换,此时局部树满足了大顶堆堆要求。
在这里插入图片描述
2、依次类推,[4,9,8]也构成一棵局部树,4和9进行交互即满足了大顶堆堆要求。
在这里插入图片描述
3,但此时[4,5,6]不满足要求,那么继续交换,直至满足整个树为大顶堆要求
在这里插入图片描述
4、当满足大顶堆后,数组第一位即最大的树,与末尾交换,即把最大的数放至最后
在这里插入图片描述
5、交换后,除去最后一位,从新在构建除数组最后一位的大顶堆
在这里插入图片描述
9、如此反复,直到数组第一位排序完

代码

import java.util.Arrays;

public class HeapSort {
    public static void main(String[] args) {
        int arr[] = {5, 4, 3, 2, 1};
        heapSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void heapSort(int arr[]) {
        int temp = 0;
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            adjustHeap(arr, i, arr.length);
        }
        for (int j = arr.length - 1; j > 0; j--) {
        	// 构建顶堆完成后,将最大值(首位)与末尾互换
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            adjustHeap(arr, 0, j);
        }
    }

    /**
     * 完成将以 i 对应对非叶子结点调整成大顶堆
     *
     * @param arr    待调整待数组
     * @param i      表示非叶子结点在数组待索引
     * @param length 表示对多少个元素继续调整,length逐渐减少
     */
    public static void adjustHeap(int arr[], int i, int length) {
        int temp = arr[i];
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
            // 左右子结点判断,找最大的一方
            if (k + 1 < length && arr[k] < arr[k + 1]) {
                k++;
            }
            // 与上述最大的子结点,进行判断,若子结点大,则与之互换
            if (arr[k] > temp) {
                arr[i] = arr[k];
                i = k;
            } else {
                break;
            }
        }
        arr[i] = temp;
    }

}

图片参考:
https://www.cnblogs.com/chengxiao/p/6129630.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值