DFS算法查找所有路径详解

DFS算法查找所有路径详解

算法介绍

深度优先搜索(Depth-First Search,DFS)是一种图遍历算法,它从起始节点开始,沿着一条路径尽可能深入,直到达到最深的节点,然后回溯到前一节点,继续探索下一条路径。DFS通常使用递归或栈(非递归)来实现。

以下是DFS算法的基本步骤:

  • 选择起始节点: 从图中选择一个起始节点作为当前节点;
  • 标记节点: 标记当前节点为已访问,以防止重复访问;
  • 探索邻居节点: 对于当前节点的未访问邻居节点,选择一个邻居节点作为新的当前节点,然后重复步骤2和步骤3;
  • 回溯: 如果当前节点没有未访问的邻居节点,回溯到上一节点,重复步骤3;
  • 重复过程: 重复步骤3和步骤4,直到所有节点都被访问。

递归实现的伪代码

cpp 复制代码
function DFS(node):
    if node is not visited:
        mark node as visited
        for each neighbor of node:
            DFS(neighbor)

非递归实现的伪代码

DFS的非递归实现通常使用栈来模拟递归调用的过程,具体步骤如下:

  • 创建一个空栈,并将起始节点压入栈中;
  • 进入循环,直到栈为空;
  • 弹出栈顶节点作为当前节点;
  • 如果当前节点未访问,标记为已访问;
  • 遍历当前节点的邻居节点,将未访问的邻居节点压入栈中;
  • 重复步骤3到步骤5,直到栈为空为止。

注意:在处理连通图时可能导致栈溢出,因此在实际应用中可能需要注意栈深度的问题。

伪代码如下:

cpp 复制代码
function DFS_non_recursive(start):
    stack = empty stack
    push start onto stack

    while stack is not empty:
        current = pop from stack
        if current is not visited:
            mark current as visited
            for each neighbor of current:
                push neighbor onto stack

具体算法实现

由于可能存在非常多的路径,我们设置一个maxLength,表示限制经过的节点个数。

cpp 复制代码
void Graph::DFS(int current, int end, std::unordered_set<int>& visited, std::vector<int>& path, int maxLength)
{
    static int currentLength = 0;
    static int i = 1;
    visited.insert(current);
    path.push_back(current);

    if (path.size() <= maxLength) 
    {
        if (current == end)
        {
            // 生成路径
            for (int node : path) 
            {
                std::cout<<node<<' ';
            }
            std::cout<<"路径总长度为:"<<currentLength<<std::endl;
        }
        else
        {
            for (int neighbor = 0; neighbor < V; ++neighbor)
            {
                if (adjMatrix[current][neighbor] != INF && visited.find(neighbor) == visited.end()) 
                {
                    int edgeWeight = adjMatrixLength[current][neighbor];
                    currentLength += edgeWeight;
                    DFS(neighbor, end, visited, path, maxLength);
                    currentLength -= edgeWeight; // 回溯时减去当前边的长度
                }
            }
        }
    }

    visited.erase(current);
    path.pop_back();
}
相关推荐
white-persist4 分钟前
【红队渗透】Cobalt Strike(CS)红队详细用法实战手册
java·网络·数据结构·python·算法·安全·web安全
舟舟亢亢11 分钟前
算法总结—【动态规划一维、二维、状态压缩】
算法·动态规划
重生之后端学习14 分钟前
152. 乘积最大子数组
数据结构·算法·leetcode·职场和发展·动态规划
weixin_6495556721 分钟前
C语言程序设计第四版(何钦铭、颜晖)第八章之字符串压缩
c语言·数据结构·算法
单车少年ing36 分钟前
一个编码BUG
算法·bug
努力中的编程者37 分钟前
哈希表(C语言底层实现)
c语言·数据结构·c++·算法·哈希算法·散列表
mjhcsp40 分钟前
C++ 迭代加深搜索(IDDFS):从原理到实战的深度解析
c++·深度优先·迭代加深
CoovallyAIHub1 小时前
ICLR 2026 | MRAD:不拟合直接查表,零样本工业缺陷检测新范式,16 数据集均值最优
深度学习·算法·计算机视觉
摆烂小白敲代码1 小时前
【数据结构与算法】汉诺塔问题(C++)
c语言·开发语言·数据结构·c++·算法·hanoi·汉诺塔问题
Trouvaille ~1 小时前
【递归、搜索与回溯】专题(八):记忆化搜索——从暴力递归到动态规划的桥梁
c++·算法·leetcode·青少年编程·面试·蓝桥杯·动态规划