1. 程式人生 > >演算法----圖的遍歷(深度優先搜尋DFS、廣度優先搜尋BFS)

演算法----圖的遍歷(深度優先搜尋DFS、廣度優先搜尋BFS)

圖的遍歷的定義:
從圖的某個頂點出發訪問圖中所有的點,且每個頂點僅被訪問一次。

深度優先搜尋DFS:

準備:指定的起始點和終點,確定好當前點與鄰接點之間的偏移值、結束搜尋的條件、符合訪問的點所需條件、回溯處理;

(1)若當前點的鄰接點有未被訪問的,則選一個進行訪問;

(2)若當前點的鄰接點都不符合訪問條件,退回到當前點的上一個點;

(3)直到訪問到目標終點,或是所有點均以訪問仍無法到達終點;

前段時間正好幫同學敲一個迷宮的講解,於是乎。。。

主要程式碼由C++編寫,已附備註

  1 #include <stack>
  2 #include <cstdio>
  3
#include <string> 4 #include <cstring> 5 #include <iostream> 6 7 using namespace std; 8 9 typedef struct { 10 int x, y, step; 11 }point; 12 13 void out(int a[100][100], int m, int n) //用於檢視迷宮地圖 14 { 15 int i, j; 16 for(i = 0; i < m; i++)
17 { 18 for(j = 0; j < n; j++) 19 cout << a[i][j] << " "; 20 cout << endl; 21 } 22 } 23 24 int main() 25 { 26 int t, z; 27 cout << "請輸入需要走幾個迷宮:" << endl; 28 while(cin >> t) 29 { 30 int
m, n; 31 for(z = 0; z < t; z++) 32 { 33 int i, j; 34 string str; //用於輸入 35 stack<point> s; //用於儲存已走的路徑 36 point start, end; //起始點和終止點 37 int map[100][100]; //迷宮地圖 38 int d1[4] = {-1, 0, 1, 0}; //走迷宮的過程中上下方向的偏移值 39 int d2[4] = {0, 1, 0, -1}; //走迷宮的過程中左右方向的偏移值 40 41 cout << "請輸入第" << z+1 << "個迷宮的行列:" << endl; 42 cin >> m >> n; 43 44 cout << "請輸入第" << z+1 << "個迷宮:" << endl; 45 for(i = 0; i < m; i++)//利用轉化的方式,將輸入變為資料地圖 46 { 47 cin >> str; 48 for(j = 0; j < n; j++) 49 { 50 if(str[j] == 'H') 51 map[i][j] = 1; 52 if(str[j] == 'O') 53 map[i][j] = 0; 54 } 55 } 56 // out(map, m, n); //檢視迷宮地圖 57 58 cout << "請輸入起點座標和終點座標:" << endl; 59 cin >> start.x >> start.y >> end.x >> end.y; 60 61 start.step = 1; 62 map[start.x][start.y] = -1; //將起始點在地圖上標記出來 63 s.push(start); 64 while(!s.empty()) 65 { 66 point p = s.top(); 67 68 if(p.x == end.x && p.y == end.y) //判斷是否到達終點 69 break; 70 71 for(i = 0; i < 4; i++) 72 { 73 int dx = p.x + d1[i]; //下一步的上下位置 74 int dy = p.y + d2[i]; //下一步的左右位置 75 76 if(dx>=0 && dx<m && dy>=0 && dy<n //判斷行走就是否符合地圖要求 77 && map[dx][dy] == 0) //判斷該點是否可走 78 { 79 map[dx][dy] = -1; //走過的點進行標記 80 point px; 81 px.x = dx, px.y = dy, px.step = p.step+1; 82 s.push(px); //將這個符合行走條件的點入棧 83 break; //保證每次只走一步 84 } 85 } 86 if(i == 4) //當i為4的時候,就是四周都不能走,回溯到上一點 87 s.pop(); 88 } 89 if(s.empty()) //因棧為空而停止迴圈,當然是無法走出迷宮,不通的 90 { 91 cout << "無法走出迷宮!" << endl; 92 continue; 93 } 94 // out(map, m, n); //檢視迷宮地圖行走情況,走過為-1,牆為1,未走的路為0 95 96 i = 0; 97 point *road = new point[m*n]; //用於輸出走出迷宮的路徑 98 while(!s.empty()) //讀取走過的點 99 { 100 point p = s.top(); 101 road[p.step] = p; 102 s.pop(); 103 i++; 104 } 105 cout << "走出迷宮共用了" << i << "步,經過的點為:"; 106 for(i = 1; i < j; i++) 107 cout << road[i].x << "," << road[i].y << "->"; 108 cout << road[i].x << "," << road[i].y << endl; 109 110 } 111 112 cout << "請輸入需要走幾個迷宮:" << endl; 113 } 114 return 0; 115 }

廣度優先搜尋BFS:

等待更新。。。