堆排序算法

堆排序算法

  • 堆排序定义:堆排序是将一组无序数组(二叉树)构建成一个堆,分为大顶堆和小顶堆

    • 大顶堆:父节点的值永远大于其左子树和右子树的值
  • 堆排序思路:将堆顶元素与末尾元素交换,然后重新调整结构,使其满足堆的定义,然后反复执行以上步骤,直到整个数组有序。

    • 实现数组元素升序排序,需要先调整为大顶堆,然后依次将堆顶“沉元素”
  • 代码实现:

package com.guodaxia.heapsort;

import java.util.Arrays;

/**
 * 实现堆排序算法,这里采用数组存储二叉树,对其无序二叉树进行升序处理和降序排序
 * @ author Guo daXia
 * @ create 2022/11/28
 */
public class HeapsortDemo {
    public static void main(String[] args) {
        int[] arr={4,9,8,5,6};
        System.out.println("排序前:"+Arrays.toString(arr));
        HeapSort(arr);
        System.out.println("排序后:"+ Arrays.toString(arr));
    }

    //2.编写一个堆排序方法
    public static void HeapSort(int[] arr){
        //从左=>右;从下=>上 进行堆排序
        for (int i=arr.length/2-1;i>-1;i--){
            adjustHeap(arr,i, arr.length);
        }
        int temp;
        //第一个for完成后,已经满足大顶堆定义
        for (int j=arr.length-1;j>0;j--){
            //交换,将堆顶元素“沉入底”
            temp=arr[0];
            arr[0]=arr[j];
            arr[j]=temp;
            //以上步骤打乱了大顶堆定义,故要调整
            //i为0表明将交换到堆顶的元素需要沉到满足大顶堆的定义的位置上
            //j逐渐减小对大顶堆的规模量进行调整
            adjustHeap(arr,0,j);
        }
    }

    /**
     * 1.将一个二叉树(数组),调整为大顶堆
     * @param arr 要调整的数组
     * @param i 除了叶子节点的其他节点索引
     * @param length 待调整数组的长度 ,length是逐渐减少的
     */
    public static void adjustHeap(int[] arr,int i,int length){
       //说明:大顶堆定义:父节点的值大于其左节点或右节点的值,左节点和右节点不需要作比较

        //先比较无序数组左右节点的值大小,然后将值较大的子节点交换父节点

        int temp=arr[i];//暂时存放当前父节点的值
        //k =2*i+1表示左节点 ;k+1表示右节点
        for (int k =2*i+1;k<length;k=2*k+1){
            if (k< arr.length&&arr[k]<arr[k+1]){
                k++;//说明下面代码是右节点进行交换
            }
            if (arr[k]>temp){
                arr[i]=arr[k];
                i=k;
            }else {
                //如果子节点值小于temp
                break;
            }
        }
        //结束循环后,说明已经局部堆顶值最大
        arr[i]=temp;//因为i一直随着k而改变,所以当i确定了,说明i位置就是已经将最大的值放在局部堆顶了,再将temp值放入arr[i]实现交换
    }
}
  • 总结

    • 难点:方法adjustHeap参数的理解及其i=k动态局部堆元素交换的理解;调整后实际交换后还需要进行重新调整。

    • 运算速度:80w数据执行3s,相当快。

    • 面试:常问,且需要掌握代码书写。

posted @ 2022-11-28 12:59  郭培鑫同学  阅读(89)  评论(0编辑  收藏  举报