堆排序
提供几种堆排序,各种方法,包括堆的各种基本操作;
//堆排 1(侧重于删除顶元素及读入元素建堆)
#include<iostream> #include<vector> #include<algorithm> using namespace std; int heap[1000]; int heap_size=0; void put(int d) //heap[1]为堆顶 建堆 { int now, next; heap[++heap_size] = d; now = heap_size; while(now > 1) { next = now >> 1; if(heap[now] >= heap[next]) break; swap(heap[now], heap[next]); now = next; } } /*void put(int d) { heap[++heap_size] = d; //push_heap(heap + 1, heap + heap_size + 1); //大根堆 push_heap(heap + 1, heap + heap_size + 1, greater<int>()); //小根堆 }*/ int get() //heap[1]为堆顶 删除顶元素及确定新堆 { int now=1, next, res= heap[1]; heap[1] = heap[heap_size--]; while(now * 2 <= heap_size) { next = now * 2; if (next < heap_size && heap[next + 1] < heap[next]) next++; if (heap[now] <= heap[next]) break; swap(heap[now], heap[next]); now = next; } return res; } int main() { int i=0; while(cin>>heap[++i]){ put(heap[i]); } for(int j=1;j<i;++j){ cout<<heap[1]<<" ";get(); } return 0; }
//堆排2
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int heap_size, n; 5 int heap[100001]; 6 void swap(int &a, int &b) 7 { 8 int t = a;a = b;b = t; 9 } 10 11 void put(int d) 12 { 13 int now, next; 14 heap[++heap_size] = d; 15 now = heap_size; 16 while(now > 1) 17 { 18 next = now >> 1; 19 if(heap[now] >= heap[next])return; 20 swap(heap[now], heap[next]); 21 now = next; 22 } 23 } 24 int get() 25 { 26 int now, next, res; 27 res = heap[1]; 28 heap[1] = heap[heap_size--]; 29 now = 1; 30 while(now * 2 <= heap_size) 31 { 32 next = now * 2; 33 if(next < heap_size && heap[next + 1] < heap[next])next++; 34 if(heap[now] <= heap[next])return res; 35 swap(heap[now], heap[next]); 36 now = next; 37 } 38 return res; 39 } 40 41 void work() 42 { 43 int i, x, y, ans = 0; 44 cin >> n; 45 for(i = 1 ; i <= n ; i++) 46 { 47 cin >> x; 48 put(x); 49 } 50 for(i = 1 ; i < n ; i++) cout << get() << ' '; 51 cout << get() << endl; 52 } 53 54 int main() 55 { 56 //freopen("heapsort.in", "r", stdin); 57 //freopen("heapsort.out", "w", stdout); 58 work(); 59 return 0; 60 }
//堆排3
1 #include<iostream> 2 using namespace std; 3 int d[1000]; 4 int n,i,total,tmp; 5 void down(int i) 6 { 7 int t,j; 8 while(i<=total/2) 9 { 10 j=2*i; 11 if((j<total)&&(d[j+1]<d[j])) j=j+1; 12 if(d[i]>d[j]) 13 { 14 t=d[i]; d[i]=d[j]; d[j]=t; 15 i=j; 16 } 17 else break; 18 } 19 20 } 21 int main() 22 { 23 cin>>n; 24 for (i=1;i<=n;i++) cin>>d[i]; 25 total=n; 26 for(i=n/2;i>=1;i--) down(i); 27 for(i=1;i<=n;i++) 28 { 29 tmp=d[1];d[1]=d[total];d[total]=tmp; 30 total=total-1; 31 down(1); 32 } 33 for(i=n;i>=1;i--) cout<<d[i]<<" "; 34 }
//堆排4(利用heap函数,调用头文件(#include<algorithm>))
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 int heap[100010]; 6 7 bool cmp(int a,int b){ return a > b; } //小根堆 8 9 int main() 10 { 11 int k; 12 cin>>k; 13 for(int i=0;i<k;++i) 14 { 15 cin>>heap[i]; 16 } 17 make_heap(heap,heap+k,cmp); 18 for(int i= 0;i<k;i++) 19 { 20 cout<<heap[0]<<" "; 21 //pop_heap(heap,heap+(k-i)); //pop删除后,自动建堆但是默认堆是大根堆 ,与make_heap相同 22 pop_heap(heap,heap+(k-i),cmp); 23 } 24 25 return 0; 26 } 27 28 //pop测试 29 /*for(int i=0;i<k;i++) 30 cout<<heap[i]<<" "; 31 cout<<endl; 32 pop_heap(heap,heap+k); 33 for(int i=0;i<k;i++) 34 cout<<heap[i]<<" ";*/
//参考(heap函数)
1 /* 介绍algorithm头文件中根的相关函数
2 make_heap(首位置, 尾位置+1, 可选的cmp函数); -> 构造堆
3 push_heap(首位置, 尾位置+1, 可选的cmp函数); -> 添加元素到堆中
4 pop_heap(首位置, 尾位置+1, 可选的cmp函数); -> 从堆中移出元素
5 sort_heap(首位置, 尾位置+1, 可选的cmp函数); -> 整个堆进行排序
6 */
7
8 #include<algorithm>
9 #include<cstdio>
10 using namespace std;
11
12 bool inc_cmp(int a,int b){ return a > b; }
13 // 可以理解为:左a右b,当a>b的时候,双方交换位置,
14 // 所以上式这个cmp意为从小到大(排序)。
15
16 bool des_cmp(int a, int b){ return a < b; }
17
18 int num[10]={3, 1, 2, 5, 6, 4};
19
20 int main()
21 {
22 make_heap(num, num+6);//构造一个堆,默认是大根堆。
23 // 上式等价于make_heap(&num[0], &num[6]);可以看到,区间是[0, 7),
24 // 即参数中的末尾是真真实末尾的后一个位置。
25 // 可以修改为make_heap(num, num+6, inc_cmp); 此时为小根堆。
26
27 // 插入一个元素到先前创建的堆中,插进来的数将调整到合适的位置。
28 num[6] = 5;
29 push_heap(num, num+7);
30
31 // pop_heap将堆顶数据移动到末尾位置,然后将剩余数据重新构造堆。
32 // 其中一个易于理解的例子就是,不断将大根堆堆顶移到末尾,
33 // 以此模拟从小到大排序。
34
35 /* ---------- */
36 printf("before: ");
37 for(int i = 0; i < 7; i++)
38 printf("%d ", num[i]);
39 printf("
");
40
41 for(int i = 7; i >= 1; i--) // 共7个数,交换到最后第二个数为止。
42 {
43 pop_heap(num, num+i);
44 }
45
46 printf("after : ");
47 for(int i = 0; i < 7; i++)
48 printf("%d ", num[i]);
49 printf("
");
50 /* ---------- */
51
52 //sort_heap,堆排序,因为前面都pop_heap掉了,所以得重新make_heap
53 make_heap(num, num + 6);
54 sort_heap(num, num+6, des_cmp);
55 for(int i = 0; i < 7; i++)
56 printf("%d ", num[i]);
57 printf("
");
58 return 0;
59 }