建筑树自下而上的问题

时间:2010-04-08 02:55:51

标签: java

我自下而上构建二叉树时遇到问题。 树的输入将是树的内部节点,该节点的子节点是最终树的叶子。

因此,如果树为空,则根将是第一个内部节点。

之后,要添加的下一个内部节点将是新的根(NR),其中旧的根(OR)是NR的子节点之一。等等。

我遇到的问题是,无论何时我添加一个NR,当我进行inOrder遍历时,OR的子节点似乎都会丢失。事实证明,当我执行getSize()调用时,在addNode(Tree,Node)之前和之后返回相同数量的节点

赞赏解决此问题的任何帮助

编辑时包含节点类代码。 树和节点类都有addChild方法,因为我不太确定将它们放在哪里以供它使用。任何对此的评论也将受到赞赏。

代码如下:

import java.util.*;

public class Tree {

Node root;
int size;

public Tree() {
    root = null;
}

public Tree(Node root) {
    this.root = root;
}

public static void setChild(Node parent, Node child, double weight) throws ItemNotFoundException {
    if (parent.child1 != null && parent.child2 != null) {
        throw new ItemNotFoundException("This Node already has 2 children");
    } else if (parent.child1 != null) {
        parent.child2 = child;
        child.parent = parent;
        parent.c2Weight = weight;
    } else {
        parent.child1 = child;
        child.parent = parent;
        parent.c1Weight = weight;
    }
}

public static void setChild1(Node parent, Node child) {
    parent.child1 = child;
    child.parent = parent;
}

public static void setChild2(Node parent, Node child) {
    parent.child2 = child;
    child.parent = parent;
}

public static Tree addNode(Tree tree, Node node) throws ItemNotFoundException {
    Tree tree1;
    if (tree.root == null) {
        tree.root = node;
    } else if (tree.root.getSeq().equals(node.getChild1().getSeq()) ||
            tree.root.getSeq().equals(node.getChild2().getSeq())) {


        Node oldRoot = tree.root;
        oldRoot.setParent(node);


        tree.root = node;


    } else { //form a disjoint tree and merge the 2 trees
        tree1 = new Tree(node);
        tree = mergeTree(tree, tree1);
    }
    System.out.print("addNode2 = ");
    if(tree.root != null ) {
        Tree.inOrder(tree.root);
    }
    System.out.println();
    return tree;

}


public static Tree mergeTree(Tree tree, Tree tree1) {
    String root = "root";
    Node node = new Node(root);
    tree.root.setParent(node);
    tree1.root.setParent(node);
    tree.root = node;
    return tree;
}

public static int getSize(Node root) {
    if (root != null) {
        return 1 + getSize(root.child1) + getSize(root.child2);
    } else {
        return 0;
    }

}

public static boolean isEmpty(Tree Tree) {
    return Tree.root == null;
}

public static void inOrder(Node root) {
    if (root != null) {
        inOrder(root.child1);
        System.out.print(root.sequence + "  ");
        inOrder(root.child2);

    }
}

}

