1. 程式人生 > 其它 >(最詳細合理程式碼)C++實現圖的深度優先遍歷、廣度優先遍歷和拓撲排序演算法

(最詳細合理程式碼)C++實現圖的深度優先遍歷、廣度優先遍歷和拓撲排序演算法

技術標籤:資料結構演算法資料結構

yysy,xdm不要照抄,起碼改個變數名和順序吧,我有點慌(doge

圖的鄰接矩陣和鄰接表矩陣

void createGraph(vector<vector<int>>& edge, vector<vector<int>>& edge1,int start, int end, vector<int> inDegree) {
	edge[start][end] = 1;
	edge1[start].push_back(end);
}
//列印儲存的圖
void displayGraph
(vector<vector<int>>& edge, vector<vector<int>>& edge1) { int i, j; cout << "鄰接矩陣: " << endl; for (i = 0; i < VERTEXNUM; i++) { for (j = 0; j < VERTEXNUM; j++) { //printf("%d ", edge[i][j]); cout << edge[i][j] <<
" "; } cout << endl; } cout << "鄰接表矩陣: " << endl; for (i = 0; i < VERTEXNUM; i++) { for (j = 0; j < edge1[i].size(); j++) { //printf("%d ", edge[i][j]); cout << edge1[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);
		}
	}
}

廣度優先遍歷

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;
}

拓撲排序演算法

bool TopSort(vector<vector<int>>& G, int n, vector<int>& inDegree) {

	vector<int> res;

	int cnt = 0; // 記錄加入圖片排序的頂點數

	queue<int> q;
	for (int i = 0; i < n; i++) {
		if (inDegree[i] == 0) {
			// 入度為0,入隊
			q.push(i);
		}
	}

	while (!q.empty()) {
		// 取隊首
		int from = q.front(); q.pop();
		// 訪問from
		res.push_back(from);

		// 遍歷鄰接表:它能到的頂點
		for (int i = 0; i < G[from].size(); i++) {
			int to = G[from][i];
			if (--inDegree[to] == 0) {
				q.push(to);
			}
		}
		// 把form能到的邊全部清空
		G[from].clear();
		cnt++;
	}

	for (auto x : res) {
		cout << x << ends;
	}
	cout << endl;

	if (cnt == n) {
		return true;
	}
	return false;
}

一段程式碼實現一個圖的多種遍歷

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

using namespace std;

#define VERTEXNUM 5

void createGraph(vector<vector<int>>& edge,  vector<vector<int>>& edge1 ,int start, int end, vector<int> inDegree);
void displayGraph(vector<vector<int>>& edge, vector<vector<int>>& edge1);
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);
bool TopSort(vector<vector<int>>& G, int n, vector<int>& inDegree);

int main(void) {

	//初始化鄰接矩陣
	vector<vector<int>>edge(VERTEXNUM, vector<int>(VERTEXNUM, 0));
	//存放頂點的遍歷狀態,0:未遍歷,1:已遍歷  
	vector<int> vertexStatusArr(VERTEXNUM, 0);
	vector<int> vertexStatusArr1(VERTEXNUM, 0);
	vector<int> inDegree(VERTEXNUM);//入度
	vector<vector<int>>edge1(VERTEXNUM);//鄰接表矩陣
	cout << "after init: " << endl;
	displayGraph(edge,  edge1);
	//建立圖
	createGraph(edge, edge1, 0, 1, inDegree);
	createGraph(edge, edge1, 0, 2, inDegree);
	createGraph(edge, edge1, 2, 1, inDegree);
	createGraph(edge, edge1, 0, 3, inDegree);
	createGraph(edge, edge1, 1, 3, inDegree);
	createGraph(edge, edge1, 3, 4, inDegree);
	createGraph(edge, edge1, 2, 4, inDegree);
	for (auto x : edge1) {
		for (auto y : x)
			inDegree[y]++;
	}
	/*for (int i = 0; i < VERTEXNUM; i++)
	{
		cout << inDegree[i] << " ";
	}
	cout<< endl;*/ //可以展示入度。
	cout << "after create: " << endl;
	displayGraph(edge,edge1);
	//深度優先遍歷
	cout << "DFS: " << endl;
	DFS(edge, vertexStatusArr);
	cout << "BFS: " << endl;
	BFS(edge, vertexStatusArr1);
	cout << "TopologicalSort: " << endl;
	bool res = TopSort(edge1, VERTEXNUM, inDegree);
	return 0;
}

參考資料:https://blog.csdn.net/JMW1407/article/details/108590505?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160751646119721940226866%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160751646119721940226866&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-6-108590505.first_rank_v2_pc_rank_v29&utm_term=C++%E6%B7%B1%E5%BA%A6%E4%BC%98%E5%85%88%E9%81%8D%E5%8E%86%E7%AE%97%E6%B3%95
https://blog.csdn.net/qjh5606/article/details/88633020?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160751788919725271670256%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160751788919725271670256&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-7-88633020.first_rank_v2_pc_rank_v29&utm_term=C++%E6%8B%93%E6%89%91%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95
兩個連結有一些理論層面的知識,可供參閱。