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
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