例如,如果我有
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()
方法,其中我会拿一棵树,检查它的孩子是否为空,但我也很难弄清楚如何让孩子的孩子。我想找到它的位置,然后将其添加到那里。
有人可以提供一些意见吗?
答案 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)时间复杂度 - 只需将其附加到列表的末尾即可。 (但是,如果您需要一些经典的树操作,例如旋转,则此实现将不起作用。)