堆排序的Java实现

来源:互联网 发布:淘宝男士太阳镜 编辑:程序博客网 时间:2024/06/04 18:07

堆排序原理需要先明白,这里直接上代码:

package algorithm;import java.util.Arrays;/** * 通过大顶堆实现堆排序,升序排序 *  * @author bin.zhang * @version 2017年8月31日 下午10:02:07 */public class HeapSort {    public static void main(String[] args) {        int[] arr = { 9, 6, 12, 33, 32, 34, 2, 100, 1000 };        sort(arr);        System.out.println(Arrays.toString(arr));    }    /**     * 将数组分为两部分,一部分为有序区,在数组末尾,另一部分为无序区,堆属于无序区     *      * @author bin.zhang     * @param arr     */    public static void sort(int[] arr) {        int size = arr.length;        buildHeap(arr, size);        for (int i = size - 1; i > 0; i--) {// i为无序区的长度,经过如下两步,长度递减            // 堆顶即下标为0的元素            swap(arr, i, 0);// 1.每次将堆顶元素和无序区最后一个元素交换,即将无序区最大的元素放入有序区            adjustHeap(arr, 0, i); // 2.将无序区调整为大顶堆,即选择出最大的元素。        }    }    /**     * 建立堆,堆是从下往上建立的,因为adjustHeap函数是建立在子树已经为大顶堆     *      * @author bin.zhang     * @param a     * @param size     */    public static void buildHeap(int[] a, int size) {        for (int i = size / 2; i >= 0; i--) {// 从最后一个非叶子节点,才能构成adjustHeap操作的目标二叉树            adjustHeap(a, i, size);        }    }    /**     * 这里将i定义为完全二叉树的根 将完全 二叉树调整为大顶堆,前提是二叉树的根的子树已经为大顶堆     *      * @author bin.zhang     * @param a     * @param i     * @param size     */    public static void adjustHeap(int[] a, int i, int size) {        int lChild = 2 * i + 1; // 左孩子        int rChild = 2 * i + 2; // 右孩子        int max = i; // 临时变量        if (i < size / 2) { // 如果i是叶子节点就结束,这一步很关键(p.s. 不明白请Debug)!!!            if (lChild < size && a[max] < a[lChild])                max = lChild;            if (rChild < size && a[max] < a[rChild])                max = rChild;            if (max != i) {                swap(a, max, i);// 交换后破环了子树的堆结构                adjustHeap(a, max, size);// 递归,调节子树为堆            }        }    }    /**     * 交换数组中的元素     *      * @author bin.zhang     * @param a     * @param i     * @param j     */    private static void swap(int[] a, int i, int j) {        a[i] = a[i] + a[j];        a[j] = a[i] - a[j];        a[i] = a[i] - a[j];    }}

C++的实现代码供参考:

//堆排序#include <iostream>using namespace std;void max_heapify(int*,int,int);int tree_left(int);int tree_right(int);int tree_parent(int);void exchange(int*,int,int);void build_max_heap(int*,int);void heap_sort(int*,int);int main(){    int* a=new int[8];    for(int i=0;i<8;i++){        a[i]=rand()%15;    }    heap_sort(a,8);    for(int i=0;i<8;i++){        cout<<a[i]<<"   ";    }    cout<<endl;    system("pause");    return 0;}int tree_left(int i){    return (i+1)*2-1;}int tree_right(int i){    return (i+1)*2;}int tree_parent(int i){    return (i-1)/2;}void exchange(int* a,int i,int j){    a[i]=a[i]+a[j];    a[j]=a[i]-a[j];    a[i]=a[i]-a[j];}void max_heapify(int* a,int i,int n){    int l=tree_left(i);    int r=tree_right(i);    int largest=i;    if(l<n&&a[l]>a[i]) largest=l;    if(r<n&&a[r]>a[largest]) largest=r;    if(largest!=i){        exchange(a,i,largest);        max_heapify(a,largest,n);    }}void build_max_heap(int* a,int n){    for(int i=tree_parent(n);i>=0;i--){        max_heapify(a,i,n);    }}void heap_sort(int* a,int n){    build_max_heap(a,n);    for(int i=n-1;i>0;i--){        exchange(a,0,i);        max_heapify(a,0,i);    }}