广度优先遍历(邻接表存储图)

广度优先遍历(邻接表存储图)



思路:

对邻接表的广度优先遍历与对邻接矩阵的广度优先遍历类似;每个顶点的边表都保存着与该顶点直接相邻的顶点,即从该顶点出发能到达的所有顶点。所以只要在队列中弹出该顶点的时候,遍历该顶点的边表,就可以将其所有的边入队。如此循环直到最后一个顶点出队,就完成了对邻接表表示的图的广度优先遍历。


测试数据

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

#include
#include
using namespace std;
#define MaxVertexNum 100

typedef int InfoType;
typedef char VertexType; 
typedef struct node{
	int adjvertex; //临界点域,一般存放顶点对应的序号或在表头向量中的坐标
	InfoType info;//网的边权值
	struct node *next; //指向下一个邻接点 
}EdgeNode;//表结点 

typedef struct VNode{
	int vertex;//顶点域
	EdgeNode *firstedge;//边表头指针 
}VertexNode;//顶点结点 

typedef struct{
	VertexNode adjlist[MaxVertexNum]; //邻接表
	int vertexNum,edgeNum;//顶点数和边数 
}ALGraph;

//队、队结点的存储结构 
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 CreateGraph(ALGraph *G)
{
	int i,j,k;
	EdgeNode *p;
	printf("请输入图的顶点数和边数:");	
	cin>>G->vertexNum>>G->edgeNum;
	printf("请输入图的各个顶点的信息(A,B…):");
	for(i=1;i<=G->vertexNum;i++)//建立顶点表 
	{
		cin>>G->adjlist[i].vertex;
		G->adjlist[i].firstedge=NULL;	
	} 
	printf("请输入各条边的信息(例:1 2表示在A顶点和B顶点之间有一条边):\n");
	for(k=1;k<=G->edgeNum;k++)//头插法建立边表 
	{
		int headIndex;
		int tailIndex; 
		cin>>tailIndex>>headIndex;
		p=(EdgeNode*)malloc(sizeof(EdgeNode));
		p->adjvertex=headIndex;	
		p->next=G->adjlist[tailIndex].firstedge;
		G->adjlist[tailIndex].firstedge=p; 
	} 
} 

//打印邻接表法创建的表 
void DisplayALGraph(ALGraph G)
{
	int i;
	printf("图的邻接矩阵如下:\n"); 
	for(i=1;i<=G.vertexNum;i++)
	{
		printf("%d  ",G.adjlist[i].vertex);
		EdgeNode *p=G.adjlist[i].firstedge; 
		while(p!=NULL)
		{
			printf("->%d ",p->adjvertex);
			p=p->next; 
		}
		printf("\n");
	}
} 

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

void BFS(ALGraph G,int v)
{
	printf("%d ",G.adjlist[v].vertex);
	Visited[v]=true;
	EnQueue(Q,v);
	while(!EmptyQueue(Q))
	{
		int i;
		EdgeNode *p;
		DeQueue(Q,v);
		for(p=G.adjlist[v].firstedge;p;p=p->next)
		{
			if(!Visited[p->adjvertex])
			{
				printf("%d ",p->adjvertex);
				Visited[p->adjvertex]=true;
				EnQueue(Q,p->adjvertex);
			}	
		}	
	}	
} 

//广度优先遍历
void BFSTraverse(ALGraph G)
{
	int i;
	InitQueue(Q);
	for(i=1;i<=G.vertexNum;i++)
	{
		if(!Visited[i])
			BFS(G,i);
	} 
} 
//主函数
int main()
{
	ALGraph G;
	CreateGraph(&G);
	DisplayALGraph(G);
	printf("从顶点7开始的广度优先遍历序列为:"); 
	BFSTraverse(G);
	return 0;
}

代码测试

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

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