圖-深度優先搜索

簡介:

深度優先搜索屬於圖算法的一種,是一個針對圖和樹的遍歷算法,英文縮寫爲DFS即Depth First Search。深度優先搜索是圖論中的經典算法,利用深度優先搜索算法可以產生目標圖的相應拓撲排序表,利用拓撲排序表可以方便的解決很多相關的圖論問題,如最大路徑問題等等。一般用堆數據結構來輔助實現DFS算法。其過程簡要來說是對每一個可能的分支路徑深入到不能再深入爲止,而且每個節點只能訪問一次。

算法思想:

在這裏插入圖片描述
如上圖所示,給定初始頂點1,隨機選取其鄰接點2(如果採用鄰接矩陣存儲,會先選擇序號較小的),頂點2作爲新起點,隨機選取其鄰接點3,3再作爲新起點,隨機選取其鄰接點4,然後在選擇5。至此,沒有可供選擇的頂點,則向上回溯,直至回溯到1,發現其還有未被發現的鄰接點8,重複上述步驟,直至遍歷完整張圖。

算法步驟:
  1. 從圖中某個頂點開始出發,訪問此頂點
  2. 訪問起始頂點的未被訪問過的鄰接點,並選取其作爲新的起始頂點
  3. 重複2,直至其所能到達的鄰接點都被訪問過
  4. 開始回溯,尋找新的未被訪問過的鄰接點,直至全圖都被訪問過
實現步驟:
  1. 給定初始頂點,選擇此點未被訪問過的鄰接點
  2. 訪問此臨接點,並且將其設置爲已訪問(採用標記數組,設置是否訪問過)
  3. 重複2,直至所有頂點皆被訪問過
代碼示例:
鄰接矩陣:
#include<iostream>
#include<algorithm>
using namespace std;

#define MAX_SIZE 100
int graph[MAX_SIZE][MAX_SIZE];
bool visted[MAX_SIZE];

void dfs(int s, int n){//遞歸實現
 	cout << s << " ";
 	visted[s] = true;
 	for(int i = 1; i <= n; i++){
  		if((graph[s][i] != 0) && (!visted[i]))
   			dfs(i, n);
 	}
}

int main(){
 	int n, m, s;
 	cin >> n >> m >> s;
 	for(int i = 0; i < MAX_SIZE; i++){//矩陣初始化 
  		for(int j = 0; j < MAX_SIZE; j++)
   			graph[i][j] = 0;
 	}
 	for(int i = 0; i < m; i++){//更新頂點間關係 
  		int x = rand() % n;
  		int y = rand() % n;
  		while(x == 0 || y == 0){//爲了便於理解,二維矩陣下標0廢棄
   			x = rand() % n;
   			y = rand() % n; 
  		}
  		graph[x][y] = 1;
 	}
 	dfs(s, n); 
 	return 0;
}
鄰接表
#include<iostream>
#include<algorithm>
using namespace std;

#define MAX_SIZE 100
bool visted[MAX_SIZE];

typedef struct Enode{
 	int index;
 	Enode *next;
}*Edge;
struct Vnode{
 	int data;
 	Enode *next; 
};

void init_v_node(Vnode *apex, int n){
 	for(int i = 0; i <= n; i++){
  		apex[i].data = 0;
  		apex[i].next = NULL;
 	}
}
void create_list(Vnode *apex, int m, int n){
 	for(int i = 0; i < m; i++){//更新圖的連通情況 
  		int x = rand() % n, y = rand() % n;
  		while(x == 0 || y == 0){
   			x = rand() % n;
   			y = rand() % n;
  		}
  		apex[x].data = x;
  		Edge t = new Enode;
  		t->index = y;
  		t->next = apex[x].next;
  		apex[x].next = t;
 	}
}
void dfs(Vnode *apex, int s){
 	cout << s << " ";
 	visted[s] = true;
 	Edge p = apex[s].next;
 	while(p != NULL){
  		int t = p->index;
  		if(!visted[t])
   			dfs(apex, t);
  		p = p->next;
 	}
}

int main(){
 	int n, m;
 	cin >> n >> m;
 	Vnode apex[n+1];//順序表存儲頂點 
 	init_v_node(apex, n);
 	create_list(apex, m, n);
 	dfs(apex, 1);
 	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章