K元树递归打印方法为非递归

时间:2018-12-14 12:43:00

标签: java recursion

我试图创建非递归Kary树。我发现了递归实现,并尝试更改为非递归。

这是树的类别:

public  NaryTreeNode(String LABEL, int n) {
    this.LABEL = LABEL;
    this.N = n;
    children = new ArrayList<>(n);
}

private void addChild(NaryTreeNode node) {
    if (children.size() < N) {
        children.add(node);
    }
}

public void addChild(String label) {
    this.addChild(new NaryTreeNode(label, N));
}

public ArrayList<NaryTreeNode> getChildren() {
    return new ArrayList<>(children);
}

public NaryTreeNode getChild(int index) {
    if (index < children.size()) {
        return children.get(index);
    }
    return null;
}

public static void printTest(NaryTreeNode root) {
    printUtil(root, 0);
}

private static void printUtil(NaryTreeNode node, int depth) {
    for (int i = 0; i < depth; ++i) {
        System.out.print("   ");
    }
    System.out.println(node.LABEL);

    for (NaryTreeNode child : node.getChildren()) {
        printUtil(child, depth + 1);
    }
}

这是测试的主要方法:

public class TestNaryTree {
public static void main(String[] args) {
    int n = 3;
    NaryTreeNode root = new NaryTreeNode("Matter", n);

    root.addChild("Pure");
    root.getChild(0).addChild("Elements");
    root.getChild(0).getChild(0).addChild("Metals");
    root.getChild(0).getChild(0).addChild("Metalloids");
    root.getChild(0).getChild(0).addChild("Non-metals");
    root.getChild(0).addChild("Compounds");
    root.getChild(0).getChild(1).addChild("Water");
    root.getChild(0).getChild(1).addChild("Carbon dioxide");
    root.getChild(0).getChild(1).addChild("Salt");
    root.getChild(0).getChild(1).addChild("Camphor");  // won't add
    root.addChild("Mixture");
    root.getChild(1).addChild("Homogeneous");
    root.getChild(1).getChild(0).addChild("Air");
    root.getChild(1).getChild(0).addChild("Vinegar");
    root.getChild(1).addChild("Heterogeneous");
    root.getChild(1).getChild(1).addChild("Colloids");
    root.getChild(1).getChild(1).addChild("Suspensions");

    NaryTreeNode.printTest(root);
}
}

这是主要结果:

enter image description here

如何将此printTest方法更改为不可递归的?

1 个答案:

答案 0 :(得分:1)

从您的代码看来,您似乎需要打印预订遍历。 如果您只想提示操作方法:请使用堆栈。

如果您想要一个可行的解决方案:

public static void printTest(NaryTreeNode root) {

    // If you don't need to know the depth, no need for the "Pair" class, you could use Stack<NaryTreeNode>
    // You could also use a Hashmap(node -> depth) if you'd rather not create a new class
    Stack<Pair> stack = new Stack<>();

    stack.push(new Pair(root, 0));
    while(!stack.empty()){
        Pair current = stack.pop();
        NaryTreeNode node = current.node;
        int depth = current.depth;
        printWithSpaces(depth, node.LABEL);

        // If you don't care about the order, you could simply replace this block by
        // stack.addAll(node.getChildren())
        ArrayList<NaryTreeNode> children = node.getChildren();
        for (int i = children.size() - 1; i >= 0; i--) {
            stack.push(new Pair(children.get(i), depth+1));
        }
    }
}

private static void printWithSpaces(int depth, String label){
    // little bit optimized instead of printing spaces
    char[] chars = new char[3*depth];
    Arrays.fill(chars, ' ');
    StringBuilder sb = new StringBuilder();
    sb.append(chars).append(label);
    System.out.println(sb);
}

private static class Pair{
    NaryTreeNode node;
    int depth;

    public Pair(NaryTreeNode node, int depth) {
        this.node = node;
        this.depth = depth;
    }
}