堆排序的C语言实现
01 | #include <stdio.h> |
02 | #include <stdlib.h> |
03 |
04 | void HeapSort( int num[], int size); |
05 | void BuildHeap( int num[] , int size); |
06 | void PercolateDown( int num[] , int index, int size); |
07 | void PrintHeap( const char * strMsg, int array[], int nLength); |
08 | void Swap( int num[] , int v, int u); |
09 |
10 | int main( int argc, char *argv[]) |
11 | { |
12 | int data[13]={8,5,4,6,13,7,1,9,12,11,3,10,2}; |
13 | HeapSort(data,13); |
14 | |
15 | system ( "PAUSE" ); |
16 | return 0; |
17 | } |
18 |
19 |
20 | void HeapSort( int num[] , int size) |
21 | { |
22 | int i; |
23 | int iLength=size; |
24 | |
25 | PrintHeap( "Befor Sort:" ,num,iLength); |
26 | |
27 | BuildHeap(num,size); // 建立小顶堆 |
28 | |
29 | for (i = iLength - 1; i >= 1; i--) { |
30 | Swap(num, 0, i); // 交换 |
31 | size--; // 每交换一次让规模减少一次 |
32 | PercolateDown(num, 0,size); // 将新的首元素下滤操作 |
33 | PrintHeap( "Sort Heap:" ,num,iLength); |
34 | } |
35 | } |
36 |
37 | // 建堆方法,只需线性时间建好 |
38 | void BuildHeap( int num[] , int size) { |
39 | int i; |
40 | for (i = size / 2 - 1; i >= 0; i--) { |
41 | PercolateDown(num, i,size); // 进行下滤操作 |
42 | PrintHeap( "Build heap:" ,num,size); |
43 | } |
44 | } |
45 | |
46 | // 对该数进行下滤操作,直到该数比左右节点都小就停止下滤 |
47 | void PercolateDown( int num[] , int index, int size) { |
48 | int min; // 设置最小指向下标 |
49 | while (index * 2 + 1<size) { // 如果该数有左节点,则假设左节点最小 |
50 | min = index * 2 + 1; // 获取左节点的下标 |
51 | if (index * 2 + 2<size) { // 如果该数还有右节点 |
52 | if (num[min] > num[index * 2 + 2]) { // 就和左节点分出最小者 |
53 | min = index * 2 + 2; // 此时右节点更小,则更新min的指向下标 |
54 | } |
55 | } |
56 | // 此时进行该数和最小者进行比较, |
57 | if (num[index] < num[min]) { // 如果index最小, |
58 | break ; // 停止下滤操作 |
59 | } else { |
60 | Swap(num, index, min); // 交换两个数,让大数往下沉 |
61 | index = min; // 更新index的指向 |
62 | } |
63 | } // while |
64 | } |
65 | |
66 | // 给定数组交换两个数的位置 |
67 | void Swap( int num[] , int v, int u) { |
68 | int temp = num[v]; |
69 | num[v] = num[u]; |
70 | num[u] = temp; |
71 | } |
72 |
73 | void PrintHeap( const char * strMsg, int array[], int nLength) |
74 | { |
75 | int i; |
76 | printf ( "%s" ,strMsg); |
77 | for (i=0;i<nLength;i++) |
78 | { |
79 | printf ( "%d " ,array[i]); |
80 | } |
81 | printf ( "\n" ); |
82 | } |
下面也是C语言的实现,稍微改动了下:
01 | #include <stdio.h> |
02 | #include <stdlib.h> |
03 |
04 | void HeapSort( int num[], int size); |
05 | void BuildHeap( int num[] , int size); |
06 | void PercolateDown( int num[] , int index, int size); |
07 | void PrintHeap( const char * strMsg, int array[], int nLength); |
08 | void Swap( int num[] , int v, int u); |
09 |
10 | int main( int argc, char *argv[]) |
11 | { |
12 | /* 将数组看成完全二叉树的中序遍历结果的线性存储 */ |
13 | int data[13]={8,5,4,6,13,7,2,9,12,11,3,10,1}; |
14 | HeapSort(data,13); |
15 | |
16 | system ( "PAUSE" ); |
17 | return 0; |
18 | } |
19 |
20 |
21 | void HeapSort( int num[] , int size) |
22 | { |
23 | int i; |
24 | int iLength=size; |
25 | |
26 | PrintHeap( "Befor Sort:" ,num,iLength); |
27 | |
28 | BuildHeap(num,size); // 建立小顶堆 |
29 | |
30 | for (i = iLength - 1; i >= 1; i--) { |
31 | Swap(num, 0, i); // 交换 |
32 | size--; // 每交换一次让规模减少一次 |
33 | PercolateDown(num, 0,size); // 将新的首元素下滤操作 |
34 | PrintHeap( "Sort Heap:" ,num,iLength); |
35 | } |
36 | } |
37 |
38 | /* 建堆方法,只需线性时间建好; |
39 | 建堆的结果:数组的第一个元素(即树根)是所有元素中的最小值,索引小于等于size/2-1的其它元素(即其它非叶子节点)的值都是其所在子树的最小值 */ |
40 | void BuildHeap( int num[] , int size) { |
41 | int i; |
42 | //从最后一个非叶子节点开始,对每个非叶子节点进型最小根调整,保证每个根节点都是其子树中的最小值 |
43 | for (i = size / 2 - 1; i >= 0; i--) { |
44 | PercolateDown(num, i,size); // 进行下滤操作 |
45 | PrintHeap( "Build heap:" ,num,size); |
46 | } |
47 | } |
48 | |
49 | /* 对该数进行下滤操作,直到该数比左右节点都小就停止下滤。 |
50 | 即对某个根节点的值进行位置下降调整,使该值比其左右子节点都小; |
51 | 若该节点是叶子节点,则无法while循环 */ |
52 | void PercolateDown( int num[] , int index, int size) { |
53 | int min; // 设置最小指向下标 |
54 | while (index * 2 + 1<size) { // 如果该数有左节点,则假设左节点最小 |
55 | min = index * 2 + 1; // 获取左节点的下标 |
56 | if (index * 2 + 2<size) { // 如果该数还有右节点 |
57 | if (num[min] > num[index * 2 + 2]) { // 就和左节点分出最小者 |
58 | min = index * 2 + 2; // 此时右节点更小,则更新min的指向下标 |
59 | } |
60 | } |
61 | // 此时进行该数和最小者进行比较, |
62 | if (num[index] < num[min]) { // 如果index最小, |
63 | break ; // 停止下滤操作 |
64 | } else { |
65 | Swap(num, index, min); // 交换两个数,让大数往下沉 |
66 | index = min; // 更新index的指向 |
67 | } |
68 | } // while |
69 | } |
70 | |
71 | // 给定数组交换两个数的位置 |
72 | void Swap( int num[] , int v, int u) { |
73 | int temp = num[v]; |
74 | num[v] = num[u]; |
75 | num[u] = temp; |
76 | } |
77 |
78 | void PrintHeap( const char * strMsg, int array[], int nLength) |
79 | { |
80 | int i; |
81 | printf ( "%s" ,strMsg); |
82 | for (i=0;i<nLength;i++) |
83 | { |
84 | printf ( "%d " ,array[i]); |
85 | } |
86 | printf ( "\n" ); |
87 | } |