Node root; int size; public Tree() { root = null; } public Tree(Node root) { this.root = root; } public static void setChild(Node parent, Node child, double weight) throws ItemNotFoundException { if (parent.child1 != null && parent.child2 != null) { throw new ItemNotFoundException("This Node already has 2 children"); } else if (parent.child1 != null) { parent.child2 = child; child.parent = parent; parent.c2Weight = weight; } else { parent.child1 = child; child.parent = parent; parent.c1Weight = weight; } } public static void setChild1(Node parent, Node child) { parent.child1 = child; child.parent = parent; } public static void setChild2(Node parent, Node child) { parent.child2 = child; child.parent = parent; } public static Tree addNode(Tree tree, Node node) throws ItemNotFoundException { Tree tree1; if (tree.root == null) { tree.root = node; } else if (tree.root.getSeq().equals(node.getChild1().getSeq()) || tree.root.getSeq().equals(node.getChild2().getSeq())) { Node oldRoot = tree.root; oldRoot.setParent(node); tree.root = node; } else { //form a disjoint tree and merge the 2 trees tree1 = new Tree(node); tree = mergeTree(tree, tree1); } System.out.print("addNode2 = "); if(tree.root != null ) { Tree.inOrder(tree.root); } System.out.println(); return tree; } public static Tree mergeTree(Tree tree, Tree tree1) { String root = "root"; Node node = new Node(root); tree.root.setParent(node); tree1.root.setParent(node); tree.root = node; return tree; } public static int getSize(Node root) { if (root != null) { return 1 + getSize(root.child1) + getSize(root.child2); } else { return 0; } } public static boolean isEmpty(Tree Tree) { return Tree.root == null; } public static void inOrder(Node root) { if (root != null) { inOrder(root.child1); System.out.print(root.sequence + " "); inOrder(root.child2); } }

public class Node {

}

Node child1; Node child2; Node parent; double c1Weight; double c2Weight; String sequence; boolean isInternal; public Node(String seq) { sequence = seq; child1 = null; c1Weight = 0; child2 = null; c2Weight = 0; parent = null; isInternal = false; } public boolean hasChild() { if (this.child1 == null && this.child2 == null) { this.isInternal = false; return isInternal; } else { this.isInternal = true; return isInternal; } } public String getSeq() throws ItemNotFoundException { if (this.sequence == null) { throw new ItemNotFoundException("No such node"); } else { return this.sequence; } } public void setChild(Node child, double weight) throws ItemNotFoundException { if (this.child1 != null && this.child2 != null) { throw new ItemNotFoundException("This Node already has 2 children"); } else if (this.child1 != null) { this.child2 = child; this.c2Weight = weight; } else { this.child1 = child; this.c1Weight = weight; } } public static void setChild1(Node parent, Node child) { parent.child1 = child; child.parent = parent; } public static void setChild2(Node parent, Node child) { parent.child2 = child; child.parent = parent; } public void setParent(Node parent){ this.parent = parent; } public Node getParent() throws ItemNotFoundException { if (this.parent == null) { throw new ItemNotFoundException("This Node has no parent"); } else { return this.parent; } } public Node getChild1() throws ItemNotFoundException { if (this.child1 == null) { throw new ItemNotFoundException("There is no child1"); } else { return this.child1; } } public Node getChild2() throws ItemNotFoundException { if (this.child2 == null) { throw new ItemNotFoundException("There is no child2"); } else { return this.child2; } }

1 个答案:

答案 0 :(得分:1)

仅查看附加的代码,找不到明确的setChild被调用,只有setParent。如果您还附加了setParent的代码,那么我们可以确认该方法是否也创建了从父级到子级的反向链接。

我的猜测是setParent不会setChild,在这种情况下,孩子们的链接并没有丢失:它们从未被制作过。

//编辑后:

好的,现在确认setParent没有setChild,所以你从来没有做过这些链接。你应该扩充表单的所有调用:

someNode.setParent(otherNode);

还要:

otherNode.setChild(someNode);

其他评论:

  • setChild可以通过调用setChild1setChild2来减少重复性。
  • setChild中哪个链接可以自由使用的逻辑是正确的,但令人困惑,即“如果另一个链接不是免费的,那么使用这个”,而不是更直接的“如果这个是免费的,只需使用它。“
  • 养成在尽可能小的范围内声明和使用局部变量的习惯,例如: tree1中的addNode可以在使用它的一个块内声明。事实上,它甚至可以完全写出代码,例如tree = merge(tree, new Tree(node));
  • 您应该确认的是:node.getChild1().getSeq()是否容易导致NullPointerException被抛出?
    • //编辑后:好吧,它会抛出ItemNotFoundException。在任何一种情况下,addNode中的原始条件都是错误的,因为您无法保证两个孩子都存在(因为那时您将无法为其添加子项)。
  • //编辑后:为什么要将Node.setChild* Tree中的static功能复制为{{1}}方法...然后不使用其中任何一种?