一、无向图的连通分量和生成树
对于无向图,在进行遍历时:若是连通图,仅需从图中任一顶点出发,就能访问图中所有顶点;若是非连通图,需从图中多个顶点出发,每次从一个新顶点出发访问的顶点集
序列恰好是各个连通分量的顶点集。
⑴ 若G=(V,E)是无向连通图, 顶点集和边集分别是V(G) ,E(G) 。若从G中任意点出发遍历时, E(G)被分成两个互不相交的集合:
T(G) :遍历过程中所经过的边的集合;
B(G) :遍历过程中未经过的边的集合;
显然: E(G)=T(G)∪B(G) ,T(G)∩B(G)=Ø
显然,图G’=(V, T(G))是G的极小连通子图,且G’是一棵树。G’称为图G的一棵生成树。从任意点出发按DFS算法得到生成树G’称为深度优先生成树;按BFS算法得到的G’称为广度优先生成树。
⑵ 若G=(V,E)是无向非连通图,对图进行遍历时得到若干个连通分量的顶点集:V1(G) ,V2(G) ,…,Vn(G)和相应所经过的边集:T1(G) ,T2(G) , …,Tn(G) 。
则对应的顶点集和边集的二元组:Gi=(Vi(G),Ti(G))(1≦i≦n)是对应分量的生成树,所有这些生成树构成了原来非连通图的生成森林。
二、图的生成树和生成森林实现
1、深度优先生成树(树的结构用孩子--兄弟表示法:即结构有数据域和两个指针,一个指针指向第一个孩子结点,另一个指针指向一个兄弟结点)
//生成树的结点定义
typedef struct CSNode
{
ElemType data;
struct CSNode *firstchild;
struct CSNode *nextsibling;
}CSNode;
//DFSTree
CSNode *DFSTree(ALGraph *G,int v)
{
CSNode *T,*ptr,*q;
LinkNode *p;
Visited[v]=true;
T=(CSNode *)malloc(sizeof(CSNode));
T->data=G->AdjList[v].data;
T->firstchild=T->nextsibling=NULL;
q=NULL;
p=G->AdjList[v].firstarc;
while(p!=NULL)
{
int w=p->adjvex;
if(!Visited[w])
{
ptr=DFSTree(G,w);
if(q==NULL)
T->firstchild=ptr;
else T->nextsibling=ptr;
q=ptr;
}
p=p->nextarc;
}
return T;
}
2、广度优先生成树
//BFSTree
typedef struct Queue
{
int elem[MAX_VEX];
int front,rear;
}Queue;
CSNode *BFSTree(ALGraph *G,int v)
{
CSNode *T,*ptr,*q;
LinkNode *p;
Queue *Q;
Q=(Queue *)malloc(sizeof(Queue));
Q->front=Q->rear=0;
Visited[v]=true;
T=(CSNode *)malloc(sizeof(CSNode));
T->data=G->AdjList[v].data;
T->firstchild=T->nextsibling=NULL;
Q->elem[++Q->rear]=v;
while(Q->front!=Q->rear)
{
int w=Q->elem[++Q->front];
q=NULL:
p=G->AdjList[w].firstarc;
while(p!=NULL)
{
k=p->adjvex;
if(!Visited[k])
{
Visited[k]=true;
ptr=(CSNode *)malloc(sizeof(CSNode));
ptr->data=G->AdjList[k].data;
ptr->firstchild=ptr->nextsibling=NULL;
if(q==NULL)
T->firstchild=ptr;
else T->nextsibling=ptr;
q=ptr;
Q->elem[++Q->rear]=k;
}
p=p->nextarc;
}
}
return T;
}
3、生成森林
//生成森林
CSNode *DFSForest(ALGraph *G)
{
CSNode *T,*ptr,*q;
for(int w=0;w<G->vexnum;w++)
Visited[w]=false;
T=NULL;
for(int w=0;w<G->vexnum;w++)
{
if(!Visited[w])
{
ptr=DFSTree(G,w);
if(T==NULL)
T=ptr;
else q->nextsibling=ptr;
q=ptr;
}
}
return T;
}