为啥使用堆栈的dfs没有给出正确的结果

Posted

技术标签:

【中文标题】为啥使用堆栈的dfs没有给出正确的结果【英文标题】:Why dfs using stack is not giving correct result为什么使用堆栈的dfs没有给出正确的结果 【发布时间】:2016-07-18 07:02:16 【问题描述】:

See DFS image Here

我正在使用堆栈打印 dfs 序列。根据输入和图形的图像,序列是 1 2 4 8 5 6 3 7 。但我的代码给出的输出为 1 2 4 8 7 6 5 3 。谁能解释我该如何解决?

输入: 8 10 1 3 1 2 2 5 2 4 3 7 3 6 4 8 5 8 6 8 7 8 正确的输出: 顺序:1 2 4 8 5 6 3 7

我的代码:

#include <bits/stdc++.h>
using namespace std;
vector<int>edges[100];
stack<int>q;
vector<int>item;
int level[100],parent[100],visited[100],tn;



void dfs(int s)

    int j,k,fr;
    q.push(s);
    level[s]=0;
    for(j=1;j<=tn;j++)
    
        visited[j]=0;
    
    visited[s]=1;
    while(!q.empty())
    
        fr=q.top();
        q.pop();
        item.push_back(fr);
        for(k=0;k<edges[fr].size();k++)
        
            if(visited[edges[fr][k]]==0)
            
                 q.push(edges[fr][k]);
                 //cout<<"Pushed="<<fr<<"="<<edges[fr][k];
                 visited[edges[fr][k]]=1;
            


        

        //cout<<endl;



    



int main()

    int i,e,p,n,u,v,f,m;
    cin>>tn>>e;
    for(i=1;i<=e;i++)
    
        cin>>u>>v;
        edges[u].push_back(v);
        edges[v].push_back(u);
    
    dfs(1);
    cout<<"Sequence="<<endl;
    for(m=0;m<item.size();m++)
    
        cout<<item[m];
    
    return 0;

我的代码显示以下输出:1 2 4 8 7 6 5 3

【问题讨论】:

【参考方案1】:

实现中节点被访问的标记包含一个错误;函数可以改写如下。

void dfs(int s)

    int j, k, fr;
    q.push(s);
    level[s] = 0;
    for (j = 1; j <= tn; j++)
    
        visited[j] = 0;
    
    while (!q.empty())
    
        fr = q.top();
        q.pop();
        if (0 == visited[fr])
        
            visited[fr] = 1;
            item.push_back(fr);
            for (k = 0; k < edges[fr].size(); k++)
            
                q.push(edges[fr][k]);
            
        
    

在这个版本中,只有从堆栈中取出节点才会被标记。请注意,检查节点是否已被访问是必要的,因为堆栈上的节点可能会被稍后的迭代访问。这个实现产生了序列

1 2 4 8 7 3 6 5

但是,这不是所描述的所需解决方案。但是,请注意,如果没有额外的平局规则,DFS 算法允许访问序列中存在一些歧义。顺序

1 2 4 8 5 6 3 7

可以通过将具有最小 id 的邻居最后推入堆栈来生成,使其在下一次迭代中被访问。

【讨论】:

非常感谢@Codor。现在它正在工作。对于节点 8,输入应采用以下格式:7 8 --> 6 8 --> 5 8 --> 4 8

以上是关于为啥使用堆栈的dfs没有给出正确的结果的主要内容,如果未能解决你的问题,请参考以下文章

当它的目标应该被删除时,为啥这个智能指针会给出正确的结果?

为啥 C# 'is' 运算符在比较两个布尔值时会给出正确的结果,我应该使用它吗?

为啥 Date.parse 给出不正确的结果?

使用 sysdate 时的 Oracle SQL,为啥它没有给出预期的结果

按对象属性排序,使用 .sort [重复] 给出混合结果

访问 mdb 没有给出正确的结果