堆排序

 1 import java.util.Arrays;
 2 
 3 /**
 4  * 堆排序
 5  * 堆介绍:
 6  *    堆是一种重要的数据结构,为一棵完全二叉树, 底层如果用数组存储数据的话,
 7  * 假设某个元素为序号为i(Java数组从0开始,i为0到n-1),如果它有左子树,
 8  * 那么左子树的位置是2i+1,如果有右子树,右子树的位置是2i+2,如果有父节点,
 9  * 父节点的位置是(n-1)/2取整。分为最大堆和最小堆,最大堆的任意子树根
10  * 节点不小于任意子结点,最小堆的根节点不大于任意子结点。
11  * 原理:
12  *    根据上边的说法,假设完全二叉树中任意一个父节点为a[i],那么他的左子节点为a[2*i+1],右子节点为a[2*i+2]。
13  * 根据以上原理,将所有数组元素按照下标构建二叉树,并每添加一次元素,就和其父节点比较,假设构建大顶堆(即父节点
14  * 大于子节点)如果子节点大于父节点,就交换,再将此父节点当做子节点,与其父节点比较,一直比较到比父节点小,或者
15  * 到根节点(堆顶)结束。
16  * */
17 
18 public class HeapSort {
19     public static void main(String[] args) {
20         int[] t = {1, 11, 21, 22, 1, 6, 10, 3, 2, 12, 9, 0, 6, 19, 9, 32, 11, 8, 4, 7, 3, 2};
21         System.out.println("堆排序后:" + Arrays.toString(HeapSort(t)));
22     }
23     
24     public static int[] HeapSort(int[] a){
25         for(int nums=a.length; nums>0; nums--){//构建大顶堆,每次交换后空掉最后一位
26             for(int index=1; index<nums; index++){
27                 while(ifExchange(a, index) && (index-1)>=0){
28                     //如果与父节点做了交换并且父节点的下标大于等于0(即父节点下标存在),继续检查祖父节点与父节点关系
29                     index = (index-1)/2;//让下标定位到父节点
30                 }
31             }
32             int num = a[0];
33             a[0] = a[nums-1];
34             a[nums-1] = num;
35         }
36         return a;
37     }
38     
39     //与父节点交换函数,返回值为布尔类型;假设当大于父节点时交换,返回true,不交换返回false
40     public static boolean ifExchange(int[] a, int index){
41         if(index > 0){//如果不是根节点
42             int parent = (index-1)/2;//计算出父节点的下标值
43             if(a[index] > a[parent]){
44                 int num = a[index];
45                 a[index] = a[parent];
46                 a[parent] = num;
47                 return true;//如果交换,就返回true
48             }
49         }
50         return false;//默认不交换
51     }
52 }

堆排序原理可以参考,很生动:http://dsbryz.iteye.com/blog/1182056

原文地址:https://www.cnblogs.com/K-artorias/p/7482041.html