I.快速查找算法:
========================quick_find.c=================================
#include<stdio.h>
#define N 10
int main(){
int id[N];
int i, p, q, t, count, sum = 0;
for(i = 0; i < N; i++) id[i] = i;
while (scanf("%d %d", &p, &q) == 2){
count = 0;
if(id[p] == id[q]) continue;
//下面的这个for循环很有意思,它具有记忆功能:记忆之前连通的数!
for(t = id[p], i = 0; i < N; i++)
if(id[i] == t){
id[i] = id[q];
count++;
sum ++;
}
printf("count = %d, sum = %d/n", count, sum);
for(i = 0; i < N; i++) printf("%d ", id[i]);
printf("/n");
}
}
=====编译运行=====
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章 导论$ gcc quick_find.c
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章 导论$ ./a.out
0 2
count = 1, sum = 1
2 1 2 3 4 5 6 7 8 9
1 4
count = 1, sum = 2
2 4 2 3 4 5 6 7 8 9
2 5
count = 2, sum = 4
5 4 5 3 4 5 6 7 8 9
3 6
count = 1, sum = 5
5 4 5 6 4 5 6 7 8 9
0 4
count = 3, sum = 8
4 4 4 6 4 4 6 7 8 9
6 0
count = 2, sum = 10
4 4 4 4 4 4 4 7 8 9
1 3
II.快速并集算法:
===================quick_union.c=======================================
#include<stdio.h>
#define N 10
/*
*这个一个连通性问题的快速union的解决方案。
*/
int main(){
int id[N];
int i, j, p, q;
int count_i, count_j, sum = 0;
for(i = 0; i < N; i++) id[i] = i;
while(scanf("%d %d", &p, &q) == 2){
//下面是很有意思的两个for循环!如果输入的位置的值被改动过,此处的i可能出现多个值,例如,1 1 9 4 9 6 9 9 0 0 输入 5 5,首先i=5发现5号位置被改动过->i=9发现9号位置也被改动->i=0发现0号位置也被改动,继续给i赋值->i=1,好了发现1号位置没有被改动,OK 最终i=1;
//这个for循环的作用总结为:追踪上一级的位置有没有被改动!直到找到一个没有被改动的位置的值附给变量。
count_i = count_j = 0;
for(i = p; i != id[i]; i = id[i]) {count_i++; sum++;}
for(j = q; j != id[j]; j = id[j]) {count_j++; sum++;}
if(i == j) continue;
id[i] = j;
count_i++;
sum++;
printf("访问数组id的次数:%d/n", count_i + count_j);
printf("访问数组id的总数:%d/n", sum);
for(i = 0; i < N; i++) printf("%d ", id[i]);
printf("/n/n");
}
}
=======编译运行===========
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章 导论$ gcc quick_union.c
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章 导论$ ./a.out
0 2
访问数组id的次数:1
访问数组id的总数:1
2 1 2 3 4 5 6 7 8 9
1 4
访问数组id的次数:1
访问数组id的总数:2
2 4 2 3 4 5 6 7 8 9
2 5
访问数组id的次数:1
访问数组id的总数:3
2 4 5 3 4 5 6 7 8 9
3 6
访问数组id的次数:1
访问数组id的总数:4
2 4 5 6 4 5 6 7 8 9
0 4
访问数组id的次数:3
访问数组id的总数:7
2 4 5 6 4 4 6 7 8 9
6 0
访问数组id的次数:4
访问数组id的总数:11
2 4 5 6 4 4 4 7 8 9
1 3
III.加权快速并集算法:
=========================weighted_quick_union.c=========================================
#include<stdio.h>
#define N 10
/*
*这个一个连通性问题的快速加权union的解决方案。
*/
int main(){
int id[N], sz[N];
int i, j, p, q;
int count_i, count_j, sum = 0;
for(i = 0; i < N; i++){
id[i] = i;
sz[i] = 1;
}
while(scanf("%d %d", &p, &q) == 2){
count_i = count_j = 0;
for(i = p; i != id[i]; i = id[i]){count_i++; sum++;}
for(j = q; j != id[j]; j = id[j]){count_j++; sum++;}
if(i == j) continue;
if(sz[i] < sz[j]){
id[i] = j;
count_i++;
sum++;
sz[j] += sz[i];
} else {
id[j] = i;
count_j++;
sum++;
sz[i] += sz[j];
}
printf("访问数组id的次数:%d/n", count_i+count_j);
printf("访问数组id的总次数:%d/n", sum);
for(i = 0; i < N; i++) printf("%d ", id[i]);
printf("/n/n");
}
}
=========编译运行============
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章 导论$ gcc weighted_quick_union.c
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章 导论$ ./a.out
0 2
访问数组id的次数:1
访问数组id的总次数:1
0 1 0 3 4 5 6 7 8 9
1 4
访问数组id的次数:1
访问数组id的总次数:2
0 1 0 3 1 5 6 7 8 9
2 5
访问数组id的次数:2
访问数组id的总次数:4
0 1 0 3 1 0 6 7 8 9
3 6
访问数组id的次数:1
访问数组id的总次数:5
0 1 0 3 1 0 3 7 8 9
0 4
访问数组id的次数:2
访问数组id的总次数:7
0 0 0 3 1 0 3 7 8 9
6 0
访问数组id的次数:2
访问数组id的总次数:9
0 0 0 0 1 0 3 7 8 9
1 3
IV.分路径压缩加权快速并集算法:
====================weighted_quick_union_pc_hal.c================================
#include<stdio.h>
#define N 10
/*
*这个一个连通性问题的分路径压缩快速加权union的解决方案。
*/
int main(){
int id[N], sz[N];
int i, j, p, q;
int count_i, count_j, sum = 0;
for(i = 0; i < N; i++){
id[i] = i;
sz[i] = 1;
}
while(scanf("%d %d", &p, &q) == 2){
count_i = count_j = 0;
for(i = p; i != id[i]; i = id[i]){
id[i] = id[id[i]];
count_i += 4;
sum += 4;
}
for(j = q; j != id[j]; j = id[j]){
id[j] = id[id[j]];
count_j += 4;
sum += 4;
}
if(i == j) continue;
if(sz[i] < sz[j]){
id[i] = j;
count_i++;
sum++;
sz[j] += sz[i];
} else {
id[j] = i;
count_j++;
sum++;
sz[i] += sz[j];
}
printf("访问数组id的次数:%d/n", count_i+count_j);
printf("访问数组id的总次数:%d/n", sum);
for(i = 0; i < N; i++) printf("%d ", id[i]);
printf("/n/n");
}
}
==============编译运行=====================
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章 导论$ gcc weighted_quick_union_pc_hal.c
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章 导论$ ./a.out
0 2
访问数组id的次数:1
访问数组id的总次数:1
0 1 0 3 4 5 6 7 8 9
1 4
访问数组id的次数:1
访问数组id的总次数:2
0 1 0 3 1 5 6 7 8 9
2 5
访问数组id的次数:5
访问数组id的总次数:7
0 1 0 3 1 0 6 7 8 9
3 6
访问数组id的次数:1
访问数组id的总次数:8
0 1 0 3 1 0 3 7 8 9
0 4
访问数组id的次数:5
访问数组id的总次数:13
0 0 0 3 1 0 3 7 8 9
6 0
访问数组id的次数:5
访问数组id的总次数:18
0 0 0 0 1 0 3 7 8 9
1 3