图的创建以及深度与广度优先遍历C/C++

一、图的存储结构
图有几种最常见的存储结构:邻接矩阵、邻接表和十字链表。
下面仅以邻接表表示法进行图的操作
邻接表:
邻接表(Adjacency List)是一种顺序存储结构与链式存储相结合的图的存储方法。邻接表类似于树的孩子链表表示法。就是对于图G中的每个Vi,将所有邻接于Vi的顶点Vj链成一个单链表,这个单链表就称为顶点Vi的邻接表,再将所有点的邻接表表头放到数组中,就构成了图的邻接表。在邻接表中有两种节点结构,如下:
《图的创建以及深度与广度优先遍历C/C++》
邻接表的表示形式如下:
《图的创建以及深度与广度优先遍历C/C++》
二、邻接表的数据结构

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 ;

三、建立无向图的算法

/* *建立无向图的邻接表存储 */
 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 ;
     }
 }

四、进行无向图的深度优先遍历
思路:
假设初始状态是图中所有顶点未曾被访问,则深度优先搜索可以从图中某个顶点v出发,访问此顶点,然后访问v的一个未被访问的邻接节点w1,接着再从w1出发,访问w1的一个未被访问过的邻接节点w2,然后再从w2出发,访问w2的一个未被访问的邻接顶点w3…如此下去深度优先遍历图,直至图中所有和v有路径相同的顶点都被访问到;若此时途中尚有顶点未被访问,则另选图中另外一个未曾被访问的顶点做起始节点,重复上述过程,直至途中所有节点都被访问到为止。
算法:

/*
 *进行图的深度优先搜索遍历
 */
 void DFSAL(ALGraph *G , int i)
 {
     //以Vi为出发点对图进行遍历
     EdgeNode *p ;
     printf("visit vertex : %s \n" , G->adjList[i].vertex) ;
     visited[i] = 1 ;
     p = G->adjList[i].firstedge ;
     while(p)
     {
         if(!visited[p->adjvex])
         {
             DFSAL(G , p->adjvex) ;
         }
         p = p->next ;
     }
 }
 void DFSTraverseAL(ALGraph *G)
 {
     int i ;
     for(i = 0 ; i < G->n ; i++)
     {
         visited[i] = 0 ;
     }
     for(i = 0 ; i < G->n ; i++)
     {
         if(!visited[i])
         {
             DFSAL(G , i) ;
         }
     }
 }

五、进行图的广度优先遍历
1、从图中某个顶点V0出发,并访问此顶点;
2、从V0出发,访问V0的各个未曾访问的邻接点W1,W2,…,Wk;然后,依次从W1,W2,…,Wk出发访问各自未被访问的邻接点;
3、重复步骤2,直到全部顶点都被访问为止。
利用队列进行访问节点的记录。
算法:

/* *建立队列的数据结构方便进行广度优先遍历 */
typedef struct
{
    int data[MaxVerNum] ;
    int head , tail ; //队头与队尾
} Quene ;
/* *进行广度优先搜索遍历 */
void BFSG(ALGraph *G , int k)
{
    int i , j ;
    Quene q ;
    EdgeNode *p ;
    q.head = 0 ;
    q.tail = 0 ; //进行队列的初始化
    printf("visit vertex : %s \n" , G->adjList[k].vertex) ;
    visited[k] = 1 ;
    q.data[q.tail++] = k ;
    while(q.head  % (MaxVerNum - 1) != q.tail % (MaxVerNum - 1))
    {
        i = q.data[q.head++] ;
        p = G->adjList[i].firstedge ;
        while(p)
        {
            if(!visited[p->adjvex])
            {
                printf("visit vertex : %s \n" , G->adjList[p->adjvex].vertex) ;
                visited[p->adjvex] = 1 ;
                q.data[q.tail++] = p->adjvex ;
            }
            p = p->next ;
        }
    }
}
void BFSTraverseAL(ALGraph *G)
{
    int i ;
    for(i = 0 ; i < G->n ; i++)
    {
        visited[i] = 0 ;
    }
    for(i = 0 ; i < G->n ; i++)
    {
        if(!visited[i])
        {
            BFSG(G , i) ;
        }
    }
}

六、全部测试代码

/* *进行图的遍历,进行图的深度遍历与广度遍历 */
#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
{
    int data[MaxVerNum] ;
    int head , tail ; //队头与队尾
} Quene ;
/* *建立无向图的邻接表存储 */
 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 DFSAL(ALGraph *G , int i)
 {
     //以Vi为出发点对图进行遍历
     EdgeNode *p ;
     printf("visit vertex : %s \n" , G->adjList[i].vertex) ;
     visited[i] = 1 ;
     p = G->adjList[i].firstedge ;
     while(p)
     {
         if(!visited[p->adjvex])
         {
             DFSAL(G , p->adjvex) ;
         }
         p = p->next ;
     }
 }
 void DFSTraverseAL(ALGraph *G)
 {
     int i ;
     for(i = 0 ; i < G->n ; i++)
     {
         visited[i] = 0 ;
     }
     for(i = 0 ; i < G->n ; i++)
     {
         if(!visited[i])
         {
             DFSAL(G , i) ;
         }
     }
 }
 /* *进行广度优先搜索遍历 */
void BFSG(ALGraph *G , int k)
{
    int i , j ;
    Quene q ;
    EdgeNode *p ;
    q.head = 0 ;
    q.tail = 0 ; //进行队列的初始化
    printf("visit vertex : %s \n" , G->adjList[k].vertex) ;
    visited[k] = 1 ;
    q.data[q.tail++] = k ;
    while(q.head  % (MaxVerNum - 1) != q.tail % (MaxVerNum - 1))
    {
        i = q.data[q.head++] ;
        p = G->adjList[i].firstedge ;
        while(p)
        {
            if(!visited[p->adjvex])
            {
                printf("visit vertex : %s \n" , G->adjList[p->adjvex].vertex) ;
                visited[p->adjvex] = 1 ;
                q.data[q.tail++] = p->adjvex ;
            }
            p = p->next ;
        }
    }
}
void BFSTraverseAL(ALGraph *G)
{
    int i ;
    for(i = 0 ; i < G->n ; i++)
    {
        visited[i] = 0 ;
    }
    for(i = 0 ; i < G->n ; i++)
    {
        if(!visited[i])
        {
            BFSG(G , i) ;
        }
    }
}
 /* *进行图的测试 */
void main()
{
  ALGraph *G ;
  EdgeNode *p = NULL ;
  int i ;
  G = (ALGraph*)malloc(sizeof(ALGraph)) ;
  CreateALGraph(G) ;
  printf("进行深度优先遍历\n") ;
  DFSTraverseAL(G) ;
  printf("进行广度优先遍历\n") ;
  BFSTraverseAL(G) ;
}
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/g15827636417/article/details/53047569
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