邻接矩阵的广度优先遍历--C实现

嘻嘻,好高兴,自己一个人咬着牙挺到了现在,我已走了这么远的路

#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
#define MVN 20
#define Maxint 32767
#define MAXSIZE 20
typedef int QElemTypes;
typedef  char VerTexType;
typedef int ArcType;
typedef struct 
{
	QElemTypes* base;// 队列装载装置
	int front;//队头,此处会弹出警告,但是 QElemTypes = int 
	int rear;//队尾
	int length;
}SqQueue,SQueue;

typedef struct
{
	VerTexType Vexs[MVN];// 顶点矩阵
	ArcType Arcs[MVN][MVN];// 邻接矩阵
	int Vexnum,Arcnum;// 当前顶点数和边数
	_Bool visited[MVN];// 记录被访问过的节点
}AMGraph;// Adjacency Matrix Graph :邻接矩阵

int get_first(AMGraph* G, VerTexType* v);
int GetVertex(AMGraph* G);
int LocateVex(AMGraph* G,VerTexType v);
int Create_visited(AMGraph* G);
int FirstAdjVex(AMGraph* G, int u);
int NextAdjVex(AMGraph* G, int u, int w);
int InitQueue(SqQueue* Q);

int InitQueue(SqQueue* Q)//初始化
{
	Q->base = (QElemTypes*)malloc(sizeof(QElemTypes)*MAXSIZE);
	if(!Q->base) return 0;
	Q->front = Q->rear = 0;//头尾指针指向同一元素
	
	return 1;
}

int EnQueue(SqQueue* Q, QElemTypes e)
{
	if(!Q->base || (Q->rear + 1)%MAXSIZE ==Q->front)// 队列不存在或者已满
		return 0;
	Q->base[Q->rear] = e;//元素入队
	Q->rear = (Q->rear + 1)%MAXSIZE;// 队尾指针加一
	Q->length++;
	return 1;
}

int DeQueue(SqQueue* Q, QElemTypes* e)// 出队
{
	if(!Q->base || Q->rear == Q->front) return 0;
	(*e) = Q->base[Q->front]; //队头出队
	Q->front = (Q->front + 1)%MAXSIZE;//指针上移
	Q->length--;
	return 1;
}

int Traverse(SqQueue* Q)// 遍历队列
{
	if(!Q->base || Q->rear == Q->front) 
	{
		printf("队空,你出个锤子?!\n");
		return 0;
	}
	int temp = Q->front;
	for(int i = 0;temp != Q->rear;i++)
	{
		printf("队员%d的值为:%d\n",i,Q->base[Q->front]);
		temp = (temp + 1)%MAXSIZE;
	}
	return 1;
}

int DestroyQueue(SqQueue* Q)
{
	if(!Q->base) return 0;
	free(Q->base);
	Q->length = 0;
	return 1;
}

int ClearQueue(SqQueue* Q)
{
	if(!Q->base) return 0;
	for (int i = 0; i < MAXSIZE; i++)
	{
		Q->base[i] = 0;
	}
	Q->length = 0;
	return 1;
}

int QueueEmpty(SqQueue* Q)
{
	if(!Q->base || Q->front != Q->rear) return 0;
	return 1;
}

int QueueLength(SqQueue* Q)
{
	if(!Q->base) return 0;
	return Q->length;
}

int GetHead(SqQueue* Q,QElemTypes* e)
{
	if(!Q->base) return 0;
	return (*e) = Q->base[Q->front];
}


