堆排序

堆是一棵完全二叉树,其任一非叶结点的关键字不小于(最大堆而言)或不大于(最小堆而言)其左右孩子节点的关键字。

假设待排序数组为A[],那么初始的话我们可以按层次编号建树,对结点i(从零开始)而言,其左右结点分别为2*i+1、2*i+2。

堆排序的算法可大致描述如下:

1.建立最大堆(或最小堆);

2.

for(i = heapSize -1; i > 0; i --)
{
    swap(A[i], A[0]);
    heapSize --;
    RestoreHeap(A, 0);           
}

堆排序整体代码如下:

 1 #include <iostream>
 2 #include <cstdlib>
 3 using namespace std;
 4 int heapSize;
 5 void swap(int &a, int &b)
 6 {
 7     int temp = a;
 8     a = b;
 9     b = temp;
10 }
11 void RestoreHeap(int *A, int i)
12 {
13     int l = 2*i + 1;
14     int r = 2*i + 2;
15     int great;
16     if(l < heapSize && A[l] > A[i])
17         great = l;
18     else 
19         great = i;
20     if(r < heapSize && A[r] > A[great])
21         great = r;
22     if (great != i)
23     {
24         swap(A[i], A[great]);
25         RestoreHeap(A, great);
26     }
27 }
28 //非递归Restore算法
29 void Restore(int *A, int i)
30 {
31     int j = i;
32     int l, r, great;      
33     while(j <= heapSize/2 - 1)
34     {
35         l = 2*j + 1;
36         r = 2*j + 2;
37         if(r < heapSize && A[l] < A[r])
38             great = r;
39         else 
40             great = l;
41         if(A[great] > A[j])
42         {
43             swap(A[great], A[j]);
44             j = great;
45         }
46         else
47             break;
48     }
49 }
50 void BuildMaxHeap(int *A)
51 {
52     for(int i = heapSize/2 - 1; i >= 0; i--)
53         //RestoreHeap(A, i);
54         Restore(A, i);
55 }
56 void HeapSort(int *A)
57 {
58     BuildMaxHeap(A);
59     for(int i = heapSize - 1; i > 0; i--)
60     {
61         swap(A[i], A[0]);
62         heapSize --;
63         //RestoreHeap(A, 0);
64         Restore(A, 0);
65     }
66 }
67 int main()
68 {
69     int *A = NULL;
70     cout<<"Input heap size and its values:"<<endl;
71     while(cin>>heapSize && heapSize)
72     {
73         try
74         {
75             A = new int[heapSize];
76         }
77         catch(const bad_alloc &e)
78         {
79             cerr<<"bad alloc error:"<<e.what()<<endl;
80             abort();
81         }
82         int i;
83         for(i = 0; i < heapSize; i++)
84         {
85             cin>>A[i];
86         }
87         int size = heapSize;
88         HeapSort(A);
89         cout<<"After sort:"<<endl;
90         for(i = 0; i < size; i++)
91             cout<<A[i]<<" ";
92         cout<<endl<<"Input heap size and its values:"<<endl;
93         delete A;
94         A = NULL;
95     }
96     return 0;
97 }

堆排序是不稳定的排序,因为在重建堆的时候并没有考虑原来的顺序,即便关键字相同的元素也有可能进行交换。

如原创文章,转载请注明:转自http://www.cnblogs.com/xpowerlord/
原文地址:https://www.cnblogs.com/xpowerlord/p/3713478.html