十大经典排序算法之堆排序(Java代码实现)

算法原理

堆排序(Heap Sort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近视完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

  1. 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排序。
  2. 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排序。
    堆排序的平均时间复杂度为O(nlogn)。

算法描述

  1. 将初始待排序关键字序列(R1,R2,…,Rn)构建成大顶堆,以此为初始的无序区。
  2. 将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,…,Rn-1)和新的有序区(Rn),且满足R[1,2,…,n-1]<=R[n]。
  3. 由于交换后新的堆顶R[1]可能违反堆的性质,因此需要堆当前无序区(R1,R2,…,Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2,…,Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

动图展示

注:动图来源于菜鸟教程
在这里插入图片描述

算法实现


/**
 * 堆排序
 */
public class HeapSort {

    public static void main(String[] args) {

        int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};

        arr = heapSort(arr);

        printArray(arr);
    }

    public static void printArray(int[] arr){
        for(int a : arr)
            System.out.print(a+",");
        System.out.println();
    }

    public static int[] heapSort(int[] arr){

        int len = arr.length;

        buildMaxHeap(arr,len);

        for(int i=arr.length-1;i>0;i--){
            swap(arr,0,i);
            len--;
            heapify(arr,0,len);
        }

        return arr;
    }

    public static void swap(int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void buildMaxHeap(int[] arr,int len){ // 建立大顶堆

        for(int i = (int) Math.floor(len/2); i>=0; i--){
            heapify(arr,i,len);
        }
    }

    public static void heapify(int[] arr, int index, int len){ //堆调整

        int left=index*2+1;
        int right=index*2+2;
        int largest=index;

        if(left < len && arr[left] > arr[largest]){
            largest = left;
        }

        if(right < len && arr[right] > arr[largest]){
            largest = right;
        }

        if(largest != index){
            swap(arr,index,largest);
            heapify(arr,largest,len);
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值