c++深度优先搜索(dfs)

深度优先搜索(DFS, Depth-First Search)是一种用于遍历或搜索树或图的算法。在搜索过程中,DFS会尽可能深地搜索图的分支。当节点v的所在边都已被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这个过程一直进行到已发现从源节点可达的所有节点为止。

深度优先搜索的基本思想

  • 从一个顶点v开始,访问此顶点,然后从此顶点未被访问的邻接点中选择一个顶点w,继续访问。
  • 重复上述过程,直到所有从v可达的顶点都被访问过。
  • 若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作为起点,重复上述过程,直到图中所有顶点都被访问过为止。

深度优先搜索的伪代码

DFS(v): 
标记 v 为已访问 
对于 v 的每个未被访问的邻接点 w 
DFS(w)

深度优先搜索的C++实现

以下是一个使用邻接表表示图并使用递归实现的DFS的C++示例代码:

#include <iostream>  
#include <vector>  
#include <list>  
  
using namespace std;  
  
// 图类  
class Graph {  
    int V; // 顶点数  
    list<int> *adj; // 邻接表  
  
public:  
    Graph(int V); // 构造函数  
    void addEdge(int v, int w); // 添加边  
    void DFSUtil(int v, vector<bool> &visited); // DFS辅助函数  
    void DFS(int v); // DFS的外部接口  
};  
  
Graph::Graph(int V) {  
    this->V = V;  
    adj = new list<int>[V];  
}  
  
void Graph::addEdge(int v, int w) {  
    adj[v].push_back(w); // 添加一条从v到w的边  
}  
  
void Graph::DFSUtil(int v, vector<bool> &visited) {  
    // 标记当前节点为已访问  
    visited[v] = true;  
    cout << v << " ";  
  
    // 递归访问所有未访问的邻接点  
    list<int>::iterator i;  
    for (i = adj[v].begin(); i != adj[v].end(); ++i)  
        if (!visited[*i])  
            DFSUtil(*i, visited);  
}  
  
void Graph::DFS(int v) {  
    // 标记所有顶点为未访问  
    vector<bool> visited(V, false);  
  
    // 调用辅助函数进行DFS遍历  
    DFSUtil(v, visited);  
}  
  
// 测试代码  
int main() {  
    // 创建一个图实例  
    Graph g(4);  
    g.addEdge(0, 1);  
    g.addEdge(0, 2);  
    g.addEdge(1, 2);  
    g.addEdge(2, 0);  
    g.addEdge(2, 3);  
    g.addEdge(3, 3);  
  
    cout << "从顶点 2 开始的深度优先遍历(DFS):" << endl;  
    g.DFS(2);  
  
    return 0;  
}

深度优先搜索的实例

假设我们有以下图:

    (0)  
   / | \  
  (1) (2)  
   \ | /  
    (3)

边为:(0,1), (0,2), (1,2), (2,0), (2,3), (3,3)。

如果我们从顶点2开始进行DFS,访问顺序可能是:2, 0, 1, 3(注意,访问顺序可能因实现方式而异,因为图是无向的,且可能存在环)。

深度优先搜索的想象(概念图)

你可以想象上述图在DFS过程中的遍历过程。从顶点2开始,首先访问2,然后访问2的一个未访问的邻接点(比如0),接着从0访问其未访问的邻接点(比如1),最后回到2访问其另一个未访问的邻接点(比如3)。注意,由于存在从2到0的边,DFS可能会再次访问0,但在这个例子中,我们假设访问过的节点不会被重复访问(除非有显式需要,比如寻找环)。

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值