对于二叉树,我想按连续顺序添加下一个节点,但我的算法并不是很有效

时间:2012-11-03 22:39:23

标签: java binary-tree

例如,如果我有

  A
 / \
 B  C
/  
D 

我希望下一个添加:

  A
 / \
 B  C
/ \ 
D  E

但是我在检测项目输入的下一个位置时遇到了很多麻烦。我有以下代码:

    public static BinaryTree<String> addToTree(BinaryTree<String> tree, String name) {
        if (tree.getLeft() == null) {
            BinaryTree<String> newTree = new BinaryTree<String>();
            newTree.makeRoot(name);
            tree.attachLeft(newTree);
        }
        else if (tree.getRight() == null) {
            BinaryTree<String> newTree = new BinaryTree<String>();
            newTree.makeRoot(name);
            tree.attachRight(newTree);
        }
        // Both are non-null
        else {
            if (tree.getLeft().getLeft() == null || tree.getLeft().getRight() == null) {
                tree.attachLeft(addToTree(tree.getLeft(), name));
            }
            else if (tree.getRight().getLeft() == null || tree.getRight().getRight() == null) {
                tree.attachRight(addToTree(tree.getRight(), name));
            }
        }

        return tree;
    }

但它只适用于三级树。如果我尝试添加第四个,则不再添加任何内容。

如何实现它以便找出下一个项目为空的位置,然后将其添加到那里?

我还想过一个checkNullity()方法,其中我会拿一棵树,检查它的孩子是否为空,但我也很难弄清楚如何让孩子的孩子。我想找到它的位置,然后将其添加到那里。

有人可以提供一些意见吗?

5 个答案:

答案 0 :(得分:2)

我认为您可以修改breadth first traversal来完成此操作。从队列中弹出项目时,请检查是否有任何子项为空。第一个空子槽是您要添加到的位置。

addNode(root, newNode) 
  q = empty queue
  q.enqueue(root)
  while not q.empty do
    node := q.dequeue()
    if node.left == null
      //create new node as nodes left child
      return
    q.enqueue(node.left)
    if node.right == null
      //create new node as nodes right child
      return
    q.enqueue(node.right)

答案 1 :(得分:0)

您可以在将所有节点添加到树中时枚举它们。如果您要将n个节点添加到树中,它将是n/2个节点的子节点:如果n%2 == 0则保留,如果n%2 == 1则保持正确

答案 2 :(得分:0)

因为,您希望按从左到右的顺序插入元素并从同一级别开始。我建议你去看看Breath First Search。我提供了一个基本的实现。

public void insert(child, root){

    if (root == null){
        root = child
    }

    Node iter = root
    Myqueue q = new Myqueue(); //Implementation of the Java Queue Interface

    while (iter!=null){

        //Check: If the left node exists, enque in the que
        if(iter.is_left()){
            q.insert(iter.left)
        }
        else{
            iter.left = child
            iter = null
        }

        //Similary for the right
        if(iter.is_right()){
            q.insert(iter.right)
        }
        else{
            iter.right = child
            iter = null
        }
        if (iter != null){
        iter = q.poll() //Retreiving the head of the queue
        }
    }
}

答案 3 :(得分:0)

这肯定会创建你要求的树,虽然我仍然不确定它是你想要的:

public class BinaryTree<T> {
  T root = null;
  BinaryTree<T> left = null;
  BinaryTree<T> right = null;

  public BinaryTree<T> getLeft() {
    return left;
  }

  public BinaryTree<T> getRight() {
    return right;
  }

  public void makeRoot(T root) {
    this.root = root;
  }

  public void attachLeft(BinaryTree<T> tree) {
    left = tree;
  }

  public void attachRight(BinaryTree<T> tree) {
    right = tree;
  }

  public static BinaryTree<String> addToTree(BinaryTree<String> tree, String name) {
    if (tree.getLeft() == null) {
      BinaryTree<String> newTree = new BinaryTree<String>();
      newTree.makeRoot(name);
      tree.attachLeft(newTree);
    } else if (tree.getRight() == null) {
      BinaryTree<String> newTree = new BinaryTree<String>();
      newTree.makeRoot(name);
      tree.attachRight(newTree);
    } else {
      addToTree(tree.getLeft(), name);
    }
    return tree;
  }

  public static void main(String[] args) {

    try {
      BinaryTree<String> tree = new BinaryTree<String>();
      String add = "ABCDEFG";
      tree.makeRoot(add.substring(0, 1));
      for (int i = 1; i < add.length(); i++) {
        addToTree(tree, add.substring(i, i + 1));
      }
      System.out.println("Done");
    } catch (Throwable e) {
      e.printStackTrace();
    }
  }
}

<强>加

我明显误解了这个问题。也许一个例子会有所帮助。

如果我从下面的字符串一次添加一个字符(作为字符串)你会期望什么?

“ABCDEFG”

  A
 / \
 B   C
/ \  | \
D  E F  G?

或其他。

你会期待什么

“ADEFGBC”

  A
 / \
 D   E
/ \  | \
F  G B  C

  A
 / \
 B   C
/ \  | \
D  E F  G

或其他什么?

两种情况都有可能,但在任何一种情况下我都看不到任何价值。

答案 4 :(得分:0)

为了将元素添加到二叉树中的适当位置,您必须从每个节点的根处开始回答以下问题:我应该下降到左侧还是右侧子树? / em>这就是你的问题归结为 - 如何在每个节点做出这个决定。

你开始没问题。如果节点没有左子树,则新添加的叶子应该是其左子节点。如果节点有一个左子树但没有右子树,那么新添加的叶子应该是它的右子。

但是如何确定节点是否同时具有子树?为此,您需要在可以用来决定的节点上保留某种信息。一种可能性是在每个节点处保持其子树的总大小。然后,如果两个子树具有相同的大小,则意味着两者都是完美平衡的,因此您添加到左侧。否则,如果左子树的大小为 2 ^ n-1 ,则表示它是平衡的(而右侧的子树不是),因此您向右添加。如果没有,请添加到左侧。


然而,你可以做得更简单。由于树总是保留此结构,因此您可以将树表示为ArrayList。根节点位于索引 0 ,对于索引 n 的节点,其子节点位于索引_2 * n + 1_和_2 * n + 2_。这就是binary heaps are implemented的方式。这样,您将获得添加新节点的 O(1)时间复杂度 - 只需将其附加到列表的末尾即可。 (但是,如果您需要一些经典的树操作,例如旋转,则此实现将不起作用。)