第七章 树(最大堆、最小堆、排序、并查集)
输入
14
99 5 36 7 22 17 46 12 2 19 25 28 1 92
输出
1 2 5 7 12 17 19 22 25 28 36 46 92 99
一、堆排序,利用最小堆,进行排序
1 #include <stdio.h> 2 int h[100], n; 3 void swap(int x,int y) 4 { 5 int t; 6 t = h[x]; 7 h[x] = h[y]; 8 h[y] = t; 9 } 10 void siftdown(int i) 11 { 12 int t, flag = 0; 13 while (2 * i <= n&&flag == 0) 14 { 15 if (h[i] > h[i * 2]) 16 t = i * 2; 17 else 18 t = i; 19 if (i * 2 + 1 <= n&&h[t] > h[2 * i + 1]) 20 t = 2 * i + 1; 21 if (t != i) 22 { 23 swap(t, i); 24 i = t; 25 } 26 else 27 flag = 1; 28 } 29 } 30 void creat() 31 { 32 int i; 33 for (i = n / 2;i >= 1;i--) 34 siftdown(i); 35 } 36 int deletemin() 37 { 38 int t; 39 t=h[1]; 40 h[1] = h[n]; 41 n--; 42 siftdown(1); 43 return t; 44 } 45 int main() 46 { 47 int num, i; 48 scanf("%d",&num); 49 for (i = 1;i <= num;i++) 50 scanf("%d",&h[i]); 51 n = num; 52 creat(); 53 for (i = 1;i <= num;i++) 54 { 55 printf("%d ", deletemin()); 56 } 57 printf("\n"); 58 return 0; 59 }
二、堆排序,利用最大堆,进行排序
1 #include <stdio.h> 2 int h[100], n; 3 void swap(int x, int y) 4 { 5 int t; 6 t = h[x]; 7 h[x] = h[y]; 8 h[y] = t; 9 } 10 void siftdown(int i) 11 { 12 int t, flag = 0; 13 while (2 * i <= n&&flag == 0) 14 { 15 if (h[i] < h[2 * i]) 16 t = 2 * i; 17 else 18 t = i; 19 if (2 * i + 1 <= n&&h[2 * i + 1] > h[t]) 20 t = 2 * i + 1; 21 if (t != i) 22 { 23 swap(t,i); 24 i = t; 25 } 26 else 27 { 28 flag = 1; 29 } 30 } 31 } 32 void creat() 33 { 34 int i; 35 for (i = n / 2;i >= 1;i--) 36 siftdown(i); 37 } 38 void heapsort() 39 { 40 while (n > 1) 41 { 42 swap(1, n); 43 n--; 44 siftdown(1); 45 } 46 } 47 int main() 48 { 49 int num, i; 50 scanf("%d",&num); 51 n = num; 52 for (i = 1;i <= num;i++) 53 scanf("%d",h+i); 54 55 creat(); 56 57 heapsort(); 58 59 for (i = 1;i <= num;i++) 60 printf("%d ",h[i]); 61 printf("\n"); 62 return 0; 63 }
三、并查集
题目:
快过年了,犯罪分子也开始为年终奖奋斗了。晓哼的家乡出现了多次抢劫事件。由于强盗人数过于庞大,作案频繁,警方想查清楚到底有几个犯罪团伙实在太不容易了,不过警察叔叔还是搜集到了一些线索,需要咱们帮忙分析一下:
现在有10个强盗。
1号强盗与2号强盗是同伙。
3号强盗与4号强盗是同伙。
5号强盗与2号强盗是同伙。
4号强盗与6号强盗是同伙。
2号强盗与6号强盗是同伙。
8号强盗与7号强盗是同伙。
9号强盗与7号强盗是同伙。
1号强盗与6号强盗是同伙。
2号强盗与4号强盗是同伙。
有一点需要注意,强盗同伙的同伙也是同伙。你能帮助警方查出有多少个独立的犯罪团伙吗?
输入一下数据:
第一行n m,n表示强盗的人数,m表示警方搜集到的m条线索。接下来的m行每一行有两个数 a b。
表示强盗a和强盗b是同伙。
10 9
1 2
3 4
5 2
4 6
2 6
8 7
9 7
1 6
2 4
运行结果: 3
1 #include <stdio.h> 2 int n, m, f[100]; 3 void init() 4 { 5 int i; 6 for (i = 1;i <= n;i++) 7 f[i] = i; 8 } 9 void merge(int x, int y) 10 { 11 int i,t; 12 t = f[y]; 13 for (i = 1;i <= n;i++) 14 { 15 if (t == f[i]) 16 f[i] = f[x]; 17 } 18 } 19 int main() 20 { 21 int x, y,i,sum=0; 22 scanf("%d%d",&n,&m); 23 init(); 24 while (m--) 25 { 26 scanf("%d%d",&x,&y); 27 merge(x,y); 28 } 29 for (i = 1;i <= n;i++) 30 { 31 if (f[i] == i) 32 sum++; 33 } 34 printf("%d\n",sum); 35 36 return 0; 37 }
1 #include <stdio.h> 2 int n, m, f[100]; 3 void init() 4 { 5 int i; 6 for (i = 1;i <= n;i++) 7 f[i] = i; 8 } 9 int getf(int x) 10 { 11 if (f[x] == x) 12 return x; 13 else 14 { 15 f[x] = getf(f[x]); 16 return f[x]; 17 } 18 } 19 void merge(int x, int y) 20 { 21 int t1, t2; 22 t1 = getf(x); 23 t2 = getf(y); 24 if (t2 != t1) 25 { 26 f[t2] = t1;//靠左原则 27 } 28 return; 29 } 30 int main() 31 { 32 int x, y,i,sum=0; 33 scanf("%d%d",&n,&m); 34 init(); 35 while (m--) 36 { 37 scanf("%d%d",&x,&y); 38 merge(x,y); 39 } 40 for (i = 1;i <= n;i++) 41 { 42 if (f[i] == i) 43 sum++; 44 } 45 printf("%d\n",sum); 46 47 return 0; 48 }

浙公网安备 33010602011771号