图的连通性问题(一)

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

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

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

⑴ 若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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值