简体   繁体   English

java中通用树(n元树)的层序遍历

[英]Level Order traversal of a generic tree(n-ary tree) in java

(In case you want to avoid the lengthy explanation, all I am looking for is a level order traversal for a generic-tree(n-ary tree) in java. The code supplied works and needs the level order display function. Looked around for an hour but couldnt find reference to generic n-ary trees. Would appreciate if soemone can help me build the LevelOrderDisplay function on top of my code as it will help me understand the queue error that I am getting. Thanks! ) (如果您想避免冗长的解释,我所寻找的只是java中泛型树(n元树)的级别顺序遍历。提供的代码有效并且需要级别顺序显示功能。环顾四周一个小时,但找不到对通用 n 元树的引用。如果 soemone 可以帮助我在我的代码之上构建 LevelOrderDisplay 函数,我将不胜感激,因为它将帮助我理解我得到的队列错误。谢谢!)

I have been trying to implement a tree representation of Autosys job schedules at work.我一直在尝试在工作中实现 Autosys 作业计划的树形表示。 As each job(process) can have one or or more dependent job on them, i decided to go with a n-ary tree implementation so that i can map the flow.由于每个作业(进程)可以有一个或多个依赖作业,我决定采用 n 元树实现,以便我可以映射流程。 I am using java collections for the same.我正在使用 java 集合。 I need to perform a level order traversal to display job dependencies.我需要执行级别顺序遍历以显示作业依赖项。 First Print Root, then all nodes on level one and then all nodes on level 2 and so on.首先打印根,然后是第一层的所有节点,然后是第二层的所有节点,依此类推。

I tried to search for over an hour on StackOverflow but most the examples I came across were for Binary Trees.我试图在 StackOverflow 上搜索一个多小时,但我遇到的大多数示例都是二叉树。 I do understand that I need to use a queue for this.我明白我需要为此使用队列。

From what i got during my research, the algorithm should look like: Please correct me if this is wrong and if possible, provide a code for this.从我在研究过程中得到的信息来看,算法应该是这样的:如果这是错误的,请纠正我,如果可能,请提供一个代码。 Alternate approaches are also welcome but what I am really looking for is a simple elementary level order traversal of a generic tree.也欢迎使用其他方法,但我真正要寻找的是通用树的简单基本级顺序遍历。

Lets make this a resourceful thread for generic tree implementation.让我们使它成为通用树实现的资源丰富的线程。 Most of the code is already working.大部分代码已经可以工作了。 Please help.请帮忙。

Algo:

For each node, first the node is visited and then it's child nodes are put in a FIFO queue.对于每个节点,首先访问该节点,然后将其子节点放入 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

For some strange reason, I have not been able to declare a queue in my Eclipse IDE.由于某些奇怪的原因,我无法在 Eclipse IDE 中声明队列。 I have imported java.util.*;我已经导入了 java.util.*; I am missing something here, please have a look at the below errors.我在这里遗漏了一些东西,请查看以下错误。

1st Attempt:第一次尝试:

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

Error: The type LinkedList is not generic;错误:LinkedList 类型不是通用的; it cannot be parameterized with arguments它不能用参数参数化

2nd Attempt:第二次尝试:

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

Error: - QueueList cannot be resolved to a type错误:- QueueList 无法解析为类型

Current Tree Structure for reference:当前树结构供参考:

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

The output of the current display function is in pre order: 100 90 20 30 50 200 300 70 I need a level order traversal for the same.当前显示函数的输出是预先排序的: 100 90 20 30 50 200 300 70 我需要一个水平顺序遍历。 Required output.所需的输出。

> 100
> 90 50 70
> 20 30 200 300

This is a working code if someone wants to run it on their machine and add the level order traversal function.如果有人想在他们的机器上运行它并添加级别顺序遍历功能,这是一个有效的代码。 Please provide commented explanation for the queue operations as that is where I am stuck.请为队列操作提供注释解释,因为这是我被卡住的地方。

Thanks!谢谢!

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

The following seems to work.以下似乎有效。 For extra credit, iteration can be done with an enhanced for loop, and aborted at any time.额外的功劳,迭代可以通过增强的 for 循环完成,并随时中止。 You might want to add access modifiers.您可能想要添加访问修饰符。

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

Test code:测试代码:

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

Level-order traversal using Queue:使用 Queue 进行层序遍历:

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM