图的生成树算法C/C++

一、图的生成树
设E(G)为连通图G中所有边的集合,则从图中任意顶点出发遍历图时,必将E(G)分成两个集合T(G)和B(G),其中T(G)是遍历过程中经历边的集合;B(G)是剩余的边的集合。显然T(G)和图G中所有顶点一起构成连通图G的极小连通子图,即可知它是连通图的一颗生成树。
二、生成树的构造方法
1、通过深度优先遍历构建图的生成树
2、对于非连通图,通过这样的遍历得到的是生成森林
这里写图片描述
三、以孩子兄弟链表表示法作为生成森林的存储结构

/*
 *定义树孩子兄弟表示的存储结构
 */
typedef struct treenode
{
    VertexType data[3] ; //存储结点数据
    struct treenode *firstson ; //第一个孩子节点
    struct treenode *next ; //第一个孩子节点的兄弟节点
} *CSTree , CSNode ;

四、通过深度优先遍历生成森林算法

 /*
 *建立无向图G的深度优先生成森林的孩子兄弟链表T
 */
CSTree DFSForest(ALGraph G , CSTree T)
{
    int i , j ;
    CSNode *p ;
    CSTree q ;
    T = NULL ;
    for(i = 0 ; i < G.n ; i++)
    {
        visited[i] = 0 ;
    }
    for(i = 0 ; i < G.n ; i++)
    {
        if(!visited[i])
        {
            p = (CSTree)malloc(sizeof(CSNode)) ;
            //给根节点赋值
            for(j = 0 ; j < 3 ; j++)
            {
                p->data[j] = G.adjList[i].vertex[j] ;
            }
            p->firstson = NULL ;
            p->next = NULL ;
            if(!T)
            {
                T = p ;
                q = T ;
            }
            else
            {
              q->next = p ;
            }
            q = p ;
            DFSTree(G , i , p) ; //建立以p为根节点的生成树
        }
    }
    return T ;
}

五、生成树算法

void DFSTree(ALGraph G , int i , CSTree T)
 {
     int j , first = 1 ;
     EdgeNode *w ;
     CSNode *p , *q;
     q = T ;
     visited[i] = 1 ;
     for(w = G.adjList[i].firstedge ; w ; w = w->next)
     {
         if(!visited[w->adjvex])
         {
            p = (CSTree)malloc(sizeof(CSNode)) ;
            for(j = 0 ; j < 3 ; j++)
            {
                p->data[j] = G.adjList[w->adjvex].vertex[j] ;
            }
            p->firstson = NULL ;
            p->next = NULL ;
            if(first)
            {
                T->firstson = p ;
                first = 0 ;
            }
            else
            {
              q->next = p ;
            }
            q = p ;
            DFSTree(G , w->adjvex , q) ;
         }
     }
 }

六、测试代码

/*
 *以及深度优先遍历得到图的生成森林,以孩子兄弟链表表示法作生成森林的存储结构
 */
#include<stdio.h>
#include<malloc.h>
#define MaxVerNum 100 /*定义最大节点数*/
int visited[MaxVerNum] ;
typedef char VertexType ;
typedef struct node
{
    int adjvex ;
    struct node *next ; //指向下一个邻接节点域
} EdgeNode ;
typedef struct vnode
{
    VertexType vertex[3] ; //顶点域
    EdgeNode *firstedge ; //边表头指针
} VertexNode ;
typedef VertexNode AdjList[MaxVerNum] ;
/*
 *定义以邻接边为存储类型的图
 */
typedef struct
{
    AdjList adjList ; //邻接表
    int n , e ; //顶点数与边数
} ALGraph ;
/*
 *定义树孩子兄弟表示的存储结构
 */
typedef struct treenode
{
    VertexType data[3] ; //存储结点数据
    struct treenode *firstson ; //第一个孩子节点
    struct treenode *next ; //第一个孩子节点的兄弟节点
} *CSTree , CSNode ;
 void DFSTree(ALGraph G , int i , CSTree T)
 {
     int j , first = 1 ;
     EdgeNode *w ;
     CSNode *p , *q;
     q = T ;
     visited[i] = 1 ;
     for(w = G.adjList[i].firstedge ; w ; w = w->next)
     {
         if(!visited[w->adjvex])
         {
            p = (CSTree)malloc(sizeof(CSNode)) ;
            for(j = 0 ; j < 3 ; j++)
            {
                p->data[j] = G.adjList[w->adjvex].vertex[j] ;
            }
            p->firstson = NULL ;
            p->next = NULL ;
            if(first)
            {
                T->firstson = p ;
                first = 0 ;
            }
            else
            {
              q->next = p ;
            }
            q = p ;
            DFSTree(G , w->adjvex , q) ;
         }
     }
 }
 /*
 *建立无向图G的深度优先生成森林的孩子兄弟链表T
 */
CSTree DFSForest(ALGraph G , CSTree T)
{
    int i , j ;
    CSNode *p ;
    CSTree q ;
    T = NULL ;
    for(i = 0 ; i < G.n ; i++)
    {
        visited[i] = 0 ;
    }
    for(i = 0 ; i < G.n ; i++)
    {
        if(!visited[i])
        {
            p = (CSTree)malloc(sizeof(CSNode)) ;
            //给根节点赋值
            for(j = 0 ; j < 3 ; j++)
            {
                p->data[j] = G.adjList[i].vertex[j] ;
            }
            p->firstson = NULL ;
            p->next = NULL ;
            if(!T)
            {
                T = p ;
                q = T ;
            }
            else
            {
              q->next = p ;
            }
            q = p ;
            DFSTree(G , i , p) ; //建立以p为根节点的生成树
        }
    }
    return T ;
}
/*
 *建立无向图的邻接表存储
 */
 void CreateALGraph(ALGraph *G)
 {
     int i , j , k ;
     EdgeNode *s ;
     printf("请输入顶点数与边数(输入格式为:顶点数,边数): ") ;
     scanf("%d,%d" , &G->n , &G->e) ;
     printf("请输入顶点信息(输入格式为:顶点号<CR>):\n") ;
     for( i = 0 ; i < G->n ; i++)
     {
         scanf("%s" , G->adjList[i].vertex) ;
         G->adjList[i].firstedge = NULL ; //将顶点的边表头指针设置为空
     }
     printf("请输入边的信息(输入格式为:i,j):\n") ;
     for(k = 0 ; k < G->e ; k++)
     {
         scanf("%d,%d" , &i , &j) ;
         s = (VertexNode*)malloc(sizeof(VertexNode)) ;
         //边上的第一个节点
         s->adjvex = j ;
         s->next = G->adjList[i].firstedge ;
         G->adjList[i].firstedge = s ;
         //边上的第二个节点
         s = (VertexNode*)malloc(sizeof(VertexNode)) ;
         s->adjvex = i ;
         s->next = G->adjList[j].firstedge ;
         G->adjList[j].firstedge = s ;
     }
 }
 /*
  *进行森林的先根遍历
  */
void PreForest(CSTree T)
{
    if(T)
    {
        printf("%s " , T->data) ;
        PreForest(T->firstson) ;
        while((T = T->next))
        {
            PreForest(T) ;
        }
    }
}
/*
 *进行生成树的测试
 */
void main()
{
   ALGraph *G ;
   CSTree T ;
   G = (ALGraph*)malloc(sizeof(ALGraph)) ;
   T = (CSTree)malloc(sizeof(CSNode)) ;
   CreateALGraph(G) ;
   T = DFSForest(*G , T) ;
   //进行树森林的遍历
   PreForest(T) ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值