BFS

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

为了简单,ABCD用1234来代替

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
typedef int VertexType;
#define MaxVertexNum 100

// 需要设计两种结点结构类型:一是定点表的顶点,二是单链表的结点
typedef struct ArcNode{  // 边表结点
	int adjvex;  // 该弧所指向的顶点的位置
	struct ArcNode *next;  // 指向下一条弧的指针
}ArcNode;

typedef struct VNode{  // 顶点表结点
	VertexType data;  // 顶点信息
	ArcNode *firstedge;  // 单链表头指针
}VNode, AdjList[MaxVertexNum];

typedef struct{
	AdjList vertices;  // 邻接表
	int vexnum, arcnum;  // 图的顶点数和弧数
}ALGraph;

typedef struct queue{
	int front;
	int rear;
	int elem[MaxVertexNum];
};

void InitQueue(queue *q){
	q->front = q->rear = 0;
}

void Enqueue(queue *q, int v){
	if ((q->rear + 1) % MaxVertexNum == q->front) return;
	q->elem[q->rear] = v;
	q->rear = (q->rear + 1) % MaxVertexNum;
}

void DeQueue(queue *q, int &v){
	if (q->rear == q->front) return;
	v = q->elem[q->front];
	q->front = (q->front + 1) % MaxVertexNum;
}

bool isEmpty(queue *q){
	if (q == NULL) return true;
	else return false;
}

/*
创建邻接表函数,参数为一个邻接表变量
该函数将提示用户输入创建一个邻接表所需要的关键信息,
包括图中结点个数,边的条数,每个结点存储的数据,每条边两边结点的索引值
*/
int LocalBow(char data, ALGraph *g){  // 查询顶点的位置
	int i;
	for (int i = 0; i < g->arcnum; ++i){
		if (g->vertices[i].data == data){
			return i;
		}
	}
	return 0;
}

void CreateAL(ALGraph *g){
	int end;
	int start;
	cout << "请输入结点数和边数: ";
	cin >> g->vexnum >> g->arcnum;
	cout << "请输入每个顶点保存的数据: " << endl;
	for (int i = 0; i < g->vexnum; i++){  // vexnum 图的顶点数
		cout << "vertex" << i << ":";
		cin >> g->vertices[i].data;  // 给每一个顶点赋值
		g->vertices[i].firstedge = NULL;  // 初始化时一定要让每个顶点的指针为空,否则为野指针
	}
	cout << "请输入每条边的两个顶点在数组中的的下标(中间用空格分隔)" << endl;

	for (int j = 0; j < g->arcnum; j++){   // arcnum 图的弧数
		cout << "请输入第" << j << "条边" << endl;
		cin >> start >> end;  // 接收从start ----> end
		ArcNode *node = (ArcNode *)malloc(sizeof(ArcNode));  // 边表结点
		node->adjvex = end;  // 该弧所指向的顶点的位置
		node->next = g->vertices[start].firstedge;  // 头插法插入边结点
		g->vertices[start].firstedge = node;  // 顶点的firstedge为node
	}
}

/*
打印链表函数,接收一个邻接表指针变量,和边表结点指针变量
该函数专门用于打印邻接表中链表的结点数据
*/
void PrintLink(ALGraph *g, ArcNode *next){
	while (next != NULL){
		cout << g->vertices[next->adjvex].data << " ";
		next = next->next;
	}
	cout << endl;
}

/*
打印创建好的邻接表函数,接收一个邻接表指针变量
该函数将打印每个顶点以及与其相连的顶点中保存的数据
*/
void disp(ALGraph *g){
	cout << "邻接表为: " << endl;
	for (int i = 0; i < g->vertices[i].data; i++){
		cout << g->vertices[i].data << " ";
		PrintLink(g, g->vertices[i].firstedge);
	}
}

// -------------------------------------------------------
//上面部分是邻接表,下面是BFS代码
bool visited[MaxVertexNum];
void Init_visited(bool visited[], int len){
	for (int i = 0; i < len; ++i){
		visited[i] = false;
	}
}

void BFS(ALGraph *g, int v){  // 图,你决定访问的第一个顶点
	ArcNode *p = NULL;  // 工作指针p
	queue * q = (queue*)malloc(sizeof(queue));
	InitQueue(q);  // 初始化一个队列
	printf("%d ", g->vertices[v].data);  // 访问第一个顶点v
	visited[v] = true;  // 对v做已访问标记,visited一开始要全部初始化为false
	Enqueue(q, v);  // 顶点v入队列
	while (!isEmpty(q)){  // 只要队列不空
		DeQueue(q, v);  // 顶点v出队列
		p = g->vertices[v].firstedge;  // 指针p指向当前顶点的边表链表头指针
		while (p){
			if (!visited[p->adjvex]){  // p所指向顶点如果未被访问
				printf("%d ", g->vertices[p->adjvex].data);  // 访问p所指向的顶点
				visited[p->adjvex] = true;  // 对这个顶点做已访问标记
				Enqueue(q, p->adjvex);  // 这个顶点入队列
			}
			p = p->next;  // p指向该顶点的下一条边
		}	
	}
}

int main(void){
	ALGraph* g = (ALGraph*)malloc(sizeof(ALGraph));//创建邻接表
	CreateAL(g);//屏幕打印邻接表
	disp(g);
	cout << "广度优先遍历打印树: ";	
	Init_visited(visited, MaxVertexNum);
	BFS(g, 0);
	system("pause");
	return 0;
}

在这里插入图片描述

这里着重讲了广度优先遍历的过程,邻接表在另外的博客详述

https://blog.csdn.net/wysw1998/article/details/102897133
队列用的自己写的循环队列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值