无向图的联通分量和生成树(调用算法7.7、7.8,将无向图 构造为生成森林,并以孩子—兄弟二叉链表存储之)
2014-08-29 21:35
381 查看
具有n 个顶点的无向连通图至少有n-1 条边,如果只有n-1 条边,则不会形成环,这
样的图称为“生成树”。连通图可通过遍历构造生成树,非连通图的每个连通分量可构造
一棵生成树,整个非连通图构造为生成森林。algo7-1.cpp 调用算法7.7、7.8,将无向图
构造为生成森林,并以孩子—兄弟二叉链表存储之。
代码的运行结果:
请选择无向图
请输入G的类型(有向图:0,有向网:1,无向图:2,无向网:3): 2
请输入G的顶点数,边数: 13,13(见图751)
请输入13个顶点的值(<2个字符):
A B C D E F G H I J K L M
请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔):
A B
A C
A F
A L
B M
D E
G H
G I
G K
H K
J L
J M
L M
无向图(见图752)
13个顶点:
A B C D E F G H I J K L M
13条弧(边):
A-L A-F A-C A-B
B-M
D-E
G-K G-I G-H
H-K
J-M J-L
L-M
先序遍历生成森林:(见图753)
A L M J B F C D E G K H I
![](http://img.blog.csdn.net/20140829213653233?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvS29uZ2tPbmdM/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20140829213701065?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvS29uZ2tPbmdM/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
以上对图的输入产生的邻接表如图752 所示,仍略去网的权值指针域,并用顶点名
称代替顶点位置。调用算法7.7 产生的生成森林如图753 所示,此生成森林以孩子—兄
弟二叉链表存储的结构如图754 所示。
样的图称为“生成树”。连通图可通过遍历构造生成树,非连通图的每个连通分量可构造
一棵生成树,整个非连通图构造为生成森林。algo7-1.cpp 调用算法7.7、7.8,将无向图
构造为生成森林,并以孩子—兄弟二叉链表存储之。
// algo7-1.cpp 调用算法7.7、7.8 #include"c1.h" #define MAX_NAME 2 // 顶点字符串的最大长度+1 typedef char VertexType[MAX_NAME]; typedef VertexType TElemType; // 定义树的元素类型为图的顶点类型 #include"c6-5.h" // 孩子—兄弟二叉链表存储结构 #include"func6-2.cpp" // 孩子—兄弟二叉链表存储结构的先根遍历操作 typedef int InfoType; // 权值类型 #include"c7-21.h" // bo7-2.cpp采用的存储类型 #include"bo7-2.cpp" // 邻接表的基本操作 void DFSTree(ALGraph G,int v,CSTree &T) { // 从第v个顶点出发深度优先遍历图G,建立以T为根的生成树。算法7.8 Boolean first=TRUE; int w; CSTree p,q; visited[v]=TRUE; for(w=FirstAdjVex(G,G.vertices[v].data);w>=0;w=NextAdjVex(G,G.vertices[v].data, G.vertices[w].data)) // w依次为v的邻接顶点 if(!visited[w]) // w顶点不曾被访问 { p=(CSTree)malloc(sizeof(CSNode)); // 分配孩子结点 strcpy(p->data,G.vertices[w].data); p->firstchild=NULL; p->nextsibling=NULL; if(first) { // w是v的第一个未被访问的邻接顶点 T->firstchild=p; first=FALSE; // 是根的第一个孩子结点 } else // w是v的其它未被访问的邻接顶点 q->nextsibling=p; // 是上一邻接顶点的兄弟姐妹结点(第1次不通过此处,以后q已赋值) q=p; DFSTree(G,w,q); // 从第w个顶点出发深度优先遍历图G,建立子生成树q } } void DFSForest(ALGraph G,CSTree &T) { // 建立无向图G的深度优先生成森林的(最左)孩子(右)兄弟链表T。算法7.7 CSTree p,q; int v; T=NULL; for(v=0;v<G.vexnum;++v) visited[v]=FALSE; // 赋初值,visited[]在bo7-2.cpp中定义 for(v=0;v<G.vexnum;++v) // 从第0个顶点找起 if(!visited[v]) // 第v个顶点不曾被访问 { // 第v顶点为新的生成树的根结点 p=(CSTree)malloc(sizeof(CSNode)); // 分配根结点 strcpy(p->data,G.vertices[v].data); p->firstchild=NULL; p->nextsibling=NULL; if(!T) // 是第一棵生成树的根(T的根) T=p; else // 是其它生成树的根(前一棵的根的“兄弟”) q->nextsibling=p; // 第1次不通过此处,以后q已赋值 q=p; // q指示当前生成树的根 DFSTree(G,v,p); // 建立以p为根的生成树 } } void print(char *i) { printf("%s ",i); } void main() { ALGraph g; CSTree t; printf("请选择无向图\n"); CreateGraph(g); // 构造无向图g Display(g); // 输出无向图g DFSForest(g,t); // 建立无向图g的深度优先生成森林的孩子—兄弟链表t printf("先序遍历生成森林:\n"); PreOrderTraverse(t,print); // 先序遍历生成森林的孩子—兄弟链表t printf("\n"); }
代码的运行结果:
请选择无向图
请输入G的类型(有向图:0,有向网:1,无向图:2,无向网:3): 2
请输入G的顶点数,边数: 13,13(见图751)
请输入13个顶点的值(<2个字符):
A B C D E F G H I J K L M
请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔):
A B
A C
A F
A L
B M
D E
G H
G I
G K
H K
J L
J M
L M
无向图(见图752)
13个顶点:
A B C D E F G H I J K L M
13条弧(边):
A-L A-F A-C A-B
B-M
D-E
G-K G-I G-H
H-K
J-M J-L
L-M
先序遍历生成森林:(见图753)
A L M J B F C D E G K H I
以上对图的输入产生的邻接表如图752 所示,仍略去网的权值指针域,并用顶点名
称代替顶点位置。调用算法7.7 产生的生成森林如图753 所示,此生成森林以孩子—兄
弟二叉链表存储的结构如图754 所示。
相关文章推荐
- 【数据结构】算法7.7-7.8 无向图的连通分量和生成树
- 6-7-树的二叉链表(孩子-兄弟)存储表示-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版
- 树、森林与二叉树(树的存储结构(树的孩子兄弟链表应用举例),树转换为二叉树,二叉树转换成树和森林,树和森林的遍历)
- 孩子兄弟存储结构的几个统计算法实现
- 孩子兄弟链表构造算法(1)
- 树的存储结构(树的二叉链表(孩子—兄弟))
- 无向图的生成树和生成森林算法
- 树的二叉链表(孩子-兄弟)存储
- 调用生成通过存储过程自动生成AWR报告
- 根据表名,自动生成增、删、改参数化存储过程和调用代码
- Linq调用存储过程自动生成Int结果集的解决方法
- Linq调用存储过程自动生成Int结果集的解决方法
- 无向连通图求割点(tarjan算法去掉改割点剩下的联通分量数目)
- 不调用API,自编写算法生成随机数(java版)
- 构造最小生成树的 prim 算法
- phpMyAdmin调用和生成MySQL的存储过程以及CURSOR的应用
- 构造最小生成树的算法——Prim算法
- 分量算法poj 1751 Highways 最小生成树之Kruskal(克鲁斯卡尔)算法
- 树的存储:双亲数组法,孩子链表法,孩子兄弟法
- 基于邻接矩阵存储的图的最小生成树的Prime算法