堆排序的Java实现

2 篇文章 0 订阅

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

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);

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值