c语言编程 输出一个无向图的邻接表,邻接矩阵,进行深度和广度优先遍历

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>

//#define GRAPH_LIST 

int *g_visited;  //访问标志
int *g_queue;  //定义一个队列Q
int g_front=-1,g_rear=-1;         //初始化队列Q
int g_queue_size;
int g_vernum;
int g_arcnum;

typedef struct VNode    //头结点的类型定义
{
    char  data[20];   //用于存储的顶点
    int nextver_index;       //边指向的顶点的位置
    struct VNode *nextver_point;   //指示下一个与该顶点相邻接的顶点
}AdjList;
typedef struct            //图的类型定义
{
      AdjList *vertex;  //用于存储顶点
      int *arcs;                //邻接矩阵,存储边的信息
      int vernum,arcnum;             //顶点数和边的数目
}MGraph;

void Visited_init(MGraph *N)
{
    int v;
    for(v=0;v<g_vernum;v++)
    {
        g_visited[v]=0;   //访问标志数组初始化为未被访问
    }
    return;
}

void CreateGraph_L(MGraph *N)   //邻接表表示
{
   int i,j,k;
   
   AdjList *p;
   
   printf("请输入%d个顶点的值:\n",g_vernum);  
   for(i=0;i<g_vernum;i++)    //将顶点存储在头结点中
    {
        printf("%d vlaue:\t",i);
        scanf("%s",N->vertex[i].data);
        N->vertex[i].nextver_point=&N->vertex[i];  //将相关联的顶点置为空
        N->vertex[i].nextver_index = 0;
   }
    printf("\n");

   for(k=0;k<g_arcnum;)   
   {
        printf("第 %d 条边的两个顶点序号(逗号隔开):\t",k+1);
   
        scanf("%d,%d",&i,&j);
        if(i >=g_vernum || j>=g_vernum)
        {
            printf("第 %d 条边的两个顶点序号(逗号隔开): 输入错误,请重新输入\t\n\n",k+1);
            continue;
        }
        //建立邻接表关系链
        p=(AdjList *)malloc(sizeof(AdjList));
        p->nextver_index=j;
        p->nextver_point=N->vertex[i].nextver_point;
        N->vertex[i].nextver_point=p;
        p=(AdjList *)malloc(sizeof(AdjList));
        p->nextver_index=i;
        p->nextver_point=N->vertex[j].nextver_point;
        N->vertex[j].nextver_point=p;
        k++;
  }
}
void DisplayGraph_L(MGraph *N)   //图的邻接表存储结构输出
{
    int i;
    AdjList *p;
    printf("邻接表表示为:\n");
 	for(i=0;i<g_vernum;i++)
    {
        printf("%s[%d]",N->vertex[i].data,i);
        p=N->vertex[i].nextver_point;   //将p指向边表的第一个结点
        while(p != &N->vertex[i])
        {
            printf("->%s[%d] ",N->vertex[p->nextver_index].data,p->nextver_index);
            p=p->nextver_point;
        }
        printf("\n");
   }
}
void CreateGraph_T(MGraph *N)    //邻接矩阵表示
{   
    int i,j,k;

    //初始化邻接矩阵边的信息初始化为空
    memset((char *)N->arcs, 0, 4*g_vernum * g_vernum);
    
    printf("请输入%d个顶点的值:\n",g_vernum);  
    for(i=0;i<g_vernum;i++) 
    {
        printf("%d vlaue:\t",i);
        scanf("%s",N->vertex[i].data);
    }
    
    for(k=0;k<g_arcnum;)
    {
        printf("第 %d 条边的两个顶点序号(逗号隔开):\t",k+1);
        scanf("%d,%d",&i,&j);
        if(i >=g_vernum|| j>=g_vernum)
        {
            printf("第 %d 条边的两个顶点序号(逗号隔开): 输入错误,请重新输入\t\n\n",k+1);
            continue;
        }
        N->arcs[i*g_vernum + j]=1;
        N->arcs[j*g_vernum + i]=1;
        k++;
    }

}

