排序算法堆排序

堆排序原理:首先构建最大堆,然后将第一个元素与最后一个元素交换,接着长度减1,继续构建最大堆,直到排序完成。

堆排序
 1 /*
2 步骤:
3
4 ①.构建最大堆
5 ②.交换首尾元素
6 ③.长度减1,重新构建最大堆
7 ④.循环②、③步骤
8 */
9 #include <iostream>
10 using namespace std;
11
12
13 //元素交换
14 void swap(int &a,int &b)
15 {
16 int temp=a;
17 a=b;
18 b=temp;
19 }
20
21 /*///////////////////////////////////////////////
22 堆排序
23 */
24
25 int left(int i) //返回左儿子位置
26 {
27 return 2*i+1;
28 }
29
30 int right(int i) //返回右儿子位置
31 {
32 return 2*i+2;
33 }
34
35
36 void Heapify(int *a,int i,int len) //对将第i个结点作为根结点的子树进行最大堆化
37 {
38 int l = left(i);
39 int r = right(i);
40 int largest;
41
42 if( a[l]>a[i] && l<len )
43 largest = l;
44 else largest = i;
45
46 if( a[r]>a[largest] && l<len )
47 largest = r;
48
49 if( largest != i )
50 {
51 swap(a[i],a[largest]);
52 Heapify(a,largest,len);
53 }
54 }
55
56
57 void Build_MaxHeap(int *a,int len) //创建最大堆
58 {
59 int i;
60 for(i=len/2;i>=0;i--) //从第len/2个结点进行建堆
61 Heapify(a,i,len);
62 }
63
64
65 void HeapSort(int *a,int len)
66 {
67 int i;
68
69 Build_MaxHeap(a,len);
70
71 for(i=len-1;i>=0;i--)
72 {
73 swap(a[0],a[i]); //每次将第一个元素(即最大的元素)与最后一个元素交换,然后对长度减1个元素进行最大堆化
74 Heapify(a,0,i-1);
75 }
76
77 for(i=0;i<len;i++)
78 cout<<a[i]<<" ";
79 cout<<endl;
80 }
81 /////////////////////////////////////////////////
82
83
84
85
86 int main()
87 {
88 int n,i,a[20];
89 cout<<"请输入数组元素n:"<<endl;
90 cin>>n;
91 cout<<"请输入"<<n<<"个元素:"<<endl;
92 for(i=0;i<n;i++)
93 cin>>a[i];
94 HeapSort(a,n);
95 return 0;
96 }



在初始化构建大顶堆时,每个非终端结点最多比较两次(左右子结点),因此,这个构建的过程时间复杂度为O(n)。

排序过程中,第i次取堆顶记录重建大顶堆的时间复杂度为O(logi),并且需要取n-1次堆顶记录,所有重建堆的时间复杂度为O(nlogn)。总体上来说,堆排序的时间复杂度为:O(nlogn)。

因为初始化构建堆所需比较次数较多,所以堆排序不适合待排序元素较少的情况。

原文地址:https://www.cnblogs.com/chenbin7/p/2197933.html