(大话数据结构)邻接矩阵构造图,深度优先遍历和广度优先遍历

该文提供了一个C语言实现的邻接矩阵图,包括了深度优先遍历(DFS)和广度优先遍历(BFS)的修正代码,解决了原书中存在的输入错误问题,如scanf的类型指定和回车键处理。程序首先创建无向图的邻接矩阵,然后进行DFS和BFS遍历,以遍历图中的所有顶点。
/*邻接矩阵构造图,深度优先遍历和广度优先遍历
参考程杰的《大话数据结构》,但他的19年9月第23次印刷的
版本中存在代码的严重错误,本文对错误部分进行了修正 
*/
/*错误的内容为scanf没有表明输入类型,以及多次调用
scanf存在回车键被录入的问题,所以需要将缓冲区的内容清空 
*/

#include<stdio.h>
#include<stdlib.h>
typedef char VertexType;//顶点类型 
typedef int EdgeType; //边的类型
#define MAXVEX 100 //最大顶点数
#define INFINITY 65535 //用65535来代表无穷
#define TRUE 1
#define FALSE 0
#define MAX 10
typedef int Boolean;//Boollean是布尔类型,其值是TRUE或者FALSE
Boolean visited[MAX]; 
typedef struct{
	VertexType vexs[MAXVEX];//顶点表
	EdgeType arc[MAXVEX][MAXVEX]; //邻接矩阵,可看作边表 
	int numVertexes,numEdges; //图中当前的顶点数和边数 
}MGraph; 

typedef int ElemType;
typedef struct LinkNode{
	ElemType data;
	struct LinkNode *next;
}LinkNode;
typedef struct Queue{
	LinkNode *front,*rear;
}Queue;
void InitQueue(Queue &Q)
{
	Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
	Q.front->next = NULL;
}
bool IsEmpty(Queue Q)
{
	if(Q.front==Q.rear)
	{
		return true;
	}else
	{
		return false;
	}
}
void EnQueue(Queue &Q,ElemType x)
{
	LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
	s->data = x;
	s->next = NULL;
	Q.rear->next = s;
	Q.rear = s;
}
bool DeQueue(Queue &Q,ElemType &x)
{
	if(Q.front==Q.rear)
	{
		return false;
	}
	LinkNode *p = Q.front->next;
	x = p->data;
	Q.front->next = p->next;
	if(Q.rear ==p)
	{
		Q.rear = Q.front;
	}
	free(p);
	return true;
}

/*建立无项表的邻接矩阵表示*/
void CreateMGraph(MGraph *G)
{
	int i,j,k,w;
	printf("输入顶点数和边数\n");
	scanf("%d,%d",&G->numVertexes,&G->numEdges);//输入顶点数和边数 
	printf("请输入顶点名称:");
	fflush(stdin); //清除缓冲区,防止 回车重复读入 
	for( i = 0;i<G->numVertexes;i++)
	{
		scanf("%c",&G->vexs[i]); //顶点名称 
		fflush(stdin);//清除缓冲区,防止 回车重复读入 
	}
	for(i = 0;i<G->numVertexes;i++)
	{
		for(j = 0;j<G->numVertexes;j++)
		{
			G->arc[i][j] = INFINITY;//邻接矩阵初始化 
		}
	}
	for(k = 0;k<G->numEdges;k++)
	{
		printf("输入边(vi,vj)上的下标i,和j和权w:\n");
		scanf("%d,%d,%d",&i,&j,&w);//输入边(vi,vj)上的权w
		G->arc[i][j] = w;//权重赋值 
		G->arc[i][j] = G->arc[j][i];//因为是无向图,矩阵对称 
	}
}

/*邻接矩阵的深度优先递归算法*/
void DFS(MGraph G,int i)
{
	int j;
	visited[i] = TRUE;
	printf("%c ",G.vexs[i]);//打印顶点
	for(j = 0;j<G.numVertexes;j++)
	{
		if(G.arc[i][j] ==1 &&!visited[j])
		{
			DFS(G,j);//对未访问的邻接顶点递归调用 
		}
	} 
} 
/*邻接矩阵的深度遍历操作*/
void DFSTraverse(MGraph G)
{
	int i;
	for(i = 0;i < G.numVertexes; i++)
	{
		visited[i] = FALSE;//初始化visited数组,均未访问 
	}
	for(i = 0;i < G.numVertexes; i++)
	{
		if(!visited[i])//对未访问的顶点调用DFS,如果为连通图,只会调用一次 
		{
			DFS(G,i);
		}
	}
}

/*邻接矩阵的广度优先遍历算法*/
void BFSTraverse(MGraph G)
{
	int i,j;
	Queue Q;
	for(i=0;i<G.numVertexes;i++)
	{
		visited[i] = FALSE;//初始化 
	}
	InitQueue(Q);//辅助队列 
	for(i=0;i<G.numVertexes;i++)
	{
		if(!visited[i])
		{
			visited[i] = TRUE;//设置当前顶点访问过 
			printf("%c ",G.vexs[i]);//打印访问的结点 
			EnQueue(Q,i);//将其入队
			while(!IsEmpty(Q))
			{
				DeQueue(Q,i);//将其出队
				for(j=0;j<G.numVertexes;j++)
				{
					/*判断其他顶点与当前顶点是否有边并且未被访问过*/
					if(G.arc[i][j] == 1 && !visited[j])
					{
						visited[j]=TRUE;//将找到的顶点标记为已访问
						printf("%c ",G.vexs[j]);//打印改顶点
						EnQueue(Q,j);//将其入队 
					}
				} 
			} 
		}
	}
} 


int main()
{
	MGraph G;
	CreateMGraph(&G);
	printf("深度优先遍历的结果为:\n"); 
	DFSTraverse(G);
	printf("\n");
	printf("广度优先遍历的结果为:\n");
	BFSTraverse(G);
	return 0;
}

运行结果:
邻接矩阵

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值