排序之堆排序(Java)

Posted 念奕玥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序之堆排序(Java)相关的知识,希望对你有一定的参考价值。

堆排序是利用堆这种数据结构所设计的一种排序算法。堆实际上是一个完全二叉树结构。 完全二叉树:假设一个二叉树的深度为h,除第 h层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边。

堆又分两种:

  • 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
  • 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

堆排序的核心步骤:

  1. 将待排序的数组初始化为大顶堆,该过程即建堆。
  2. 将堆顶元素与最后一个元素进行交换,除去最后一个元素外可以组建为一个新的大顶堆。
  3. 第2步堆顶元素跟最后一个元素交换后,新建立的堆不是大顶堆,需要重新建立大顶堆。重复上面的处理流程,直到堆中仅剩下一个元素。

具体排序过程:

在这里插入图片描述

对于堆节点的访问:
父节点 i 的左子节点的位置:(2*i+1);
父节点 i 的右子节点的位置:(2*i+2);
子节点 i 的父节点所在层数:(i-1)/2;
(以上三个位置可以自己画一个0~n的二叉树推一推)

public class heapsort {
    public static void main(String[] args) {
        int[] arr = {13,5,2,8,32,56,32,421,78,4};
        sort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+"\\t");
        }
    }
    private static void sort(int[] arr){
        //i必须>0,不能是>=0。避免最后一次交换把最小值位置放错
        for (int i = arr.length-1; i >0; i--) {
            maxHeap(arr,i);//此时堆顶是最大数
            //堆顶与当前堆的最后一个元素进行交换
            int temp=arr[0];
            arr[0]=arr[i];
            arr[i]=temp;
        }
    }
    /**
     * 【建立大顶堆】将最大值放置在堆顶
     * @param arr 待排序的数组
     * @param n 数组长度-1
     */
    private static void maxHeap(int[] arr,int n){
        int child;
        //第一个非叶子节点(n-1)/2
        for (int i = (n-1)/2; i>=0; i--) {
            //左子节点位置
            child=2*i+1;
            //若存在右子节点,且左子节点<右子节点
            //让child代表右子节点(较大值)
            if(child!=n && arr[child]<arr[child+1]) child++;

            //父节点若小于子节点中的最大值,则进行交换
            if (arr[i]<arr[child]){
                int temp= arr[i];
                arr[i]=arr[child];
                arr[child]=temp;
            }
        }
    }
}

以上是关于排序之堆排序(Java)的主要内容,如果未能解决你的问题,请参考以下文章

重温基础算法内部排序之堆排序法

Java八大基本排序之堆排序

Java八大排序之堆排序

排序之堆排序(Java)

简易学算法之堆排序

数据结构Java版之堆&堆排序