图的连通性问题(一)

来源:互联网 发布:java程序计数器 编辑:程序博客网 时间:2024/04/29 18:57

一、无向图的连通分量和生成树

对于无向图,在进行遍历时:若是连通图,仅需从图中任一顶点出发,就能访问图中所有顶点;若是非连通图,需从图中多个顶点出发,每次从一个新顶点出发访问的顶点集

序列恰好是各个连通分量的顶点集。

⑴ 若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;//DFSTreeCSNode *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、广度优先生成树

//BFSTreetypedef 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;}