堆排序

这里以小顶堆为例:

思路:

对于堆排序来说,首先需要做的是要建堆,建堆是一个不断调整堆的过程,能够在线性时间内完成。

堆排序的过程
1、建堆,建堆是不断调整堆的过程,从len/2处开始调整,一直到第一个节点,此处len是堆中元素的个数。建堆的过程是线性的过程,从len/2到0处一直调用调整堆的过程,相当于o(h1)+o(h2)…+o(hlen/2) 其中h表示节点的深度,len/2表示节点的个数,这是一个求和的过程,结果是线性的O(n)。
2、调整堆:调整堆在构建堆的过程中会用到,而且在堆排序过程中也会用到。利用的思想是比较节点i和它的孩子节点left(i),right(i),选出三者最大(或者最小)者,如果最大(小)值不是节点i而是它的一个孩子节点,那边交互节点i和该节点,然后再调用调整堆过程,这是一个递归的过程。调整堆的过程时间复杂度与堆的深度有关系,是lgn的操作,因为是沿着深度方向进行调整的。
3、堆排序:堆排序是利用上面的两个过程来进行的。首先是根据元素构建堆。然后将堆的根节点取出(一般是被最后一个节点覆盖掉),将前面len-1个节点继续进行堆调整的过程,然后再将根节点取出,这样一直到所有节点都取出。堆排序过程的时间复杂度是O(nlgn)。因为建堆的时间复杂度是O(n)(调用一次);调整堆的时间复杂度是lgn,调用了n-1次,所以堆排序的时间复杂度是O(nlgn)

代码:

 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <vector>
 8 #include <cstdlib>
 9 
10 using namespace std;
11 
12 #define PI acos(-1.0)
13 #define EPS 1e-10
14 #define lll __int64
15 #define ll long long
16 #define INF 0x7fffffff
17 
18 //tree为小根堆(这里用数组来实现)
19 vector<int> tree;
20 //排好序的序列fix
21 int *fix;
22 
23 void buildTree();
24 void insertElement(int x);
25 void deleteMinElement();
26 void swim(int ii);
27 void order();
28 
29 int main(){
30     //freopen("D:\\input.in","r",stdin);
31     //freopen("D:\\output.out","w",stdout);
32     int n;
33     scanf("%d",&n);
34     tree.resize(n+1);
35     for(int i=1;i<=n;i++)    scanf("%d",&tree[i]);
36     buildTree();
37     insertElement(9);
38     deleteMinElement();
39     n=tree.size();
40     fix=new int[n];
41     order();
42     for(int i=1;i<n;i++)    printf("%d ",fix[i]);
43     return 0;
44 }
45 void buildTree(){
46     int cur=(tree.size()-1)/2;
47     while(cur){
48         swim(cur);
49         cur--;
50     }
51 }
52 void insertElement(int x){
53     tree.push_back(x);
54     int cur=tree.size()-1;
55     int son;
56     while(1){
57         son=cur;
58         cur>>=1;
59         if(!cur){
60             tree[son]=x;
61             break;
62         }
63         if(tree[cur]>=x){
64             tree[son]=tree[cur];
65         }else{
66             tree[son]=x;
67             break;
68         }
69     }
70 }
71 void deleteMinElement(){
72     tree[1]=tree[tree.size()-1];
73     tree.pop_back();
74     swim(1);
75 }
76 void swim(int ii){
77     int son,t=tree[ii];
78     int n=tree.size()-1;
79     while((ii<<1)<=n){
80         if((ii<<1)+1<=n&&tree[ii<<1]>=tree[(ii<<1)+1])   son=(ii<<1)+1;
81         else    son=(ii<<1);
82         if(t>tree[son]){
83             tree[ii]=tree[son];
84             ii=son;
85         }else{
86             break;
87         }
88     }
89     tree[ii]=t;
90 }
91 void order(){
92     int cur=1;
93     while(tree.size()!=1){
94         fix[cur++]=tree[1];
95         deleteMinElement();
96     }
97 }

 

posted @ 2015-04-10 22:35  jiu~  阅读(520)  评论(0编辑  收藏  举报