数据结构进阶实训课程笔记和算法练习
Source Code
C语言中文网
题目1 1 2 3 判断给定的图G是否是连通图。若连通,则输出该生成树。若不连通,则输出其所有的连通子图(生成森林) - 图G分别采用邻接矩阵或邻接表存储表示 - 实现在该两种存储表示方法下的上述操作
1.1 算法设计思想
深度优先搜索算法的改进。
如果一次深度优先搜索没有把所有顶点遍历完,即visited数组有false值,那么就可以证明图不是连通的。
1.2 源代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 void Judge (MGraph G, bool *b) { printf ("The spanning tree or forest of this graph is: " ); int v; for ( v = 0 ; v < G.vexnum; ++v){ visited[v] = false ; } DFS( G, 0 ); for ( v = 1 ; v < G.vexnum; v++){ if (!visited[v]){ DFS( G, v); *b = false ; printf (" | " ); } } *b = true ; } void JudgeAdjList (ALGraph *g, bool *b) { printf ("The spanning tree or forest of this graph is: " ); int i; int visited[MAX_VERtEX_NUM]; for (i=0 ;i<g->vexnum;i++){ visited[i]=0 ; } DFSAdjList(g, 0 , visited); for (i=1 ;i<g->vexnum;i++){ if (!visited[i]){ printf (" | " ); DFSAdjList(g, i, visited); *b = false ; } } *b = true ; }
1.3 运行情况截图
题目2 1 无向图G(不带权值)采用邻接表结构,试设计一个算法,求图G中从顶点u到顶点v的最短路径。
2.1 算法设计思想
运用Dijkstra(迪杰斯特拉)算法的思想。
visit[]:这个数组用来标记结点的访问与否,如果该结点被访问,则为1,如果该结点还没有访问,则为0;
distance[]:这个数组用来记录当前从v到各个顶点的最短路径长度,算法的核心思想就是通过不断修改这个表实现。
先遍历直达源顶点的所有顶点,距离记为1,置visit[]已访问;
后面遍历所有其他未访问的顶点,更新distance[]数组。
1 2 3 4 5 6 7 实例 1 / \ 0 2 / \ 3 4 程序将以此图作为输入
2.2 源代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 void Dijkstra (ALGraph G, int s, int t) { int i, j; int visit[MAX_VERTEX_NUM]; int distance[MAX_VERTEX_NUM]; for (i=0 ; i<G.vexnum; i++){ distance[i]=INFINITY; visit[i]=false ; } distance[s]=0 ; visit[s]=1 ; ArcNode *p=G.vertices[s].firstarc; while (p){ if (!visit[p->adjvex]){ distance[p->adjvex]=1 ; visit[p->adjvex]=1 ; } p=p->nextarc; } for (i=0 ; i<G.vexnum; i++){ if (!visit[G.vertices[i].data]){ p=G.vertices[i].firstarc; while (p){ if (distance[p->adjvex]<INFINITY){ distance[G.vertices[i].data]=distance[p->adjvex]+1 ; } p=p->nextarc; } } } }
2.3 运行情况截图
题目3 1 无向图G(不带权值)采用邻接表表示,试设计一个算法,输出从顶点Vi到顶点Vj的所有简单路径。
3.1 算法设计思想
利用递归算法,从起始点出发,分别递归遍历它的所有顶点,将遍历过的顶点访问数组置false,并将节点记录进path数组,当遇到目标加点将path数组中顶点全部输出,即为简单路径。
1 2 3 4 5 6 7 实例 0 / \ 1 2 \ / 3 程序将以此图作为输入
3.2 源代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int path[MAX_VERTEX_NUM];path[0 ]=start; void findAllSimplePath (ALGraph G, int start, int end , int path[], int i) { ArcNode *p; int j, n; visited[start]=1 ; p=G.vertices[start].firstarc; while (p){ n=p->adjvex; if (n==end ){ path[i+1 ] = end ; for (j=0 ; j<=i+1 ; j++) printf ("%-3d" , path[j]); printf ("\n" ); } else if (!visited[n]){ path[i+1 ]=n; findAllSimplePath(G, n, end , path, i+1 ); } p=p->nextarc; } }
3.3 运行情况截图
题目4 1 图G采用邻接表表示,试设计一个算法,求无向连通图G中距离顶点v最远的一个顶点。
4.1 算法设计思想
同题目2的算法思想,既然用Dijkstra算法求出了所有一个点到其他所有顶点的路径,那么取distance数组中的最大值即为最远顶点。
4.2 源代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 int Dijkstra (ALGraph G, int s) { int i, j; int visit[MAX_VERTEX_NUM]; int distance[MAX_VERTEX_NUM]; for (i=0 ; i<G.vexnum; i++){ distance[i]=INFINITY; visit[i]=false ; } distance[s]=0 ; visit[s]=1 ; ArcNode *p=G.vertices[s].firstarc; while (p){ if (!visit[p->adjvex]){ distance[p->adjvex]=1 ; visit[p->adjvex]=1 ; } p=p->nextarc; } for (i=0 ; i<G.vexnum; i++){ if (!visit[G.vertices[i].data]){ p=G.vertices[i].firstarc; while (p){ if (distance[p->adjvex]<INFINITY){ distance[G.vertices[i].data]=distance[p->adjvex]+1 ; } p=p->nextarc; } } } int max =0 ; for (i=1 ; i<G.vexnum; i++){ if (distance[max ]<distance[i]) max =i; } return max ; }
4.3 运行情况截图