有意思的排序算法堆排序
堆排序,是一个非常优秀的排序算法,像合并排序而不像插入排序,其运行时间为O(nlgn),像插入排序而不像合并排序,它是一种原地排序算法,所以说,堆排序将插入排序和合并排序的优点结合起来了。
堆排序借助于堆数据结构,(二叉)堆是一个数组,它可以被视为一棵完全二叉树,树中每个节点与数组中存放该节点值得那个元素对应。
堆排序算法可以分为以下几步:
1) 建立原先数列对应的最大(或最小)堆。
2) 重复n-1次循环,每次选出一个最大(或最小)值,并放到合适的位置。
Java代码实现如下:
1 public class HeapSort implements SortAlgorithm {
2
3 private IntArray A = null ;
4
5 public HeapSort() {
6 A = new IntArray();
7 }
8
9 private class IntArray {
10 public int [] aArray = null ;
11 public int heapSize = 0 ;
12 }
13
14 @Override
15 public void sort( int [] A) {
16 maxHeapSort(A);
17 }
18
19 @Override
20 public void sort( int [] A, boolean isInc) {
21 if (isInc) {
22 maxHeapSort(A);
23 } else {
24 minHeapSort(A);
25 }
26 }
27
28 /**
29 * 最大堆排序,升序
30 *
31 * @param A
32 * int数组
33 */
34 private void maxHeapSort( int [] A) {
35 this .A.aArray = A;
36 this .A.heapSize = A.length;
37 buildMaxHeap( this .A);
38 for ( int i = A.length; i >= 2; i-- ) {
39 exchange(1 , i);
40 this .A.heapSize = this .A.heapSize - 1 ;
41 maxHeapify( this .A, 1 );
42 }
43 }
44
45 /**
46 * 最小堆排序,降序
47 *
48 * @param A
49 * int数组
50 */
51 private void minHeapSort( int [] A) {
52 this .A.aArray = A;
53 this .A.heapSize = A.length;
54 buildMinHeap( this .A);
55 for ( int i = A.length; i >= 2; i-- ) {
56 exchange(1 , i);
57 this .A.heapSize = this .A.heapSize - 1 ;
58 minHeapify( this .A, 1 );
59 }
60 }
61
62 /**
63 * 使得以index为根的子树成为最大堆
64 *
65 * @param A
66 * int数组
67 * @param index
68 * 以index为根,从1开始
69 */
70 private void maxHeapify(IntArray A, int index) {
71 while (index < A.heapSize / 2 + 1 ) {
72 int left = left(index);
73 int right = right(index);
74 int largest = 0 ;
75 if (left <= A.heapSize && A.aArray[left - 1] > A.aArray[index - 1 ]) {
76 largest = left;
77 } else {
78 largest = index;
79 }
80 if (right <= A.heapSize
81 && A.aArray[right - 1] > A.aArray[largest - 1 ]) {
82 largest = right;
83 }
84 if (index != largest) {
85 exchange(index, largest);
86 index = largest;
87 } else {
88 index = A.heapSize / 2 + 1 ;
89 }
90 }
91 }
92
93 /**
94 * 使得以index为根的子树成为最小堆
95 *
96 * @param A
97 * int数组
98 * @param index
99 * 以index为根,从1开始
100 */
101 private void minHeapify(IntArray A, int index) {
102 while (index < A.heapSize / 2 + 1 ) {
103 int left = left(index);
104 int right = right(index);
105 int smallest = 0 ;
106 if (left <= A.heapSize && A.aArray[left - 1] < A.aArray[index - 1 ]) {
107 smallest = left;
108 } else {
109 smallest = index;
110 }
111 if (right <= A.heapSize
112 && A.aArray[right - 1] < A.aArray[smallest - 1 ]) {
113 smallest = right;
114 }
115 if (index != smallest) {
116 exchange(index, smallest);
117 index = smallest;
118 } else {
119 index = A.heapSize / 2 + 1 ;
120 }
121 }
122 }
123
124 /**
125 * 建最大堆
126 *
127 * @param A
128 * int数组
129 */
130 private void buildMaxHeap(IntArray A) {
131 for ( int i = A.aArray.length / 2; i >= 1; i-- ) {
132 maxHeapify(A, i);
133 }
134 }
135
136 /**
137 * 建最小堆
138 *
139 * @param A
140 * int数组
141 */
142 private void buildMinHeap(IntArray A) {
143 for ( int i = A.aArray.length / 2; i >= 1; i-- ) {
144 minHeapify(A, i);
145 }
146 }
147
148 private int left( int index) {
149 return 2 * index;
150 }
151
152 private int right( int index) {
153 return 2 * index + 1 ;
154 }
155
156 private void exchange( int i, int j) {
157 int temp = A.aArray[i - 1 ];
158 A.aArray[i - 1] = A.aArray[j - 1 ];
159 A.aArray[j - 1] = temp;
160 }
161
162 }
PS:zhuangzhuang1988兄再来一个~O(∩_∩)O哈哈~
标签: 算法
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did49211