You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带权无向图中如何使用BFS和DFS实现遍历至指定节点后终止?

实现方案与修正代码

原有代码核心问题

  • 邻接表遍历逻辑错误:原有BFS、DFS函数中直接将邻接表数组下标作为节点编号使用,导致遍历逻辑完全不符合预期
  • 缺少目标节点终止逻辑:没有设计目标节点入参,也没有添加到达目标节点后终止遍历的判断

修正后代码

#include "iostream"
#include "vector"
#include "queue"
#include "stack"
#include "algorithm"

using namespace std;

typedef pair<int , int> Pair;

struct Edge{
    int src, dest, weight;
};

class Graph{
public:
    vector<vector<Pair>> adjacencyList;
    Graph(vector<Edge> const &edges, int N)
    {
       adjacencyList.resize(N);
       for(auto &edge: edges)
       {
           int src = edge.src;
           int dest = edge.dest;
           int weight = edge.weight;
           adjacencyList[src].push_back(make_pair(dest,weight));
           adjacencyList[dest].push_back(make_pair(src,weight));
       }
    }
};

// 新增target参数作为终止节点
void BFS(Graph const &graph, int src, int target, vector<bool> &discovered)
{
    queue<int> q;
    discovered[src] = true;
    q.push(src);
    while(!q.empty())
    {
        src = q.front();
        q.pop();
        cout<<src<<" ";
        // 到达目标节点直接终止遍历
        if(src == target) {
            return;
        }
        for(int i = 0; i < graph.adjacencyList[src].size() ;i++)
        {
            // 正确获取邻接节点编号
            int adj_node = graph.adjacencyList[src][i].first;
            if(!discovered[adj_node])
            {
                discovered[adj_node] = true;
                q.push(adj_node);
            }
        }
    }
}

// 新增target参数作为终止节点
void DFS(Graph const &graph, int src, int target, vector<bool> &discovered)
{
    stack<int> stack;
    stack.push(src);
    while(!stack.empty()){
        src = stack.top();
        stack.pop();
        if(discovered[src])
        {
            continue;
        }
        discovered[src] = true;
        cout<<src<< " ";
        // 到达目标节点直接终止遍历
        if(src == target) {
            return;
        }
        // 倒序遍历保证遍历顺序和递归DFS一致,不需要可改为正向遍历
        for(auto it = graph.adjacencyList[src].rbegin(); it != graph.adjacencyList[src].rend(); ++it)
        {
            int adj_node = it->first;
            if(!discovered[adj_node])
            {
                stack.push(adj_node);
            }
        }
    }
}

void printGraph(Graph const &graph, int N)
{
    for (int i = 0; i < N; ++i) {
        for(Pair v: graph.adjacencyList[i])
        {
            cout<<"("<<i<<" , "<<v.first<<" , "<<v.second<<") ";
        }
        cout<<endl;
    }
}

int main()
{
    vector<Edge> edges =
            {
                    // `(x, y, w)` —> edge from `x` to `y` having weight `w`
                    {0,1,0}, {0,2,0}, {0,3,0},
                    {1, 2,0}, {2,4,0}, {3,3,0}, {4,4,0}
            };
    int N = 5;
    Graph graph(edges,N);
    int start, target;
    cout << "请输入源节点编号(有效范围0~4):";
    cin >> start;
    cout << "请输入目标节点编号(有效范围0~4):";
    cin >> target;
    if(start <0 || start >=N || target <0 || target >=N) {
        cout << "输入节点编号非法" << endl;
        return 0;
    }
    vector<bool> discovered(N, false);
    cout << "BFS遍历结果(到目标节点为止):";
    BFS(graph, start, target, discovered);
    cout<<endl;
    vector<bool> discovered2(N, false);
    cout << "DFS遍历结果(到目标节点为止):";
    DFS(graph, start, target, discovered2);
    cout<<endl;
    cout << "图的邻接表结构:" << endl;
    printGraph(graph, N);
    return 0;
}

效果说明

输入源节点为0、目标节点为4时,输出示例如下:

请输入源节点编号(有效范围0~4):0
请输入目标节点编号(有效范围0~4):4
BFS遍历结果(到目标节点为止):0 1 2 3 4 
DFS遍历结果(到目标节点为止):0 3 2 4 
图的邻接表结构:
(0 , 1 , 0) (0 , 2 , 0) (0 , 3 , 0) 
(1 , 0 , 0) (1 , 2 , 0) 
(2 , 0 , 0) (2 , 1 , 0) (2 , 4 , 0) 
(3 , 0 , 0) (3 , 3 , 0) (3 , 3 , 0) 
(4 , 2 , 0) (4 , 4 , 0) (4 , 4 , 0) 

内容的提问来源于stack exchange,提问作者Danyal Sufyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 05:06:08