void DisplayGraph_T(MGraph *N)        //输出邻接矩阵存储表示的图N 
{
   int i,j;
   printf("\n无向图的邻接矩阵:\n");
   for(i=0;i<g_vernum;i++)
   {
        printf("%s\t",N->vertex[i].data);
   }
    printf("\n");

   for(i=0;i<g_vernum;i++)
   {
        for(j=0;j<g_vernum;j++)
        {
            printf("%8d",N->arcs[i*g_vernum + j]);
        }
        printf("\n");
    }
}

void Visit(char *v)   //访问函数,输出图中的顶点
{
     printf("%s -> ",v);
}
int Visited_set(int key)
{
    g_visited[key]=1;    //设置访问标志为1,表示已经被访问过
    return 0;
}
int Visited_get(int key)
{
    return g_visited[key];
}
int Enqueue(int key)
{
    g_rear++;
    g_queue[g_rear % g_queue_size] = key;    //v入队列 g_rear进队口
    return 0;
}
int Dequeue(void)
{
    g_front++; 
    return g_queue[g_front%g_queue_size];   //队首元素出队赋值给v
}
int Queue_empty()
{
    return g_front == g_rear;
}
int Queue_full()
{
    return (g_rear - g_front) == g_queue_size;
}
void Queue_init()
{
    g_front=-1;
    g_rear=-1;         //初始化队列Q
}



void DFS_L(MGraph *N, AdjList *cur, int i)   //从顶点r出发递归深度优先搜索图N
{
    AdjList *tmp = NULL;
    Visited_set(i);
    Visit(N->vertex[i].data);  //访问第r个顶点

    while(&N->vertex[i] != cur)
    {
        if(Visited_get(cur->nextver_index)!=1)
        {
            tmp = N->vertex[cur->nextver_index].nextver_point;
            DFS_L(N, tmp, cur->nextver_index);
        }
        cur = cur->nextver_point;
    }
    return;
}

void DFSTraverse_L(MGraph *N)  // 从第一个顶点起,深度优先搜索图N 
{
    int v;
    printf("图N的深度优先遍历:\n");
    Visited_init(N);
    
    for(v=0; v<g_vernum; v++)
    {
        if(Visited_get(v) == 1)
        {
            continue;
        }

        DFS_L(N, N->vertex[v].nextver_point, v);   //对未访问的顶点r进行深度优先遍历
    }

    printf(":end\n");
}
void DFS_T(MGraph *N,int i)   //从顶点r出发递归深度优先搜索图N
{
    int j;
    Visited_set(i);
    Visit(N->vertex[i].data);  //访问第r个顶点

    for(j=0;j<g_vernum;j++)
    {
        if(N->arcs[i*g_vernum + j] != 0 && Visited_get(j)!=1)
        {
            DFS_T(N,j);
        }
    }
    return;
}
void DFSTraverse_T(MGraph *N)  // 从第一个顶点起,深度优先搜索图N 
{
    int v;
    printf("图N的深度优先遍历:\n");

    Visited_init(N);
    
    for(v=0; v<g_vernum; v++)
    {
        if(Visited_get(v) == 1)
        {
            continue;
        }

        DFS_T(N,v);   //对未访问的顶点r进行深度优先遍历
    }
    printf(":end\n");
}
int	BFS_L(MGraph *N)
{
    int t=0;
    AdjList *p;
    while(!Queue_empty() && !Queue_full())  //如果队列不空
    {
        t=Dequeue();   //队首元素出队赋值给v

        p=N->vertex[t].nextver_point;

        while(p!=&N->vertex[t])  //遍历序号为v的所有邻接点
        {
            if(Visited_get(p->nextver_index)==0)  //如果该顶点未被访问过
            {
                Visited_set(p->nextver_index);
                Visit(N->vertex[p->nextver_index].data);
                Enqueue(p->nextver_index);
            }
            p=p->nextver_point;   //p指向下一个邻接点
        }
    }
    return 0;
}

