【问题标题】:Level Order traversal of a generic tree(n-ary tree) in javajava中通用树(n-ary树)的级别顺序遍历
【发布时间】:2012-10-08 20:01:20
【问题描述】:

(如果您想避免冗长的解释,我所寻找的只是java中通用树(n-ary tree)的级别顺序遍历。提供的代码有效并且需要级别顺序显示功能。环顾了一个小时,但找不到对通用 n 元树的引用。如果 soemone 可以帮助我在我的代码之上构建 LevelOrderDisplay 函数将不胜感激,因为它将帮助我理解我得到的队列错误。谢谢!)

我一直在尝试实现 Autosys 工作计划的树形表示。由于每个作业(流程)都可以有一个或多个相关作业,因此我决定使用 n-ary tree 实现,以便我可以映射流程。我正在使用 java 集合。我需要执行级别顺序遍历以显示作业依赖关系。 首先打印根,然后是第一层的所有节点,然后是第二层的所有节点,依此类推。

我试图在 StackOverflow 上搜索一个多小时,但我遇到的大多数示例都是针对二叉树的。我明白我需要为此使用队列。

根据我在研究过程中得到的信息,算法应该如下所示: 如果这是错误的,请纠正我,如果可能,请提供代码。 也欢迎替代方法,但我真正要寻找的是通用树的简单基本级顺序遍历。

让我们让它成为通用树实现的资源丰富的线程。大多数代码已经在工作了。请帮忙。

Algo:

对于每个节点,首先访问该节点,然后将其子节点放入 FIFO 队列中。

printLevelorder(tree)
1) Create an empty queue q
2) temp_node = root /*start from root*/
3) Loop while temp_node is not NULL
    a) print temp_node->data.
    b) Enqueue temp_node’s children (first left then right children) to q
    c) Dequeue a node from q and assign it’s value to temp_node

由于某种奇怪的原因,我无法在我的 Eclipse IDE 中声明队列。 我已经导入了 java.util.*; 我在这里遗漏了一些东西,请查看以下错误。

第一次尝试:

Queue<NaryTreeNode> BFSqueue = new LinkedList<NaryTreeNode>();

错误:LinkedList 类型不是通用的;它不能用参数进行参数化

第二次尝试:

QueueList<NaryTreeNode> BFSqueue = new QueueList<NaryTreeNode>();

错误:- QueueList 无法解析为类型

当前树结构供参考:

     root(100)
    /      |       \
  90       50       70
  /        \
20 30   200  300

当前显示函数的输出是前序的: 100 90 20 30 50 200 300 70 我需要一个水平顺序遍历。 所需的输出。

> 100
> 90 50 70
> 20 30 200 300

如果有人想在他们的机器上运行它并添加级别顺序遍历功能,这是一个工作代码。请为队列操作提供注释解释,因为这是我卡住的地方。

谢谢!

import java.util.*;
import java.io.*;
import java.util.List;

//The node for the n-ary tree
public class NaryTreeNode {
  int data;
  List <NaryTreeNode> nary_list = new ArrayList<NaryTreeNode>();
}


public class NaryTree {

  void display(NaryTreeNode t) {
    if(t==null)
      return;

    System.out.print(t.data + " ");

    for(NaryTreeNode n : t.nary_list) 
          display(n) ;            //Recursive Call
 }


  public static void main(String args[]){

    NaryTree t1 = new NaryTree();

    NaryTreeNode root = new NaryTreeNode();

    root.data = 100;

    NaryTreeNode lev_11 = new NaryTreeNode();   lev_11.data=90;
    NaryTreeNode lev_12 = new NaryTreeNode();   lev_12.data=50;
    NaryTreeNode lev_13 = new NaryTreeNode();   lev_13.data=70;
    NaryTreeNode lev_21 = new NaryTreeNode();   lev_21.data=20;
    NaryTreeNode lev_22 = new NaryTreeNode();   lev_22.data=30;
    NaryTreeNode lev_23 = new NaryTreeNode();   lev_23.data=200;
    NaryTreeNode lev_24 = new NaryTreeNode();   lev_24.data=300;

    //Add all the nodes to a list.

    List<NaryTreeNode> temp2 = new ArrayList<NaryTreeNode>();  //Level two first branch
    temp2.add(lev_21);
    temp2.add(lev_22);

    List<NaryTreeNode> temp3 = new ArrayList<NaryTreeNode>();  //level two second branch
    temp3.add(lev_23);
    temp3.add(lev_24);

    lev_11.nary_list.addAll(temp2);
    lev_12.nary_list.addAll(temp3);

    List<NaryTreeNode> temp = new ArrayList<NaryTreeNode>();  //level one
    temp.add(lev_11);
    temp.add(lev_12);
    temp.add(lev_13);


    // Add Temp to root  to form a leaf of the root
    root.nary_list.addAll(temp);

    // root=null;
    //Call the display function.
    t1.display(root);
  }
}

