二叉树中的 BFS

发布于 2024-11-07 11:53:00 字数 569 浏览 9 评论 0原文

我正在尝试编写二叉树中广度优先搜索的代码。我已将所有数据存储在队列中,但我不知道如何访问所有节点并消耗它们的所有子节点。

这是我的 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);
   }
}

我已经将根数据排入队列,但它仍然不起作用。 有人能指出我的错误吗?

I'm trying to write the codes for breadth-first search in binary tree. I've stored all the data in a queue, but I can't figure out how to travel to all nodes and consume all their children.

Here's my code in 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);
   }
}

I've already enqueued the root data, but it's still not working.
Can anyone point out my mistake?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

樱花细雨 2024-11-14 11:53:00

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++ 双端队列,但是任何可以让您将项目放在后面并从前面获取它们的东西都可以正常工作。

A BFS can be easily written without recursion. Just use a queue to order your expansions:

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);
    }
}

The key is that you don't need to traverse the tree recursively; you just let your data structure handle the order in which you visit nodes.

Note that I'm using the C++ deque here, but anything that lets you put items on the back and get them from the front will work fine.

我喜欢麦丽素 2024-11-14 11:53:00
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 模式。如果必须进行递归,则需要检查队列是否为空作为基本条件。还要检查一下你是如何通过队列的,我认为这可能是不正确的。我会建议一个迭代解决方案。

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;
}

First the head node is inserted into the queue. The loop will iterate while the queue is not empty. Starting from the head node, in each iteration one node is removed and the non-null childs are inserted in the queue. In each iteration one node gets out and its non-null childs gets pushed. In the next iteration the next oldest discovered vertex, which is now at the front of the queue , is taken out (in the order they were discovered) and then they are processed to check their child.

                                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}

Above the iteration stops when we get that there is no more discovered vertex which are waiting to be selected, in the queue, so all the vertices which were discovered in the binary tree (graph connected component) is selected.

I your code first you pass enqueue the nodes in queue and then traverse these childs again recursively, which creates a DFS pattern. If you have to do recursion, you need to check for if the queue is empty as the base condition. Also have a check how you are passing the queue, i think it may be incorrect. I would suggest an iterative solution.

能怎样 2024-11-14 11:53:00

您在这里并不是进行广度优先遍历。相反,您将左右元素放入队列中并移动到左子树。您首先耗尽左子树,然后移动到右子树。

编写一个过程来将节点排入队列。

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
}

You are not doing a breadth first traversal here. Instead you are enqueuing the left and right element inside the queue and moving to the left subtree. You are exhausting the left subtree first and then moving on to the right subtree.

Write a procedure to enqueue the node instead.

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
}
江湖彼岸 2024-11-14 11:53:00

这是一个BFS的静态代码,用于明确BFS的概念。
在此代码中,我使用了 2 个数组,一个在节点数组中,另一个是边缘数组。通过递归,我打印了有向图的每个节点的所有邻居。

 Graph is:  A-->D-->E
            |\  |   | 
            v \ v   v     
            B-->C <-|
           
 There is a Edge from A to C    

这是代码:

enter code here
 #include<stdio.h>
 int NodeArr[5][3]={{'A',1,0},
               {'B',2,3},
               {'C',3,-1},
               {'D',4,4},
               {'E',-1,6}};

  int edgeArr[7][2]={
                 //For A Node
                {'B',1},
                {'C',2},
                {'D',-1},
                 //For B Node
                {'C',-1},
                  //As C Node has no directed neighbour 
                 //For D Node
                {'C',5},
                {'E',-1},
                 //For E Node
                {'C',-1},};

  void printcharacter(int edge_index){
    printf("%c ",edgeArr[edge_index][0]);
     if(edgeArr[edge_index][1]==-1)
        return;

    printcharacter(edgeArr[edge_index][1]);

  }

int main(){

 printf("Neighbour of All Nodes for Directed Graph");
for(int i=0;i<5;i++){
   if(NodeArr[i][2]!=-1){
    int edge_index=NodeArr[i][2];
    printf("Neighbour of %c are ",NodeArr[i][0]);
    printcharacter(edge_index);
    printf("\n");
       }
 
     }
 }

This is a Static code for BFS to clear the concept of BFS.
In this code I have used 2 array one in node array and another one is edge array. And by recursion I have printed all the Neighbour of each Node for a directed graph.

 Graph is:  A-->D-->E
            |\  |   | 
            v \ v   v     
            B-->C <-|
           
 There is a Edge from A to C    

This is the code:

enter code here
 #include<stdio.h>
 int NodeArr[5][3]={{'A',1,0},
               {'B',2,3},
               {'C',3,-1},
               {'D',4,4},
               {'E',-1,6}};

  int edgeArr[7][2]={
                 //For A Node
                {'B',1},
                {'C',2},
                {'D',-1},
                 //For B Node
                {'C',-1},
                  //As C Node has no directed neighbour 
                 //For D Node
                {'C',5},
                {'E',-1},
                 //For E Node
                {'C',-1},};

  void printcharacter(int edge_index){
    printf("%c ",edgeArr[edge_index][0]);
     if(edgeArr[edge_index][1]==-1)
        return;

    printcharacter(edgeArr[edge_index][1]);

  }

int main(){

 printf("Neighbour of All Nodes for Directed Graph");
for(int i=0;i<5;i++){
   if(NodeArr[i][2]!=-1){
    int edge_index=NodeArr[i][2];
    printf("Neighbour of %c are ",NodeArr[i][0]);
    printcharacter(edge_index);
    printf("\n");
       }
 
     }
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文