码迷,mamicode.com
首页 > 编程语言 > 详细

堆排序

时间:2018-12-31 22:39:18      阅读:329      评论:0      收藏:0      [点我收藏+]

标签:void   sort   一个   []   简单   时间复杂度   时间   子节点   位置   

堆排序是利用堆这种数据结构而设计的一种排序算法,属于选择排序,它的最坏、最好、平均复杂度均为O(Nlog2^N),属于不稳定排序;

堆是具有以下性质的完全二叉树:每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆;每个节点的值都小于或等于其左右孩子节点的值,称为小顶堆;
用简单的公式描述一下堆的定义:
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]

堆排序的基本思想:将待排序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆),此时,整个序列的最大值就是堆顶的根节点。将其与序列的末尾元素进行交换,此时序列末尾就为最大值。然后将剩余n-1个元素重新构造一个堆,这样可以得到n个元素中的次小值。如此反复执行,便能得到一个有序序列了。

总结来说:
1.将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
2.将顶堆元素与序列末尾元素交换,将最值元素沉到数组末端;
3.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列完全有序。

示例代码:
public class Test {

    public static void main(String[] args) {
        
        int[] arr = {6, 3, 8, 2, 9, 1};
        System.out.println("排序前数组为:");
        for(int i : arr) {
            System.out.print(i + ", ");
        }
        System.out.println();
        sort(arr);
        
        System.out.println("排序后数组为:");
        for(int i : arr) {
            System.out.print(i + ", ");
        }
        
    }
    
    public static void sort(int[] arr) {
        for(int i=arr.length/2-1;i>=0;i--) { //构建大顶堆
            adjustHeap(arr,i, arr.length); //从第一个非叶子节点从下至上,从右至左调整结构
        }
        
        for(int j=arr.length-1;j>0;j--) { //调整堆结构+交换堆顶元素与序列末尾元素
            swap(arr, 0, j);
            adjustHeap(arr, 0, j);
        }
    }
    
    public static void adjustHeap(int[] arr, int i, int length) {
        int tmp = arr[i]; //先取出当前父节点元素i
        for(int k=i*2+1;k<length;k=k*2+1) { //从当前元素的左子节点开始
            if(k+1 < length && arr[k] < arr[k+1]) { //如果左子节点小于右子节点,k指向右子节点
                k++;
            }
            if(arr[k] > tmp) { //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                arr[i] = arr[k];
                i = k;
            }
        }
        arr[i] = tmp; //将tmp值放到最终位置
    }
    
    public static void swap(int[] arr, int a, int b) {
        int tmp = arr[a];
        arr[a] = arr[b];
        arr[b] = tmp;
    }
    
}
堆排序的时间复杂度为O(Nlog2^N),空间复杂度为O(1),稳定性不好。

堆排序

标签:void   sort   一个   []   简单   时间复杂度   时间   子节点   位置   

原文地址:https://www.cnblogs.com/yuanfei1110111/p/10203402.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!