迭代n级链表Java

时间:2017-10-26 13:11:53

标签: java linked-list tree nodes

我有一个带有节点的树,每个节点都包含一个带有节点的列表,这些列表中的每个节点都包含节点......它可以是10级深度,大约有100个节点对象。

我已经尝试迭代查找所有单个节点对象,但大多数指南都涵盖了二进制树..它只是压倒性的。如果有人有一些伪代码或者可以指出我正确的方向,我会很高兴。下面的类(抱歉格式错误):

节点

public class Node {
    public String text;
    public LinkedList<Node> nodes;

    public Node() {
        this.nodes = new LinkedList<Node>();
    }

    public Node(String data) {
        this();
        this.text = data;
    }
}

public class Tree {
    public LinkedList<Node> nodes;
    public String text;

    public Tree() {
        nodes = new LinkedList<Node>();
    }

    public Tree(String data) {
        this();
        this.text = data;
    }
}

程序

public class Main {

    public static void main(String[] args) {

        LinkedList<Tree> trees = new LinkedList<Tree>();

        trees.add(new Tree("Root 1"));

        trees.get(0).nodes.add(new Node("Node 1"));
        trees.get(0).nodes.add(new Node("Node 2"));
        trees.get(0).nodes.add(new Node("Node 3"));

        trees.get(0).nodes.get(0).nodes.add(new Node("Node 1:Child 1"));
        trees.get(0).nodes.get(1).nodes.add(new Node("Node 2:Child 1"));
        trees.get(0).nodes.get(2).nodes.add(new Node("Node 3:Child 1"));

        for (Tree tree : trees) {
            tree.nodes.. // find all node-objects
        }
    }
}

4 个答案:

答案 0 :(得分:2)

这可以通过递归来完成。由于最大深度为10,最大元素数为100,因此递归不应出现任何性能问题。示例代码:

List<Node> flattenTree(List<Node> nodes){
    List<Node> allNodes=new LinkedList<>(nodes) ;
    for(Node node:nodes){
        {
           if(node.getNodes()!=null)
           allNodes.addAll(flattenTree(node.getNodes()));
        } 
     return allNodes;
    }

使用以下方式调用:

List<Node> allNodes = flattenTree(tree.getNodes);

allNodes将包含此树的所有节点。

答案 1 :(得分:1)

您可以使用递归来执行此操作:

interface TreeOp {
    void apply(Tree tree);
}

...

void traverse(Tree tree, TreeOp op) {
    op.apply(tree);
    for (Tree child: tree.nodes) {
        traverse(child, op);
    }
}

...

for (Tree tree : trees) {
    traverse(tree, (tree) -> {
       doSomethingWith(tree);
    });
}

更新:

实际上,您可以使用Consumer界面而不是定义新界面:

void traverse(Tree tree, Consumer<Tree> op) {
    op.accept(tree);
    for (Tree child: tree.nodes) {
        traverse(child, op);
    }
}

更新2:

遍历可能是Tree的一种方法:

void traverse(Consumer<Tree> op) {
    op.accept(this);
    for (Tree child: nodes) {
        traverse(child, op);
    }
}

答案 2 :(得分:1)

出于好奇,什么样的问题需要像这样的数据结构?

main中的此类内容应该让您走上正轨:

// set up the master list of all nodes and the list of unvisited nodes
// with the base tree's node.
List<Node> allTheNodes = new LinkedList<>();
allTheNodes.add(tree.node);
List<Node> unvisited = new LinkedList<>();
unvisited.add(tree.node);

while (!unvisited.isEmpty())
{
    // while our unvisited list is not empty, visit the first node in the list
    // and add all of its subnodes to both the list of nodes to visit and the master list of nodes.
    Node currentNode = unvisited.get(0);
    allTheNodes.addAll(currentNode.nodes);
    unvisited.addAll(currentNode.nodes);
    unvisited.remove(currentNode);
}   

// now, allTheNodes should have all of your nodes in it.

答案 3 :(得分:1)

您只需跟踪节点的深度:

LinkedList<Node> currentNodes = new LinkedList<Node>();
currentNodes.add(root);
int depth = 0;
while depth < 10 {
    depth++;
    int size = currentNodes.size();
    for (int i = 0; i < size; i++) {
        Node current = currentNodes.removeFirst();
        //Do something with current
        for (int j = 0; j < current.nodes.size(); j++) {
            currentNodes.addLast(current.nodes.get(j));
        }
    }
}