int CreateUDN(AMGraph* G)// 创建无向图
{	VerTexType v1;
	VerTexType v2;//弧的两个顶点
	int weight; // 弧的权重
	printf("输入顶点的数量:\n");
	scanf("%d",&(*G).Vexnum);// 指定顶点的数量
	printf("输入边的数量:\n");
	scanf("%d",&(*G).Arcnum);// 指定边的数量
	
	for(int i = 0; i< (*G).Vexnum; i++)//对于无向图,初始化为无穷大
	{
		for(int j = 0; j < (*G).Vexnum; j++)
			(*G).Arcs[i][j] = 0;
	}
	GetVertex(G);

	for (int k = 0; k < (*G).Arcnum; k++)// 数据写入矩阵
	{	printf("哪两个顶点之间是连通的?\n");
		printf("顶点1:\n");
		get_first(G,&v1);// 把输入的值写入到v1
		printf("顶点2:\n");
		get_first(G,&v2);//把输入的值写入到v2
		
		int i = LocateVex(G,v1);
		int j = LocateVex(G,v2);//定位两个顶点所在位置。
		(*G).Arcs[i][j] = 1;//表示有联系。
		(*G).Arcs[j][i] = (*G).Arcs[i][j];// 无向网的邻接矩阵沿对角线对称。
	}
	return 1;
}

int GetVertex(AMGraph* G)
{	
	for (int i = 0; i <(*G).Vexnum; i++)// 逐个输入顶点的值
	{	printf("输入顶点的值:\n");	
		get_first(G,&(*G).Vexs[i]);//写入到指定位置
	}
}

int LocateVex(AMGraph* G,VerTexType v)//查找顶点在顶点数组中的下标
{
	if(sizeof(*G) == 0) return 0;
	for(int i = 0; i < MVN; i++)
	{
		if((*G).Vexs[i] == v)
			return i;
	}
	return 0;
}

int get_first(AMGraph* G, VerTexType* v)//读取字符,并截断换行符
{	scanf("%d",EOF);
	(*v) = getchar();// 为什么在顶点数组创建完毕之后,指针会指向首元素?在建立通道阶段。
	while(getchar() != '\n')
		continue;
	return 1;
}

int Create_visited(AMGraph* G)
{	
	if(sizeof(*G) == 0) return 0;
	for(int i = 0; i< MVN;i++)
		(*G).visited[i] = false;
	return 1;
}



void BFS(AMGraph* G, int v, SqQueue* Q)// v表示从何处开始遍历
{	
	printf("BFS1:%c\n",(*G).Vexs[v]);//输出当前顶点的值
	(*G).visited[v] = true; //该顶点已被访问过,打上标记
	InitQueue(Q);//根据地址构造循环队列
	EnQueue(Q,v);// 把下标入队
	int u;// 存放队头节点,也就是正在访问的节点
	while(!QueueEmpty(Q))
	{	
		DeQueue(Q,&u);// u为第一个顶点
		for(int w = FirstAdjVex(G,u); w < (*G).Vexnum; w = NextAdjVex(G, u, w))// 已实现,需要优化!!,会打印一些没用的东西
		{	
			if(!(*G).visited[w])//为何此处一直是true??
			{
				printf("BFS2:%c\n",(*G).Vexs[w]);// 有待更改
				printf("w==%d\n",w);
				(*G).visited[w] = true;// w已被访问
				EnQueue(Q,w);// v的邻接点w入队
			}// if
		}// for
	}// while
}//BFS


int FirstAdjVex(AMGraph* G, int u)// 返回第一个相邻的且未被访问过的节点
{
	if(sizeof((*G)) == 0) return 0;
	//printf("Here\n");
	for(int j = 0; ; j++)
		if( (*G).Arcs[u][j] != 0 && !(*G).visited[j])
			return j;
}

int NextAdjVex(AMGraph* G, int u, int w)// 返回第一个相邻节点的下一个节点,且未被访问过
{
	if(sizeof((*G)) == 0) return 0;
	for(int j = w;  ; j++)
		if((*G).Arcs[u][j] != 0 && !(*G).visited[j])
			return j;
}
int main()
{
		SqQueue Q;
		AMGraph G;
		CreateUDN(&G);
		Create_visited(&G);
		BFS(&G,0,&Q);
		
		return 0;		
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山河锦绣放眼好风光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值