C++实现图的深度优先遍历和广度优先遍历

图的深度和广度优先遍历

图的深度优先遍历

1、算法思想

  • (1)从图中的某个初始点 v 出发,首先访问初始点 v.
  • (2)选择一个与顶点 v 相邻且没被访问过的顶点 ver ,以 ver为初始顶点,再从它出发进行深度优先遍历。
  • (3)当路径上被遍历完,就访问上一个顶点的第 二个相邻顶点。
  • (4)直到所有与初始顶点 v联通的顶点都被访问。

2、邻接矩阵构造图

#include <iostream>
#include <vector>

using namespace std;

#define VERTEXNUM 5

void createGraph(vector<vector<int>>&edge, int start, int end);
void displayGraph(vector<vector<int>>&edge);
void DFS(vector<vector<int>>&edge , vector<int>& vertexStatusArr);
void DFScore(vector<vector<int>>&edge, int i, vector<int>& vertexStatusArr);

int main(void) {
	
	//初始化邻接矩阵
	vector<vector<int>>edge(VERTEXNUM, vector<int>(VERTEXNUM, 0));
	
	//存放顶点的遍历状态,0:未遍历,1:已遍历  
	vector<int> vertexStatusArr (VERTEXNUM,0);

	cout << "after init: " << endl;
	displayGraph(edge);
	//创建图
	createGraph(edge, 0, 3);
	createGraph(edge, 0, 4);
	createGraph(edge, 3, 1);
	createGraph(edge, 3, 2);
	createGraph(edge, 4, 1);

	cout << "after create: " << endl;
	displayGraph(edge);
	//深度优先遍历
	DFS(edge, vertexStatusArr);

	return 0;
}
//创建图 
void createGraph(vector<vector<int>>&edge, int start, int end) {
	edge[start][end] = 1;
}
//打印存储的图
void displayGraph(vector<vector<int>>&edge) {
	int i, j;
	for (i = 0; i<VERTEXNUM; i++) {
		for (j = 0; j<VERTEXNUM; j++) {
			//printf("%d ", edge[i][j]);
			cout << edge[i][j] << " ";
		}
		cout << endl;
	}
}
//深度优先遍历
void DFS(vector<vector<int>>&edge, vector<int>& vertexStatusArr) {
	cout << "start BFT graph: " << endl;
	for (int i = 0; i<VERTEXNUM; i++) {
		DFScore(edge, i, vertexStatusArr);
	}
	cout << endl;
}
void DFScore(vector<vector<int>>&edge, int i, vector<int>& vertexStatusArr) {
	if (vertexStatusArr[i] == 1) {
		return;
	}
	cout << i << " ";
	vertexStatusArr[i] = 1;

	for (int j = 0; j<VERTEXNUM; j++) {
		if (edge[i][j] == 1) {
			DFScore(edge, j, vertexStatusArr);
		}
	}
}

                                                                     在这里插入图片描述

设有n个点,e条边
邻接矩阵:矩阵包含n ^2个元素,在算法中,共n个顶点,对每个顶点都要遍历n次,所以时间复杂度为O(n^2)

3、邻接表构造图 

#include <stdio.h>
#include <malloc.h>

#define VERTEXNUM 5

//存放顶点的邻接表元素  
typedef struct edge {
	int vertex;
	struct edge* next;
}st_edge;

void createGraph(st_edge** edge, int start, int end);
void displayGraph(st_edge** edge);
void delGraph(st_edge** edge);
void DFT(st_edge** edge, int* vertexStatusArr);
void DFTcore(st_edge** edge, int i, int* vertexStatusArr);

