Java数据结构和算法-堆排序

堆排序

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

       堆排序是一种选择排序,整体主要由构建初始堆+交换堆顶元素和末尾元素并重建堆两部分组成。其中构建初始堆经推导复杂度为O(n),在交换并重建堆的过程中,需交换n-1次,而重建堆的过程中,根据完全二叉树的性质,[log2(n-1),log2(n-2)...1]逐步递减,近似为nlogn。所以堆排序时间复杂度一般认为就是O(nlogn)级。

堆排序Java实现:

package com.algorithm.sort;

/**
 * 堆排序
 */

public class HeapSort {
    public static void main(String[] args) {
        int[] array={39,44,1,0,33,12,37,28,16};
        HeapSort heapSort=new HeapSort();
        heapSort.heapSort(array);
        for(int i=0;i<array.length;i++){
            System.out.println(array[i]);
        }
    }

   public void heapSort(int[] a){
        if (a==null||a.length<=1){
            return;
        }
        //创建大堆
       buildMaxHead(a);
        for(int i=a.length-1;i>=1;i--){
            //最大元素已经排在下表为0的位置
            exchangeElements(a,0,i);//每交换一次沉淀一个最大元素
            maxHeap(a,i,0);
        }
   }

    private static void buildMaxHead(int[] a) {
        int half=(a.length-1)/2;
        for(int i=half;i>=0;i--){
            //只需遍历长度的一半
            maxHeap(a,a.length,i);
        }

    }
    //length表示用于构造大堆的数组长度元素数量
    private static void maxHeap(int[] a, int length, int i) {
        int left=i*2+1;
        int right=i*2+2;
        int largest=i;
        if(left<length&&a[left]>a[i]){
            largest=left;
        }
        if(right<length&&a[right]>a[largest]){
            largest=right;
        }
        if(i!=largest){
            //进行数据交换
            exchangeElements(a,i,largest);
            maxHeap(a,length,largest);
        }
    }
    //在数组a里面进行两个下表元素交换
    private static void exchangeElements(int[] a,int i,int largest) {
        int temp=a[i];
        a[i]=a[largest];
        a[largest]=temp;
    }
}
输出: 0 1 12 16 28 33 37 39 44

代码执行:

思路:

 a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;​​​​​​​

 b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

 c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

链接:https://www.cnblogs.com/chengxiao/p/6129630.html

猜你喜欢

转载自blog.csdn.net/Colin_Qichao/article/details/81411235