排序算法——堆排序

堆定义:堆是基于完全二叉树的一种数据结构,并且满足条件:每个根节点的数据都比他的叶子节点的数据要大(大顶堆)或小(小顶堆);

堆排序:基于堆这种数据结构进行排序的方法叫做堆排序;

排序方法及步骤:

我们用数组结构来实现堆,假设有一个堆使用长度为length的数组array实现,由数学及数据结构知识可知,堆中最后一个非叶子节点对应的数组下标为length/2-1;假设堆中有一个非叶子节点i,i的左右子节点对应在数组中的下标分别为i*2+1、i*2+2;

知道这些基本的完全二叉树属性,我们接下来就可以实现堆排序算法了。

1、 首先对给与的数据进行初始化构建堆,即使这些数据符合堆的定义;

2、 交换堆顶(最大或最小的节点)和堆尾元素;

3、 调整除去最后一个节点的其他节点,使之满足堆的性质;

4、 返回步骤2继续操作,直至堆节点只有一个;

下面是算法实现,以大顶堆为例:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 void print_log(int *a, int length);
 5 
 6 int adjust_heap(int *arr, int index, int length)
 7 {
 8     int currentValue = arr[index];
 9     for (int i = index*2+1; i < length; i = i*2+1)
10     {
11         if (i+1 < length && arr[i] < arr[i+1])
12         {
13             i++;
14         }
15         
16         if (arr[i] > currentValue)
17         {
18             arr[index] = arr[i];
19             index = i;
20         }
21         else
22         {
23             break;
24         }
25     }
26     
27     arr[index] = currentValue;
28     
29     return 0;
30 }
31 
32 int init_heap(int *arr, int length)
33 {
34     for (int i = length/2-1; i >= 0; --i)
35     {
36         adjust_heap(arr, i, length);
37     }
38     return 0;
39 }
40 
41 int swap(int *arr, int index1, int index2)
42 {
43     int temp = arr[index1];
44     arr[index1] = arr[index2];
45     arr[index2] = temp;
46 }
47 
48 int heap_sort(int *arr, int length)
49 {
50     init_heap(arr, length);
51     
52     print_log(arr, length);
53     
54     for (int i = length-1; i >= 0; --i)
55     {
56         swap(arr, 0, i);
57         adjust_heap(arr, 0, i);
58     }
59     return 0;
60 }
61 
62 void print_log(int *a, int length)
63 {
64     for (int i = 0; i < length; ++i)
65     {
66         cout << a[i] << " , ";
67     }
68     
69     cout << endl;
70 }
71 
72 int main() {
73     int a[10] = {9, 10, 8, 6, 4, 5, 2, 3, 1, 7};
74     
75     int length = sizeof(a)/sizeof(*a);
76     heap_sort(a, length);
77     
78     print_log(a, length);
79 
80     return 0;
81 }

算法重新调整了一下:

  1 #include <iostream>
  2 using namespace std;
  3 
  4 int adjust_heap_recursive(int *arr, int index, int length);
  5 void print_log(int *a, int length);
  6 int swap(int *arr, int index1, int index2);
  7 
  8 /*****
  9 ** summary : create heap.
 10 ** parameter@arr : array to sort.
 11 ** parameter@length : the length of array.
 12 *****/
 13 int init_heap(int *arr, int length)
 14 {
 15     for (int i = 0; i < length/2-1; ++i)
 16     {
 17         adjust_heap_recursive(arr, i, length);
 18     }
 19     return 0;
 20 }
 21 
 22 /*****
 23 ** summary : adjust correct value to index .
 24 ** parameter@arr : array to opera .
 25 ** parameter@index : position .
 26 ** parameter@length : the length of array .
 27 *****/
 28 int adjust_heap_recursive(int *arr, int index, int length)
 29 {
 30     if (2*index+1 == length-1)  // have left child node.
 31     {
 32         if (adjust_heap_recursive(arr, 2*index+1, length)  > arr[index])
 33         {
 34             swap(arr, index, 2*index+1);
 35         }
 36     }
 37     else if (2*index+2 < length)  // have both left and right nodes.
 38     {
 39         if (adjust_heap_recursive(arr, 2*index+1, length) < adjust_heap_recursive(arr, 2*index+2, length))
 40         {
 41             if (adjust_heap_recursive(arr, 2*index+2, length) > arr[index])
 42             {
 43                 swap(arr, index, 2*index+2);
 44             }
 45         }
 46         else
 47         {
 48             if (adjust_heap_recursive(arr, 2*index+1, length) > arr[index])
 49             {
 50                 swap(arr, index, 2*index+1);
 51             }
 52         }
 53     }
 54 
 55     return arr[index];
 56 }
 57 
 58 /*****
 59 ** summary : exchange value between index1 and index2
 60 *****/
 61 int swap(int *arr, int index1, int index2)
 62 {
 63     int temp = arr[index1];
 64     arr[index1] = arr[index2];
 65     arr[index2] = temp;
 66 
 67     return 0;
 68 }
 69 
 70 /*****
 71 ** summary : heap sort.
 72 ** parameter@arr : array to sort.
 73 ** parameter@length : the length of array.
 74 *****/
 75 int sort_heap(int *arr, int length)
 76 {
 77     for (int i = length-1; i >= 0; --i)
 78     {
 79         swap(arr, 0, i);
 80         adjust_heap_recursive(arr, 0, i);
 81     }
 82 
 83     return 0;
 84 }
 85 
 86 /*****
 87 ** summary : heap sort.
 88 *****/
 89 int sort(int *arr, int length)
 90 {
 91     init_heap(arr, length);
 92 
 93     print_log(arr, length);
 94 
 95     sort_heap(arr, length);
 96 
 97     return 0;
 98 }
 99 
100 /*****
101 ** summary : print logs.
102 ** parameter@a : array.
103 ** parameter@length : the length of array.
104 *****/
105 void print_log(int *a, int length)
106 {
107     for (int i = 0; i < length; ++i)
108     {
109         cout << a[i];
110         if (i != length-1)
111         {
112             cout << " ,";
113         }
114     }
115 
116     cout << endl;
117 }
118 
119 int main() {
120     int a[19] = {9, 10, 8, 6, 4, 5, 2, 3, 1, 7, 11, 13, 12, 15, 14, 100, 201, 300, 821};
121 
122     int length = sizeof(a)/sizeof(*a);
123     sort(a, length);
124 
125     print_log(a, length);
126 
127     return 0;
128 }
原文地址:https://www.cnblogs.com/slz-coder150315/p/8570817.html