int main(void) {
	//动态创建存放边的指针数组   
	st_edge** edge = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);
	int i;
	for (i = 0; i<VERTEXNUM; i++) {
		edge[i] = NULL;
	}
	//存放顶点的遍历状态,0:未遍历,1:已遍历  
	int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);
	for (i = 0; i<VERTEXNUM; i++) {
		vertexStatusArr[i] = 0;
	}

	printf("after init:\n");
	displayGraph(edge);
	//创建图  
	createGraph(edge, 0, 3);
	createGraph(edge, 0, 4);
	createGraph(edge, 3, 1);
	createGraph(edge, 3, 2);
	createGraph(edge, 4, 1);

	printf("after create:\n");
	displayGraph(edge);
	//深度优先遍历 
	DFT(edge, vertexStatusArr);
	//释放邻接表占用的内存  
	delGraph(edge);
	edge = NULL;
	free(vertexStatusArr);
	vertexStatusArr = NULL;
	return 0;
}
//创建图 
void createGraph(st_edge** edge, int start, int end) {
	st_edge* newedge = (st_edge*)malloc(sizeof(st_edge));
	newedge->vertex = end;
	newedge->next = NULL;
	edge = edge + start;
	while (*edge != NULL) {
		edge = &((*edge)->next);
	}
	*edge = newedge;
}
//打印存储的图 
void displayGraph(st_edge** edge) {
	int i;
	st_edge* p;
	for (i = 0; i<VERTEXNUM; i++) {
		printf("%d:", i);
		p = *(edge + i);
		while (p != NULL) {
			printf("%d ", p->vertex);
			p = p->next;
		}
		printf("\n");
	}
}
//释放邻接表占用的内存 
void delGraph(st_edge** edge) {
	int i;
	st_edge* p;
	st_edge* del;
	for (i = 0; i<VERTEXNUM; i++) {
		p = *(edge + i);
		while (p != NULL) {
			del = p;
			p = p->next;
			free(del);
		}
		edge[i] = NULL;
	}
	free(edge);
}
//深度优先遍历 
void DFT(st_edge** edge, int* vertexStatusArr) {
	printf("start BFT graph:\n");
	int i;
	for (i = 0; i<VERTEXNUM; i++) {
		DFTcore(edge, i, vertexStatusArr);
	}
	printf("\n");
}

void DFTcore(st_edge** edge, int i, int* vertexStatusArr) {
	if (vertexStatusArr[i] == 1) {
		return;
	}
	printf("%d ", i);
	vertexStatusArr[i] = 1;
	st_edge* p = *(edge + i);
	while (p != NULL) {
		DFTcore(edge, p->vertex, vertexStatusArr);
		p = p->next;
	}
}

                                                              在这里插入图片描述

 

邻接表:包含n个头结点和e个表结点,算法中对所有结点都要遍历一次,所以时间复杂度为O(n+e)

 图的广度优先遍历

1、算法思想

广度优先遍历( Breadth_First_Search) ,又称为广度优先搜索,简称BFS。

它的思想是:

从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,
然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。
如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。

                                                                      在这里插入图片描述

2、邻接矩阵构造图

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

#define VERTEXNUM 5

void createGraph(vector<vector<int>>&edge, int start, int end);
void displayGraph(vector<vector<int>>&edge);
void DFS(vector<vector<int>>&edge, vector<int>& vertexStatusArr);
void DFScore(vector<vector<int>>&edge, int i, vector<int>& vertexStatusArr);
void BFS(vector<vector<int>>&edge, vector<int>& vertexStatusArr);

int main(void) {

	//初始化邻接矩阵
	vector<vector<int>>edge(VERTEXNUM, vector<int>(VERTEXNUM, 0));

	//存放顶点的遍历状态,0:未遍历,1:已遍历  
	vector<int> vertexStatusArr(VERTEXNUM, 0);

	cout << "after init: " << endl;
	displayGraph(edge);
	//创建图
	createGraph(edge, 0, 3);
	createGraph(edge, 0, 4);
	createGraph(edge, 3, 1);
	createGraph(edge, 3, 2);
	createGraph(edge, 4, 1);

	cout << "after create: " << endl;
	displayGraph(edge);
	//深度优先遍历
	//DFS(edge, vertexStatusArr);
	BFS(edge, vertexStatusArr);
	return 0;
}
//创建图 
void createGraph(vector<vector<int>>&edge, int start, int end) {
	edge[start][end] = 1;
}
//打印存储的图
void displayGraph(vector<vector<int>>&edge) {
	int i, j;
	for (i = 0; i<VERTEXNUM; i++) {
		for (j = 0; j<VERTEXNUM; j++) {
			//printf("%d ", edge[i][j]);
			cout << edge[i][j] << " ";
		}
		cout << endl;
	}
}

//BFS
void BFS(vector<vector<int>>&edge ,vector<int>& vertexStatusArr) {
	queue<int>q;
	q.push(0);
	vertexStatusArr[0] = 1;
	int idx = 0;
	while (!q.empty())
	{
		idx = q.front();
		q.pop();
		cout << idx << " ";
		for (int j = 0; j< VERTEXNUM; j++) {
			if (edge[idx][j] == 1 && vertexStatusArr[j] == 0)
			{
				q.push(j);
				vertexStatusArr[j] = 1;
			}
		}
	}
	cout << endl;
}

 

                                                                       在这里插入图片描述

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值