Java 或 C 中的递归广度优先旅行函数?

发布于 2024-09-03 17:56:07 字数 1107 浏览 7 评论 0原文

这是广度优先旅行的java代码:

void breadthFirstNonRecursive(){
    Queue<Node> queue = new java.util.LinkedList<Node>();
    queue.offer(root);
    while(!queue.isEmpty()){
        Node node = queue.poll();
        visit(node);
        if (node.left != null)
            queue.offer(node.left);
        if (node.right != null)
            queue.offer(node.right);
    }
}

Is it possible to write a recursive function to do the same?

起初,我认为这很容易,所以我想出了这个:

void breadthFirstRecursive(){
    Queue<Node> q = new LinkedList<Node>();
    breadthFirst(root, q);
}

void breadthFirst(Node node, Queue<Node> q){
    if (node == null) return;
    q.offer(node);
    Node n = q.poll();
    visit(n);
    if (n.left != null)
        breadthFirst(n.left, q);
    if (n.right != null)
        breadthFirst(n.right, q);   
}

然后我发现它不起作用。它实际上做了同样的事情:

void preOrder(Node node) {
    if (node == null) return;
    visit(node);
    preOrder(node.left);
    preOrder(node.right);
}

以前有人考虑过这个吗?

Here is a java code for breadth-first travel:

void breadthFirstNonRecursive(){
    Queue<Node> queue = new java.util.LinkedList<Node>();
    queue.offer(root);
    while(!queue.isEmpty()){
        Node node = queue.poll();
        visit(node);
        if (node.left != null)
            queue.offer(node.left);
        if (node.right != null)
            queue.offer(node.right);
    }
}

Is it possible to write a recursive function to do the same?

At first, I thought this would be easy, so I came out with this:

void breadthFirstRecursive(){
    Queue<Node> q = new LinkedList<Node>();
    breadthFirst(root, q);
}

void breadthFirst(Node node, Queue<Node> q){
    if (node == null) return;
    q.offer(node);
    Node n = q.poll();
    visit(n);
    if (n.left != null)
        breadthFirst(n.left, q);
    if (n.right != null)
        breadthFirst(n.right, q);   
}

Then I found it doesn't work. It is actually does the same thing as this:

void preOrder(Node node) {
    if (node == null) return;
    visit(node);
    preOrder(node.left);
    preOrder(node.right);
}

Has any one thought about this before?

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

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

发布评论

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

评论(6

小ぇ时光︴ 2024-09-10 17:56:07

我无法想象当你有一个完美的迭代解决方案时你为什么想要这样做,但你就可以了;)

void breadth_first(Node root):
  Queue q;
  q.push(root);
  breadth_first_recursive(q)

void breadth_first_recursive(Queue q):
  if q.empty() return;

  Node n = q.pop()
  print "Node: ", n
  if (n.left) q.push(n.left)
  if (n.right) q.push(n.right)
  breadth_first_recursive(q)

我应该补充一点,如果你真的想递归地遍历树的节点,那么您可以使用 level 参数执行 DFS,并仅在 level 输出节点,然后向上递归。但这只是疯狂的言论,因为你会多次重新访问节点......只要接受 BFS 是一种迭代算法即可。 :)

I can't imagine why you'd want to, when you have a perfectly good iterative solution, but here you go ;)

void breadth_first(Node root):
  Queue q;
  q.push(root);
  breadth_first_recursive(q)

void breadth_first_recursive(Queue q):
  if q.empty() return;

  Node n = q.pop()
  print "Node: ", n
  if (n.left) q.push(n.left)
  if (n.right) q.push(n.right)
  breadth_first_recursive(q)

I should add that if you really want to traverse the nodes of the tree recursively, then you could do a DFS with a level parameter, and output nodes only at level, then recurse up. But that's just crazy talk, because you'd revisit nodes wayyyyy too many times... Just accept that BFS is an iterative algorithm. :)

若有似无的小暗淡 2024-09-10 17:56:07

BFS 算法不是递归算法(与 DFS 相对)。

人们可以尝试编写一个递归函数来模拟该算法,但这最终会变得相当奇怪。这样做有什么意义呢?

The BFS algorithm is not a recursive algorithm (as opposed to DFS).

