DFS 深度優先搜尋
阿新 • • 發佈:2020-09-03
#include "DFS.h" #include <list> #include <stack> using namespace std; DFS::DFS(int vertexCount) { this->v = vertexCount; this->adj = new list<int>[v]; } list<int> DFS::searchByStack(int s, int t){ //最短路徑結果集 list<int> resultList; //鄰接表訪問標識,為true標識此index的鄰接表已經遍歷過了,不需要重複訪問 bool started[v]; //每個頂點到起點可能連線,的前一個頂點(不一定是最短的連線) int prev[v]; stack<int> startVertexStack; //初始化全域性變數 for (int i = 0; i < this->v; ++i) { started[i] = false; prev[i] = -1; } startVertexStack.push(s); while(!startVertexStack.empty()){ //這裡先top不pop,是因為還需要進行回溯,如果這個節點的所有相關節點都已經start過了,那麼就可以進行pop了 int adjStartIndex = startVertexStack.top(); started[adjStartIndex] = true; list<int>::iterator it; bool needToPop = true; for(it = adj[adjStartIndex].begin(); it != adj[adjStartIndex].end(); it++){ if (!started[*it]){ needToPop = false; startVertexStack.push(*it); prev[*it] = adjStartIndex; if (*it == t){ int index = t; resultList.push_front(t); while (prev[index] != -1){ resultList.push_front(prev[index]); index = prev[index]; } return resultList; } //只要push了一個就立即跳出for迴圈,因為這裡要進行深度搜索,不需要現在就沿著鄰接表去遍歷所有 break; } } if(needToPop){ //這裡pop的,其實就是adjStartIndex,因為,只有一次push都沒的情況下才會進這裡 startVertexStack.pop(); } } return resultList; } list<int> DFS::search(int s, int t) { //最短路徑結果集 list<int> resultList; //鄰接表訪問標識,為true標識此index的鄰接表已經遍歷過了,不需要重複訪問 bool started[v]; //每個頂點到起點可能連線,的前一個頂點(不一定是最短的連線) int prev[v]; //初始化全域性變數 for (int i = 0; i < this->v; ++i) { started[i] = false; prev[i] = -1; } cursiveSearch(s, t, &resultList, started, prev); return resultList; } void DFS::cursiveSearch(int start, int end, list<int> *resultList, bool *started, int *prev){ started[start] = true; list<int> thisRoundAdjList = this->adj[start]; list<int>::iterator it; for(it = thisRoundAdjList.begin(); it != thisRoundAdjList.end(); ++it){ if(!resultList->empty()){ return; } if (!started[*it]){ if (*it == end){ //此點是目的地 prev[end] = start; int index = end; resultList->push_front(end); while (prev[index] != -1){ resultList->push_front(prev[index]); index = prev[index]; } return; } else { //此點不是目的地,以此點為出發點繼續尋找 prev[*it] = start; cursiveSearch(*it, end, resultList, started, prev); } } } }