常见排序算法-----堆排序

 1     // 堆排序,升序用最大堆,降序用最小堆
 2     /*
 3      * 思路: 将数组构建成一个最大堆,从最后一个非叶子节点开始,将它和它的左右子节点中最大的节点相比较
 4      * 如果子节点大则进行交换,再找倒数第二个非叶子节点,同理。 当到倒数第三个叶子节点时,若发生交换
 5      * 则还应判断交换过后有没有对交换过的子节点发生影响,若有影响应进行调整。
 6      * 
 7      * 自底向上建立堆,自顶向下调整堆
 8      */
 9 
10     public static void main(String[] args) {
11         HeapSort hs = new HeapSort();
12         int[] arr = new int[] { 1, 4, 56, 2, 4, 6, 8, 9 };
13         hs.heapSort(arr);
14         for (int i = 0; i < arr.length; i++) {
15             System.out.println(arr[i]);
16         }
17     }
18 
19     public void heapSort(int[] arr) {
20 
21         // 找到最后一个非叶子节点开始遍历,建立最大堆
22         for (int i = arr.length - 2 >> 2; i >= 0; i--) {
23             adjustHeap(arr, i, arr.length);
24 
25         }
26 
27         for (int i = arr.length - 1; i > 0; i--) {
28             // 此时已经建立好最大堆,最大值在最上方,将其与最后一个元素进行交换,即将最大的元素排除,寻找剩余元素中的最大值
29             swap(arr, 0, i);
30             // 交换后重新调整堆结构
31             adjustHeap(arr, 0, i);
32         }
33 
34     }
35 
36     public void swap(int[] arr, int i, int j) {
37         int temp = arr[i];
38         arr[i] = arr[j];
39         arr[j] = temp;
40     }
41 
42     /**
43      * 调整是建立在 已经建立好最大堆的基础上
44      * 
45      * @param arr
46      * @param i
47      * @param length
48      */
49     public void adjustHeap(int[] arr, int i, int length) {
50 
51         int temp = arr[i];
52         for (int j = 2 * i + 1; j < length; j = j * 2 + 1) {// 从i节点的左子节点开始
53             if (j + 1 < length && arr[j] < arr[j + 1]) { // 如果存在右子节点,且右子节点大于左子节点
54                 j++; // 如果是最小堆比较的是最小值 即条件改为 arr[j]>arr[j+1] j++
55             }
56             if (arr[j] > temp) { // 如果最大的子节点大于父节点,交换(此处不需要交换直接赋值即可) //如果arr[j]
57                                     // <temp 进行交换
58                 arr[i] = arr[j];
59                 i = j;
60             } else {
61                 break; // 如果不大于说明不会对后面产生影响直接跳出循环
62             }
63             // 确定i最后所在的位置 将值赋予该位置
64             arr[i] = temp;
65         }
66 
67     }

 堆排序是一种不稳定排序,其中构建初始堆经推导复杂度为O(n),在交换并重建堆的过程中,需交换n-1次,而重建堆的过程中,根据完全二叉树的性质,[log2(n-1),log2(n-2)...1]逐步递减,近似为nlogn

详情  http://www.cnblogs.com/chengxiao/p/6129630.html

posted on 2018-07-21 14:38  Mxxxx  阅读(120)  评论(0编辑  收藏  举报