【问题讨论】:

  • 有人可以为此添加一个LevelOrder(BFS)遍历函数吗?我不知道为什么我什至不能在这段代码中定义一个队列
  • 好的,在显式导入 java.util.LinkedList 时,我可以添加队列。
  • 我正在考虑以递归方式执行此操作,我认为这就是问题所在,我认为这将很容易非递归。
  • 我写了这个函数,但是每个级别打印两次,有人能告诉我为什么吗?显示功能和输出在这里stackoverflow.com/questions/12808215/…

标签: java algorithm tree queue tree-traversal


【解决方案1】:

使用队列的级别顺序遍历:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.stream.Collectors;

public class LevelOrderTraversal {
    static class Node {
        int data;

        Node children[];

        Node(int data, int n) {
            children = new Node[n];
            this.data = data;
        }
    }

    public static void main(String[] args) {
        /*  
                       1 
                    /  |  \ 
                   2   3   4 
                 / | \ 
                5  6  7 
        */
        int n = 3;
        Node root = new Node(1, n);
        root.children[0] = new Node(2, n);
        root.children[1] = new Node(3, n);
        root.children[2] = new Node(4, n);
        root.children[0].children[0] = new Node(5, n);
        root.children[0].children[1] = new Node(6, n);
        root.children[0].children[2] = new Node(7, n);

        List<List<Integer>> levelList = levelOrder(root);
        for (List<Integer> level : levelList) {
            for (Integer val : level) {
                System.out.print(val + " ");
            }
            System.out.println();
        }
    }

    public static List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> levelList = new ArrayList<>();

        if (root == null) {
            return levelList;
        }

        Queue<Node> queue = new LinkedList<>();
        queue.add(root);

        while (!queue.isEmpty()) {
            int n = queue.size();
            List<Integer> level = new ArrayList<>();

            while (n-- > 0) {
                Node node = queue.remove();
                level.add(node.data);
                queue.addAll(Arrays.stream(node.children).filter(Objects::nonNull).collect(Collectors.toList()));
            }
            levelList.add(level);
        }
        return levelList;
    }

}

【讨论】:

  • 感谢,这篇文章已经被浏览了 13000 次,但仍然带有 - 1 :(
【解决方案2】:

以下似乎有效。为了额外的功劳,可以使用增强的 for 循环来完成迭代,并随时中止。您可能需要添加访问修饰符。

import java.util.*;

class NaryTree {
    final int data;
    final List<NaryTree> children;

    public NaryTree(int data, NaryTree... children) {
        this.data = data;
        this.children = Arrays.asList(children);
    }

    static class InOrderIterator implements Iterator<Integer> {
        final Queue<NaryTree> queue = new LinkedList<NaryTree>();

        public InOrderIterator(NaryTree tree) {
            queue.add(tree);
        }

        @Override
        public boolean hasNext() {
            return !queue.isEmpty();
        }

        @Override
        public Integer next() {
            NaryTree node = queue.remove();
            queue.addAll(node.children);
            return node.data;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }

    Iterable<Integer> inOrderView = new Iterable<Integer>() {
        @Override
        public Iterator<Integer> iterator() {
            return new InOrderIterator(NaryTree.this);
        } 
    };
}

测试代码:

public class Test {
    public static void main(String[] args) throws Exception {
        NaryTree tree = new NaryTree(100,
            new NaryTree(90, 
                new NaryTree(20),
                new NaryTree(30)
            ), new NaryTree(50, 
                new NaryTree(200),
                new NaryTree(300)
            ), new NaryTree(70)
        );
        for (int x : tree.inOrderView) {
            System.out.println(x);
        }
    }
}

【讨论】:

  • 好的,当我明确导入 java.util.LinkedList 时,问题解决了。我仍然得到输出为 100 \n 90 \n 50 \n 70 \n 20 \n 30 \n 200 \n 300 \n 我们可以修改它以获得基于级别的输出为 100\n 90 50 70 \n 20, 30 200 300 \n
猜你喜欢
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多