广度优先搜索——邻接矩阵

广度优先搜索——邻接矩阵


需要了解的是,图的广度搜索遍历类似于二叉树的层次遍历,用到了队的操作
代码如下

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

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXVEX 100

typedef int DataType;	/*设置队数据类型,可修改*/
typedef int VexType;
typedef int EdgeType;
typedef struct{
	DataType data[MAXVEX];
	int front;
	int rear; 
}Queue;				/*定义栈结构体*/

typedef struct{
	VexType ves[MAXVEX];	/*顶点表*/
	EdgeType edge[MAXVEX][MAXVEX];	/*边表*/
	int v;				/*结点数*/
	int e;				/*边数*/
}MGraph;					/*邻接矩阵*/
 
void Ini_Queue(Queue *Q){		/*创建队*/
	Q->front=Q->rear=0;
}

int In_Queue(Queue *Q,DataType e){	/*入队*/
	if(Q->front!=(Q->rear+1)%MAXVEX){
		Q->data[Q->rear]=e;
		Q->rear=(Q->rear+1)%MAXVEX;
		return OK;	
	}
	else return FALSE;
}

int Empty_Queue(Queue Q){			/*判队空*/
	if(Q.front==Q.rear)	return TRUE;
	else return FALSE;
}

int Out_Queue(Queue *Q,DataType *e){	/*出队*/
	if(Empty_Queue(*Q))	return FALSE;
	else {
		*e=Q->data[Q->front];
		Q->front=(Q->front+1)%MAXVEX;
	}
	return TRUE;
}

int Creat_MGraph(MGraph *M){		/*创建邻接矩阵*/
	int i,j,k;
	printf("请输入结点个数和边数(v,e):");
	scanf("%d%d",&(M->v),&(M->e));		/*输入顶点数与边数*/
	printf("键入结点表信息:\n");	
	for(i=0;i<M->v;i++)			/*创建顶点表*/
	scanf("%d",&(M->ves[i]));
	for(i=0;i<M->v;i++)
		for(j=0;j<M->v;j++) 
			M->edge[i][j]=0;		/*初始化边表全为0*/	 
	printf("键入边表信息(格式:i,j,范围(1-n):\n");
	for(k=0;k<M->e;k++){			/*创建边表*/
		scanf("%d%d",&i,&j);
		M->edge[i-1][j-1]=1;		/*填充edge[i][j]上的边*/
		M->edge[j-1][i-1]=1;		/*填充edge[i][j]上的边*/
	}
	return OK;
}

void Mprint(MGraph M){	//打印邻接矩阵
		 for(int i=0;i<M.v;i++)
	 {
	 printf("________________________________________\n");
	 	for(int j=0;j<M.v;j++)
		 printf("|%-3d|",M.edge[i][j]); 
		 printf("\n");
		 }
	 printf("________________________________________\n");
}


int visit[MAXVEX]={FALSE};		/*visit数组标记顶点访问情况*/ 

int BFSM(MGraph M,DataType V){	/*广度优先遍历算法*/ 
	int i;
	DataType k=V;
	for(i=0;i<M.v;i++)			/*将标记数组置为false*/
		visit[i]=FALSE;
	Queue Q;
	Ini_Queue(&Q);			/*初始化队*/
	In_Queue(&Q,k);			/*入队开始结点的序号*/
	while(!Empty_Queue(Q)){
		Out_Queue(&Q,&k);	/*先出队一个顶点序号*/
		printf("%d ",M.ves[k-1]);
		visit[k-1]=TRUE;		/*将已经访问的顶点标记为true*/
		for(i=0;i<M.v;i++)		/*将已被访问的顶点的未被访问的邻接点入队*/
			if(!visit[i]&&M.edge[k-1][i]==1)	
			In_Queue(&Q,i+1);	
	}
	return OK;				/*当队中不在有元素,则遍历结束*/ 
}

测试代码

int main(){		/*测试*/
	MGraph M;
	DataType V;
	Creat_MGraph(&M);
	Mprint(M); 
	while(1){
		printf("\n请输入一个开始结点的序号:(范围1--结点数,超过该范围退出程序):");
		scanf("%d",&V);
		if(V>M.v)return 0;		/*大于结点数退出程序*/ 
		BFSM(M,V);
	}
	 return 0;
}
/*
样例输入:
5 4

1 2 3 4 5 

1 3
2 3
2 5
2 4

以第三个结点开始: 3
得到	3 1 2 4 5 
*/
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值