圖的遍歷:深度優先搜尋與廣度優先搜尋

聽聞__發表於2018-04-26

1、定義

  • 深度優先搜尋(DFS):從圖中某個初始頂點v出發,首先訪問初始頂點v,然後選擇一個與頂點v相鄰且沒被訪問過的頂點w為初始頂點,再從w出發進行深度優先遍歷,直到圖中與當前頂點v鄰接的所有頂點都被訪問過為止。
  • 廣度優先搜尋(BFS):首先訪問初始頂點v,接著訪問頂點v的所有未被訪問過的鄰接點v1,v2,...,vt,然後再按照v1,v2,...,vt的次序,訪問每一個頂點的所有未被訪問過的鄰接點,依次類推,直到圖中所有和初始頂點v有路徑相通的頂點都被訪問過為止。

2、應用

  • 深度優先搜尋主要用於圖的查詢。
  • 廣度優先搜尋主要用於求圖中兩個頂點的最短路徑。

3、實現

(1)鄰接矩陣圖的型別定義

#define N 100

typedef char ElemType;

//adjacency matrix graph
typedef struct MGraph
{
	ElemType vertexes[N];
	int edges[N][N];
	int visited[N];
	int n;
}MGraph;

(2)深度優先搜尋演算法(DFS)

//deep-first search
void DFS(MGraph &g, int k)
{
	cout << g.vertexes[k];
	g.visited[k] = 1;
	for (int i = 0; i < g.n; i++)
	{
		if (g.visited[i] == 0 && g.edges[k][i] != 0)
		{
			DFS(g, i);
		}
	}
}

(3)廣度優先搜尋演算法(BFS)

//breadth-first search
void BFS(MGraph g, int k)
{
	queue<int> q;
	q.push(k);
	g.visited[k] = 1;
	while (!q.empty())
	{
		k = q.front();
		cout << g.vertexes[k];
		q.pop();
		for (int i = 0; i < g.n; i++)
		{
			if (g.visited[i] == 0 && g.edges[k][i] != 0)
			{
				q.push(i);
				g.visited[i] = 1;
			}
		}
	}
}

4、測試

樣例輸入:

5
HUEAK 
0 0 2 3 0
0 0 0 7 4
2 0 0 0 0
3 7 0 0 1
0 4 0 1 0

預期輸出:

HUEAK
HUEAK 
#include <iostream>
#include <queue>
using namespace std;

#define N 100

typedef char ElemType;

//adjacency matrix graph
typedef struct MGraph
{
	ElemType vertexes[N];
	int edges[N][N];
	int visited[N];
	int n;
}MGraph;

//deep-first search
void DFS(MGraph &g, int k)
{
	cout << g.vertexes[k];
	g.visited[k] = 1;
	for (int i = 0; i < g.n; i++)
	{
		if (g.visited[i] == 0 && g.edges[k][i] != 0)
		{
			DFS(g, i);
		}
	}
}

//breadth-first search
void BFS(MGraph g, int k)
{
	queue<int> q;
	q.push(k);
	g.visited[k] = 1;
	while (!q.empty())
	{
		k = q.front();
		cout << g.vertexes[k];
		q.pop();
		for (int i = 0; i < g.n; i++)
		{
			if (g.visited[i] == 0 && g.edges[k][i] != 0)
			{
				q.push(i);
				g.visited[i] = 1;
			}
		}
	}
}

int main()
{
	int n;
	while (cin >> n)
	{
		//init
		MGraph g;
		g.n = n;
		//input
		for (int i = 0; i < n; i++)
			cin >> g.vertexes[i];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				cin >> g.edges[i][j];
		//print
		memset(g.visited, 0, n * sizeof(int));
		DFS(g, 0); cout << endl;
		memset(g.visited, 0, n * sizeof(int));
		BFS(g, 0); cout << endl;
	}
	return 0;
}

參考文獻

[1] 李春葆.資料結構教程.清華大學出版社,2013.


相關文章