無向圖的聯通分量和生成樹(調用算法7.7、7.8,將無向圖 構造爲生成森林,並以孩子—兄弟二叉鏈表存儲之)

具有n 個頂點的無向連通圖至少有n-1 條邊,如果只有n-1 條邊,則不會形成環,這
樣的圖稱爲“生成樹”。連通圖可通過遍歷構造生成樹,非連通圖的每個連通分量可構造
一棵生成樹,整個非連通圖構造爲生成森林。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 所示。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章