图的广度优先遍历(邻接矩阵存储图)

图的广度优先遍历(邻接矩阵)


广度优先遍历算法思想:

借助队列,先将第一个顶点入队,每次顶点出队的时候,打印输出该顶点,然后再遍历邻接矩阵,把与该顶点所在行的所有不为0的纵坐标入队,如此重复直到所有的顶点都出队,这样对邻接矩阵存储的图的广度优先遍历就遍历完毕了。


测试数据:

8 10
1 2 3 4 5 6 7 8
1 2
1 5
2 6
3 6
3 7
3 4
4 7
4 8
6 7
7 8

#include
#include
using namespace std;     //vertex:顶点    arc:弧    adjacent:邻近的 
#define MaxVertexNum 100
typedef char VertexType;  //顶点的数据类型
typedef int EdgeType;   //边的数据类型
typedef struct{
	VertexType Vex[MaxVertexNum];  //定点表 
	EdgeType  Edge[MaxVertexNum][MaxVertexNum];  //邻接矩阵,边表 
	int vernum,arcnum; //图的当前顶点数和弧数 
}MGraph; //适合存储稠密图 

//队、队结点的存储结构 
typedef struct LinkNode{
	int data;
	struct LinkNode *next;
}LinkNode;
typedef struct {
	LinkNode *front,*rear; 
}LinkQueue,*PLinkQueue;

//初始化队列
void InitQueue(LinkQueue &Q)
{
	Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));//头指针和尾指针指向同一节点,该节点无内容 
	Q.front->next=NULL; 
	Q.rear->next=NULL;
}

//判队空
bool EmptyQueue(LinkQueue Q)
{
	if(Q.front==Q.rear)
	return true;
	else
	return false; 
}

//入队
void EnQueue(LinkQueue &Q,int x)
{
	LinkNode *S=(LinkNode*)malloc(sizeof(LinkNode));
	S->data=x;
	S->next=NULL;
	Q.rear->next=S;
	Q.rear=S;
}
//出队
bool DeQueue(LinkQueue &Q,int &T)
{
	if(EmptyQueue(Q))
		return false;
	LinkNode *p=Q.front->next;
	T=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("请输入图的顶点数和边数:");
	cin>>G->vernum>>G->arcnum;
	printf("请输入图的各个顶点的信息(A,B…):");
	for(i=1;i<=G->vernum;i++)
		cin>>G->Vex[i];//"%c"中%c后面要有空格 
	for(i=1;i<=G->vernum;i++)
	{
		for(j=1;j<=G->vernum;j++)
			G->Edge[i][j]=0;		
	} 
	printf("请输入各条边的信息(例:1 2表示在A顶点和B顶点之间有一条边):\n");
	for(k=1;k<=G->arcnum;k++)
	{//此为创建有向图的邻接矩阵 
		int Iindex,Jindex; 
		cin>>Iindex>>Jindex;
		G->Edge[Iindex][Jindex]=1;
		//如果加上G->Edge[j][i]=1;则建立的是无向图的邻接矩阵 
		G->Edge[Jindex][Iindex]=1;
	}		
} 

//打印邻接矩阵
void DisplayMGraph(MGraph G)
{
	int i,j;
	printf("	");
	for(i=1;i<=G.vernum;i++)
	printf("%c ",G.Vex[i]);
	for(i=1;i<=G.vernum;i++)
	{
		printf("\n%c\t",G.Vex[i]);
		for(j=1;j<=G.vernum;j++)
			printf("%d ",G.Edge[i][j]); 
	}	
} 

bool Visited[MaxVertexNum];//记录结点是否被访问过 
LinkQueue Q;

int FirstNeighbor(MGraph G,int x)
{
	int k;
	for(k=1;k<=G.vernum;k++)
	{
		if(G.Edge[x][k]==1)
			break; 
	}
	if(k<=G.vernum)
		return k; 
	else
		return -1;
}

int NextNeighbor(MGraph G,int x,int y)
{
	int j;
	for(j=y+1;j<=G.vernum;j++)
	{
		if(G.Edge[x][j]==1)
			break;
	}
	if(j<=G.vernum)
		return j;
	else
		return -1;
}

void BFS(MGraph G,int v)
{
	printf("%c ",G.Vex[v]);	
	Visited[v]=true;
	EnQueue(Q,v);
	while(!EmptyQueue(Q))
	{
		int i;
		DeQueue(Q,v);
		for(i=FirstNeighbor(G,v);i>=0;i=NextNeighbor(G,v,i))
		{
			if(!Visited[i])
			{
				printf("%c ",G.Vex[i]);
				Visited[i]=true;
				EnQueue(Q,i);
			}	
		}
	}
} 
void BFSTraverse(MGraph G)//breadth first search 广度优先遍历 
{//算法思想:类似于树的层序遍历,创建一个队列,入队,当队空时,
//图遍历完毕。
	int i; 
	InitQueue(Q);
	for(i=1;i<=G.vernum;i++)
		Visited[i]=false; 
	for(i=1;i<=G.vernum;i++)
	{
		if(!Visited[i])
			BFS(G,i);
	} 
}
int main()
{
	MGraph G;
	CreateMGraph(&G);
	DisplayMGraph(G);
	printf("\n从顶点1开始的图的深度优先遍历序列为:");
	BFSTraverse(G);
	return 0; 
} 



测试结果:

图的广度优先遍历(邻接矩阵存储图)_第1张图片

你可能感兴趣的:(数据结构)