void BFSTraverse_L(MGraph *N)  //从第一个顶点出发,按广度优先非递归搜索图N
{
    int v;

    printf("按广度优先非递归搜索图N: \n");
    Visited_init(N);
    Queue_init();

    for(v=0; v<g_vernum; v++)
    {/*防止出现了图*/
        if(Visited_get(v) == 1)
        {
            continue;
        }
        Visited_set(v);

        Visit(N->vertex[v].data);
        Enqueue(v);
        BFS_L(N);
    }
    printf(":end \n");
}
int BFS_T(MGraph *N)
{
    int j;
    int t=0;
    while(!Queue_empty() && !Queue_full())  //如果队列不空
    {
        t=Dequeue();   //队首元素出队赋值给v
        for(j=1;j<g_vernum;j++)
        {
            if(N->arcs[t*g_vernum + j]==1)
            {
                if(Visited_get(j)==0)  //如果该顶点未被访问过
                {
                    Visited_set(j);
                    Visit(N->vertex[j].data);
                    Enqueue(j);
                }
            }
        }
        
    }
}
void BFSTraverse_T(MGraph *N)  //从第一个顶点出发,按广度优先非递归搜索图N
{
    
    int v;

  	printf("图N的广度优先遍历:\n");
    Visited_init(N);
    Queue_init();

    for(v=0; v<g_vernum; v++)
    {
        if(Visited_get(v) == 1)
        {
            continue;
        }
        Visited_set(v);

        Visit(N->vertex[v].data);
        Enqueue(v);
        BFS_T(N);
    }

    printf(":end \n");

}
int GraphInit(MGraph *N)
{
    g_queue_size = g_vernum * g_vernum;
    /*初始化邻接表*/
    N->vertex = (AdjList *)malloc(sizeof(AdjList) * g_vernum);
    /*初始化邻接矩阵*/
    N->arcs = (int *)malloc(sizeof(int) * g_vernum * g_vernum);
    /*初始化访问标志*/
    g_visited = (int *)malloc(sizeof(int) * g_vernum);
    /*初始化队列*/
    g_queue = (int *)malloc(sizeof(int) * g_queue_size);

        
    if(N->vertex == NULL || N->arcs == NULL 
        || g_visited == NULL || g_queue == NULL)
    {
        return -1;
    }
        
    return 0;
}
int GraphRelease(MGraph *N)
{

#ifdef GRAPH_LIST
    int i;
 	AdjList *p;
    AdjList *t;
    for(i=0;i<g_vernum;i++)
    {
        printf("%s[%d]",N->vertex[i].data,i);
        p=N->vertex[i].nextver_point;   //将p指向边表的第一个结点
        while(p != &N->vertex[i])
        {
            t=p;
            p=p->nextver_point;
            free(t);
        }
    }
#endif
    free(N->arcs);
    free(g_visited);
    free(g_queue);
    free(N->vertex);
    return 0;
    
}
int  main()
{
    int ret;
    MGraph N;

again:
    printf("请输入无向图的顶点数,边数(逗号隔开):\t");
    scanf("%d,%d",&g_vernum,&g_arcnum);
    printf("\n\n");
    if( g_vernum== 0 || g_arcnum== 0)
    {
        goto again;
    }

    ret = GraphInit(&N);
    if(ret == -1)
    {
        printf("程序初始化失败\n");
        return 0;
    }
#ifdef GRAPH_LIST
    printf("邻接表链表结构\n");
    CreateGraph_L(&N);
    DisplayGraph_L(&N);
    BFSTraverse_L(&N);
    DFSTraverse_L(&N);

#endif
    printf("\n\n邻接矩阵结构\n");
    CreateGraph_T(&N);
    DisplayGraph_T(&N);
    BFSTraverse_T(&N);
    DFSTraverse_T(&N);
    
    GraphRelease(&N);
    exit(0);
    return 0;
 }

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/liuzhuchen/article/details/21564977
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