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

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


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

#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 
*/

猜你喜欢

转载自blog.csdn.net/qq_41247335/article/details/84924041