BFS在二叉树中

时间:2011-05-17 02:35:37

标签: c breadth-first-search

我正在尝试在二叉树中编写广度优先搜索的代码。我已将所有数据存储在队列中,但我无法弄清楚如何前往所有节点并消耗所有孩子。

这是我在C代码中的代码:

void breadthFirstSearch (btree *bt, queue **q) {
   if (bt != NULL) {

      //store the data to queue if there is

      if (bt->left != NULL) enqueue (q, bt->left->data);
      if (bt->right != NULL) enqueue (q, bt->right->data);

      //recursive

      if (bt->left != NULL) breadthFirstSearch (bt->left, q);
      if (bt->right != NULL) breadthFirstSearch (bt->right, q);
   }
}

我已经将根数据排入队列,但它仍无效。 谁能指出我的错误?

3 个答案:

答案 0 :(得分:11)

可以轻松编写BFS而无需递归。只需使用队列来订购您的扩展:

void BFS(btree *start)
{
    std::deque<btree *> q;
    q.push_back(start);
    while (q.size() != 0)
    {
        btree *next = q.front();
        // you may want to print the current node here or do other processing
        q.pop_front();
        if (next->left)
            q.push_back(next->left);
        if (next->right)
            q.push_back(next->right);
    }
}

关键是你不需要递归遍历树;您只需让您的数据结构处理访问节点的顺序。

请注意,我在这里使用的是C ++ deque,但是任何让你把物品放在背面并从前面拿到它们的东西都能正常工作。

答案 1 :(得分:9)

void bfs_bintree (btree_t *head)
{
  queue_t *q;
  btree_t *temp;

  q = queue_allocate ();
  queue_insert (q, head);

  while (!queue_is_empty (q))
  {
    temp = queue_remove (q);

    if (temp->left)
      queue_insert (temp->left);

    if (temp->right)
      queue_insert (temp->right);
  }
  queue_free (q);
  return;
}

首先将head节点插入队列。当队列不为空时,循环将迭代。从头节点开始,在每次迭代中移除一个节点,并将非空子节点插入队列中。在每次迭代中,一个节点退出并且其非空子节点被推送。在下一次迭代中,下一个最早发现的顶点(现在位于队列的前面)被取出(按它们被发现的顺序),然​​后处理它们以检查它们的孩子。

                                A
                               / \
                              /   \
                             B     C
                            / \     \
                           /   \     \
                          D     E     F
                         / \         / \
                        /   \       /   \
                       G     H     I     J


iteration  Vertex Selection Discovery Queue State
 initial                    :  A
    1            A          :  B C     {A is removed and its children inserted}
    2            B          :  C D E   {B is removed and its only child inserted}
    3            C          :  D E F   {C is removed and its children inserted}
    4            D          :  E F G H {D is removed and its children inserted}
    5            E          :  F G H   {E is removed and has not children}
    6            F          :  G H I J {F is removed and its children inserted}
    7            G          :  H I J   {G is removed has no children}
    8            H          :  I J     {H is removed has no children}
    9            I          :  J       {I is removed has no children}
    10           J          :  (empty) {J is removed has no children}

在我们得到的情况下停止迭代时,在队列中没有更多被发现的顶点等待被选中,因此选择了在二叉树中发现的所有顶点(图连通分量)。

我的代码首先通过队列中的节点排队,然后再递归遍历这些子节点,这将创建一个DFS模式。如果必须进行递归,则需要检查队列是否为空,作为基本条件。还要检查你如何通过队列,我认为这可能是不正确的。我建议一个迭代的解决方案。

答案 2 :(得分:5)

你这里没有进行广泛的首次遍历。相反,您将队列中的左右元素排入队列并移动到左子树。您先耗尽左子树,然后再转到右子树。

编写一个程序来代替排队节点。

void breadthFirstSearch (btree *bt, queue **q) {
 btree *tmpNode;
 enqueue(q,bt); //Assuming your root node has data

 while (!isempty(q)) //Assume isempty returns false when queue is not empty
 {
  tmpNode = dequeue(q);
  //Do whatever you want to do with tmpNode->data
  enqueue(tmpNode->left);
  enqueue(tmpNode->right);
  /* If this is a acyclic graph(tree) then this procedure should do, else you have to mark the nodes you have visited in-order not to end in a cycle */
 }

}

int main()
{
breadthFirstSearch(bt,q)
return 0
}