One could try writing a recursive function that emulates the algorithm but that would end up quite bizzare. What would be the point in doing this ?

や三分注定 2024-09-10 17:56:07

您可以使用迭代加深深度优先搜索,它实际上是一种广度优先算法使用递归。如果分支因子较高,它甚至比 BFS 更好,因为它不使用太多内存。

You can use iterative deepening depth-first search, which effectively is a breadth-first algorithm that uses recursion. It's even better than BFS if you have a high branching factor, as it doesn't use much memory.

2024-09-10 17:56:07

简单的 BFS 和 DFS 递归:
只需将树的根节点推送/提供到堆栈/队列中并调用这些函数即可!

public void breadthFirstSearch(Queue queue) {
if (queue.isEmpty()) 
  return;

Node node = (Node) queue.poll();

System.out.println(node + " ");

if (node.right != null) 
  queue.offer(node.right);

if (node.left != null) 
  queue.offer(node.left);

breadthFirstSearch(queue);

}

public void depthFirstSearch(Stack stack) {
if (stack.isEmpty()) 
  return;

Node node = (Node) stack.pop();

System.out.println(node + " ");

if (node.right != null) 
  stack.push(node.right);

if (node.left != null) 
  stack.push(node.left);

depthFirstSearch(stack);

}

A Simple BFS and DFS recursion:
Just push/offer the root node of tree in stack/queue and call these functions!

public void breadthFirstSearch(Queue queue) {
if (queue.isEmpty()) 
  return;

Node node = (Node) queue.poll();

System.out.println(node + " ");

if (node.right != null) 
  queue.offer(node.right);

if (node.left != null) 
  queue.offer(node.left);

breadthFirstSearch(queue);

}

public void depthFirstSearch(Stack stack) {
if (stack.isEmpty()) 
  return;

Node node = (Node) stack.pop();

System.out.println(node + " ");

if (node.right != null) 
  stack.push(node.right);

if (node.left != null) 
  stack.push(node.left);

depthFirstSearch(stack);

}

べ映画 2024-09-10 17:56:07

这是一个使用 arraylist 而不是队列的示例,我已经预定义了邻接矩阵和访问的数组。还创建了边缘


    public void BFS(int node, boolean[]visited)
        {
         List<Integer> li=new ArrayList<>();
         for(int j:adj[node])
         {
           if(!visited[j])
             {
                 System.out.println(j+" ");
                 visited[j]=true;
                 li.add(j);
             }
         }
             for(int j:li){
                 BFS(j,visited);
             }
        }

Here is an example using arraylist instead of queues, I have predefined the adjacency matrix and the visited array. Also created the edges


    public void BFS(int node, boolean[]visited)
        {
         List<Integer> li=new ArrayList<>();
         for(int j:adj[node])
         {
           if(!visited[j])
             {
                 System.out.println(j+" ");
                 visited[j]=true;
                 li.add(j);
             }
         }
             for(int j:li){
                 BFS(j,visited);
             }
        }

腻橙味 2024-09-10 17:56:07

这不会让每个人都满意——我确信。谨向大家致以崇高敬意。对于那些问这有什么意义的人?关键是我们相信每个迭代算法都有一个(简单?)递归解决方案。
这是 stackoverflow 中“sisis”的解决方案。

BFS(Q)

{

  if (|Q| > 0) 

     v < - Dequeue(Q)

     Traverse(v)
     foreach w in children(v)
        Enqueue(Q, w)    

     BFS(Q)
}

它有一定的有趣之处,但不清楚它是否违反了任何递归规则。如果它不违反任何递归规则,那么它应该被接受。恕我直言。

This is not going to be satisfying to everyone -- I am sure. With all respect to everyone. To the people who ask what is the point? The point is that we believe that every iterative algorithm has also a (easy?) recursive solution.
Here is a solution by "sisis" from stackoverflow.

BFS(Q)

{

  if (|Q| > 0) 

     v < - Dequeue(Q)

     Traverse(v)
     foreach w in children(v)
        Enqueue(Q, w)    

     BFS(Q)
}

It has certain amount of funninest in it, but it not clear that it violates any recursive rules. If it does not violate any recursive rules, then it should be accepted. IMHO.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文