堆排序

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

假设待排序数组为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 }

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

你可能感兴趣的:(堆排序)