堆排序讲解及Java实现

来源:互联网 发布:linux查看cpu进程 编辑:程序博客网 时间:2024/06/10 04:17

堆排序

一、首先先解释一下什么是堆?

堆可以看做是一颗树,而且是一颗完全二叉树。不同的二叉树请看下图:
各种树

二、堆排序的特性
首先介绍复杂度:
时间复杂度:O(nlgn)…
空间复杂度:O(1)
鉴于堆这种数据结构本身的特性可以发现(以最大堆为例),根节点为数组中最大元素,左右子节点小于等于根节点。
另外,假设某个元素为序号为i(Java数组从0开始,i为0到n-1), 如果它有左子树,那么左子树的位置是2i+1,如果有右子树,右子树的位置是2i+2,如果有父节点,父节点的位置是(n-1)/2取整。

三、堆排序步骤
堆排序主要分为两步:
1. 根据数组构建一个堆
2. 排序

直接上代码

public class HeapSort {    static int N = 0;    public static void main(String[] args) {        int array[]={5,1,3,11,2,6,7,8,4,9,10,12};        N = array.length;        printArray(array);        buildHeap(array);        sort(array);    }    private static void sort(int[] array) {        System.out.println("开始排序...");        for(int i=N-1;i>=1;i--){            exch(array,0,i);//交换根元素和尾元素            adjustHeap(array,i,0);        }        System.out.println("排序完毕!结果如下:");        printArray(array);    }    private static void buildHeap(int[] array) {        System.out.println("开始构建堆...");        //构建堆        for(int i=(array.length-1)/2;i>=0;i--){            //从最后一颗子树开始            adjustHeap(array,array.length,i);        }        System.out.println("堆构建完毕!结果如下:");        printArray(array);    }    private static void printArray(int[] array) {        for(int n:array){            System.out.print(n+",");        }        System.out.println("");    }    /**     * Parent = (k-1)/2     * Left = 2i+1;     * Right = 2i+2;     * @param a 数组     * @param k 下标     */    private static void adjustHeap(int[] a,int length,int k){        while(2*k+2 <= length ){            int left = 2*k+1;            int max = left;            if(left + 1 < length){                int right = left+1;                if(less(a,left,right)){                    max = right;                }            }            if(less(a,max,k)){                break;            }            exch(a,k,max);            printArray(a);            k = max;         }  }    private static boolean less(int[] a,int i,int j){        return a[i]<a[j];    }    private static void exch(int[] a,int i,int j){        int tmp = a[i];        a[i] = a[j];        a[j] = tmp;    }}

以上就是堆排序的Java实现代码,基本思想就是先构建堆,从最后一个子树开始逐一构建;当堆构建完毕之后,基于最大堆的特性,把根元素和最后一个未排序的元素互换,交换完毕后再重新构建堆。

注:如果想要倒序排列数组,则需要构建最小堆,把代码中的less方法修改成>即可。

1 0
原创粉丝点击