// 添加边 voidaddEdge(int u, int v){ if (u >= 0 && u < nodeNum_ && v >= 0 && v < nodeNum_) { graph_[u].push_back(v); graph_[v].push_back(u); } } private: size_t nodeNum_; std::vector<std::vector<int>> graph_; };
递归方式实现
随意选择一个起始顶点作为当前顶点,并将其标记为已访问。
递归地访问当前顶点的所有未访问过的邻接顶点。
当当前顶点的所有邻接顶点都被访问过后,回溯到上一个顶点。
重复步骤 2 和 3,直到所有可达的顶点都被访问。
1 2 3 4 5 6 7 8
voidrecursionDFS(int start,std::unordered_set<int>& visited){ visited.insert(start); // 表示已经访问过 for (int i : graph_[start]) { // 访问与 start 相邻的节点 if (visited.find(i) == visited.end()) { // 如果没有访问过,递归访问 recursionDFS(i, visited); } } }
栈方式实现
随意选择一个起始顶点,将其压入栈中,并标记为已访问。
当栈不为空时,弹出栈顶顶点。
将该顶点的所有未访问过的邻接顶点压入栈中,并标记为已访问。
重复步骤 2 和 3,直到栈为空。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
voidstackDFS(int start,std::unordered_set<int>& visited){ std::stack<int> s; s.push(start); visited.insert(start); while (!s.empty()) { int node = s.top(); s.pop(); for (int i : graph_[node]) { if (visited.find(i) == visited.end()) { s.push(i); visited.insert(i); } } } }
广度优先搜索
DFSEx.gif
步骤:
选择起始顶点:任选图中的一个顶点作为起始点,将其标记为已访问,并将其加入到一个队列中。
队列操作 –> 当队列不为空时,执行以下操作:
从队列的头部取出一个顶点。
访问该顶点的所有未被访问过的邻接顶点,将这些邻接顶点标记为已访问,并将它们依次加入到队列的尾部。
结束条件:重复上述队列操作,直到队列为空,此时图中所有可达顶点都已被访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
voidBFS(int start, std::unordered_set<int> &visited){ std::queue<int> q; q.push(start); visited.insert(start); while (!q.empty()) { int node = q.front(); q.pop(); for (int i : graph_[node]) { if (visited.find(i) == visited.end()) { q.push(i); visited.insert(i); } } } }