#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;
}
c语言编程 输出一个无向图的邻接表,邻接矩阵,进行深度和广度优先遍历
原文作者:数据结构之图
原文地址: https://blog.csdn.net/liuzhuchen/article/details/21564977
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/liuzhuchen/article/details/21564977
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。