【问题标题】:Queue for Binary Tree BFS二叉树 BFS 队列
【发布时间】:2012-03-24 18:40:34
【问题描述】:

我只是在尝试一些代码,而不是经验丰富的程序员。我实现了(至少认为)水平顺序遍历,它很容易完成。想知道它是否正确。

#include<iostream>
#include<queue>
using namespace std;

class node {
public :
  node *right;
  node *left;
  int info;
}*root;

queue<int> inf;

void bfs(node *t)
{
if(t!=NULL)
{
    if(t->right!=NULL)
        inf.push(t->right->info);

    if(t->left!=NULL)
        inf.push(t->left->info);

    bfs(t->right);
    bfs(t->left);
}
}

int main()
{
node *temp = new node();
temp->info = 1;

root = temp;

root->right = new node();
root->right->info = 2;
root->right->right = root->right->left = NULL;

root->left = new node();
root->left->info = 3;
root->left->right = root->left->left = NULL;

node *tmp = root;
root=root->right;

root->right = new node();
root->right->info = 4;
root->right->right = root->right->left = NULL;

root->left = new node();
root->left->info = 5;
root->left->right = root->left->left = NULL;

root = tmp;
root = root->left;

root->right = new node();
root->right->info = 6;
root->right->right = root->right->left = NULL;

root->left = new node();
root->left->info = 7;
root->left->right = root->left->left = NULL;

root = temp;


node *it;
it = root;

inf.push(root->info);


bfs(root);
for(;inf.size()!=0;)
{
    cout<<inf.front()<<" : ";
    inf.pop();
}

return 0;

}

【问题讨论】:

    标签: c++ binary-tree tree-traversal


    【解决方案1】:

    这使用std::queue&lt;int&gt; 以DFS 顺序打印节点!仅在某处使用队列不会使遍历顺序 BFS。你想要的是一个 std:: queue&lt;node*&gt; 放置根节点的地方。然后在队列不为空时进行迭代,并在每次迭代中将下一个节点从队列中取出并将其子节点放入队列中:

    for (std::queue<node*> inf(1, root); !inf.empty(); inf.pop()) {
        n = inf.front();
        process(n->info);
        if (n->left) inf.push(n->left);
        if (n->right) inf.push(n->right);
    }
    

    只是一些注意事项:

    1. 不要在容器上使用size() 来确定是否有元素:它可能例如遍历元素以计算它们(尽管标准容器都没有),empty() 表示您真正想知道的内容(尽管它应该被称为 is_empty())。
    2. 不要使用全局变量。
    3. 您的程序似乎泄漏了所有 node 对象。
    4. 您应该为您的node 类提供一个构造函数来初始化子级和info 的指针。

    【讨论】:

      【解决方案2】:

      是的,你做得很好,但是 您正在实施 DFS 算法。因为“it goes deeper until it reaches to a leaf and then back tracks.

      而且将 for 改成一段时间会更简洁:

      while(inf.size())
      {
          cout<<inf.front()<<" : ";
          inf.pop();
      }
      

      【讨论】:

        【解决方案3】:

        您正在填充队列,但您没有在遍历树时使用它。您稍后将使用它按照您访问它们的顺序打印节点,但这个顺序是 DFS 而不是 BFS。在这种简单的情况下,您也可以立即打印节点,目前不需要队列。

        这是 C++ 中的实际 DFS 算法,类似于伪代码:

        queue q;
        q.push_back( tree.root() );
        
        while( !q.empty() ) {
          node n = q.pop_front();
          // Visit n here (i.e. print it in your case)
          for all( c in n.children() ) {
            q.push_back( c );
          }
        }
        

        如您所见,BFS 根本没有递归调用。

        如果您使用递归,这通常意味着使用简单的可用堆栈数据结构。但是对于 BFS,您想使用实际的队列。您的实现大致相当于以下算法(我只是用实际显式堆栈替换了递归):

        stack s;
        s.push( tree.root() );
        
        while( !s.empty() ) {
           node n = s.pop();
          // Visit n here (i.e. print it in your case)
          for all( c in n.children() ) {
            s.push( c );
          }
        }
        

        非常相似,不过是通过堆栈来改变顺序。

        【讨论】:

        • 我明白你的意思,我试图根据级别打印树中的值,即从级别 0[root] 到级别 n[leaves]。但是,是的,我明白你所说的!谢谢。
        • @AadiDroid:是的,这就是 BFS 将走你的树的方式。一个接一个的关卡。但是,您使用的是 DFS,这首先要深入。您使用的队列将稍后打印节点,而不是按不同的顺序。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-16
        • 2021-09-19
        • 2022-08-19
        相关资源
        最近更新 更多