首先不得不吐槽一下翻译的质量,霍红卫。。。。你给我站出来,不打死你,只想问你一下,你当年四级过了吗?
- 问题描述
- 输入两个整数,代表两个节点,如果这两个整数没有建立连接(这包括直接连接和通过其他节点连接),那么我们就建立这两个节点之间的连接,否则,继续输入下一个节点
四个逐步改进的算法如下:
- #include <stdio.h>
-
- #define N 10
-
- int main(void)
- {
- int id[N];
- int t,i,p,q;
-
-
- for(i=0;i<N;i++)
- {
- id[i] = i;
- }
-
- while( scanf("%d%d",&p,&q)==2 )
- {
- if( id[p]==id[q] )
- continue;
- t = id[p];
- for(i=0;i<N;i++)
- {
- if( id[i]==t )
- {
- id[i] = id[q];
- }
- }
-
- for(i=0;i<N;i++)
- {
- printf("%d\t",id[i]);
- }
- printf("\n");
- }
-
- return 0;
- }
这四个算法所使用的数据结构都是数组,算法一是把连接(包括直接连接和间接连接)在一起的整数所对应的数组元素都赋值为相同的值。
- #include <stdio.h>
-
- #define N 10
-
- int main(void)
- {
- int id[N];
- int i,j,p,q;
-
- for(i=0;i<N;i++)
- {
- id[i] = i;
- }
-
- while( scanf("%d%d",&p,&q)==2 )
- {
-
- for(i=p;id[i]!=i;i=id[i]);
- for(j=q;id[j]!=j;j=id[j]);
-
- if( i==j )
- continue;
- id[i] = j;
-
- for(i=0;i<N;i++)
- {
- printf("%d\t",id[i]);
- }
- printf("\n");
- }
-
- return 0;
- }
算法二采用的数据结构仍然是数组,但是逻辑上确实树的结构。我们首先根据输入的两个整数,分别找到其所在的树的根节点,然后检测两个节点所在的树的根节点是否相同,如果相同,就说明是同一棵树,否则就把这两个根节点连接起来。
- #include <stdio.h>
-
- #define N 10
-
- int main(void)
- {
- int id[N],sz[N];
- int p,q,i,j;
-
- for(i=0;i<N;i++)
- {
- id[i] = i;
- sz[i] = 1;
- }
-
- while( scanf("%d%d",&p,&q)==2 )
- {
- for(i=p;id[i]!=i;i=id[i]);
- for(j=q;id[j]!=j;j=id[j]);
- if( sz[i]<sz[j] )
- {
- id[i] = j;
- sz[j] += sz[i];
- }
- else
- {
- id[j] = i;
- sz[i] += sz[j];
- }
-
- printf("i=%d\nj=%d\n",i,j);
-
- for(i=0;i<N;i++)
- {
- printf("%d\t",sz[i]);
- }
- printf("\n");
-
- for(i=0;i<N;i++)
- {
- printf("%d\t",id[i]);
- }
- printf("\n");
- }
-
- return 0;
- }
算法三是在算法二的基础之上改进而来的,但是它添加了一个数据结构,记录以每个节点为根的树中的元素的个数。通过这个数据结构,每次都把小树连接到大树上,防止树的深度过深。
- #include <stdio.h>
-
- #define N 10
-
- int main(void)
- {
- int id[N];
- int sz[N];
- int p,q,i,j;
-
-
- for(i=0;i<N;i++)
- {
- id[i] = i;
- sz[i] = 1;
- }
-
- while( scanf("%d%d",&p,&q)==2 )
- {
- for(i=p;id[i]!=i;i=id[i])
- {
- id[i] = id[id[i]];
- }
- for(j=q;id[j]!=j;j=id[j])
- {
- id[j] = id[id[j]];
- }
-
- if( sz[i]<sz[j] )
- {
- id[i] = j;
- sz[j] += sz[i];
- }
- else
- {
- id[j] = i;
- sz[i] += sz[j];
- }
-
- printf("i=%d\nj=%d\n",i,j);
-
- for(i=0;i<N;i++)
- {
- printf("%d\t",sz[i]);
- }
- printf("\n");
-
- for(i=0;i<N;i++)
- {
- printf("%d\t",id[i]);
- }
- printf("\n");
- }
-
- return 0;
- }
算法四就是在算法三的基础之上又做了进一步的改进,将树的深度进一步的缩小。
第一章连通性问题-----algorithm in C 读书笔记
原文:http://www.cnblogs.com/guohaoyu110/p/6347866.html