即时通讯来自c ++到java,我对使用java的二叉树感到困惑。让Node类成为内部静态类的唯一方法是什么?我看到的所有例子都是这样做的。但是,我这样做的方式是我有一个节点类,而binarytree类使用这个节点类。但是当我在第二次插入后尝试插入树时,我一直收到错误。我在if(dataIn <= nodeIn.getLeft().getData()){
我对我做错了什么感到困惑....这是我的插入代码。提前谢谢..
public void insert(int dataIn){
root = insert(root, dataIn);
}
private Node insert(Node nodeIn, int dataIn){
if(nodeIn==null){
nodeIn = new Node(null, null, dataIn);
}else{
if(dataIn <= nodeIn.getLeft().getData()){
nodeIn.setLeft(insert(nodeIn.getLeft(), dataIn));
}else{
nodeIn.setRight(insert(nodeIn.getRight(), dataIn));
}
}
return nodeIn;
}
答案 0 :(得分:9)
令人困惑的部分原因是“Node”不应该是insert方法的参数,你应该调用node中定义的insert方法。
因此,假设您在“普通代码”中保留“Root”节点 - 让我们称之为“rootNode”只是为了模糊。
好的,所以你要插入树的代码是:
rootNode.insert(newValue);
很容易。
现在定义该方法。
public class Node {
private int value;
private Node lower;
private Node higher;
public void insert(int newValue) {
if (newValue < value)
if(lower == null)
lower=new Node(value);
else
lower.insert(newValue);
else
if(higher == null)
higher=new Node(value);
else
higher.insert(newValue);
}
// and you'll need a constructor
public Node(int value) {
this.value=value;
}
}
这应该更清楚地阅读。我打算点击“Post”然后我要编辑它并找出如何轻易地折射那个邪恶的邪恶副本&amp;粘贴代码。
第二个想法,我会留在那里,因为它更具可读性。我能看到的最好的解决方案是使节点成为一个数组,然后得到:
public class Node {
private int value;
private Node[] nodes=new Node[2];
private final int LOWER=0;
private final int HIGHER=1;
public void insert(int newValue) {
int index=LOWER;
if (newValue > value)
index=HIGHER;
if(nodes[index] == null)
nodes[index]=new Node(value);
else
nodes[index].insert(newValue);
}
}
但我不会取代原件,因为正如我所说,它更清楚。
我推荐重构书了解更多内容。一旦你真正获得OO,它确实有助于简化你的代码。将一个对象传递给另一个静态方法(一个不使用成员变量的方法)是一个死的赠品。
关于@ ted的评论和OO的更多考虑因素 - getLeft和getRight甚至不应成为问题。在抽象之外都没有必要。
一般来说,您可能需要的是Node中的这些方法:
public boolean doesContain(int value) {
if(value == this.value)
return true
else
return nodes[ this.value < value ? LOWER : HIGHER].doesContain(value);
}
也许
public void getValuesSorted(LinkedList l) {
nodes[LOWER].getValuesSorted(l);
l.put(value);
nodes[HIGHER].getValuesSorted(l);
}
然后你甚至不需要揭露它是你正在处理的树 - beter OO抽象。
答案 1 :(得分:4)
您需要测试nodeIn.getLeft() == null
。
答案 2 :(得分:1)
是使Node类成为内部静态类的唯一方法吗?我看到的所有例子都是这样做的。
没有
Node类不需要是内部类或嵌套类。 (严格来说,&#34;静态内部&#34;类是嵌套类。)
但是,只有内部或嵌套类可以是private
。如果您的Node
类是常规类,那么您将向(至少)同一包中的其他类公开实现细节。这是一个坏主意......这就解释了为什么你看到Node
类声明它的方式。
答案 3 :(得分:1)
您可以使用以下代码清除您的理解。大多数情况下,我们不使用任何其他类,可以在单个Node类本身内完成所有操作。这是一个非常基本的例子,我认为可能会有所帮助......当我看到你有两种方法,你只提供数据而不是root。相信我最好在你的主类中拥有root。推理我们在任何需要缓存的地方都很方便。
public Node insert(Node root, Node newNode) {
if (root == null) {
root = newNode;
} else {
if(root.data > newNode.data) {
root.left = insert(root.left, newNode);
} else {
root.right = insert(root.right, newNode);
}
}
return root;
}
从已初始化的任何类中直接调用此方法。这是一个样本plz检查..
Node root = new Node(10);
root.insert(root, new Node(5));
root.insert(root, new Node(3));
root.insert(root, new Node(6));
root.insert(root, new Node(1));
答案 4 :(得分:0)
而不是:
if (dataIn <= nodeIn.getLeft().getData()) {
......你想要:
if (dataIn < nodeIn.getData()) {
您需要将要插入的值与当前节点的值进行比较。
我将<=
符号更改为<
符号,以避免重复。
所以你重构的代码是:
public void insert(int dataIn) {
root = insert(root, dataIn);
}
private Node insert(Node nodeIn, int dataIn){
if (nodeIn == null) {
nodeIn = new Node(null, null, dataIn);
} else {
if (dataIn < nodeIn.getData()) {
nodeIn.setLeft(insert(nodeIn.getLeft(), dataIn));
} else {
nodeIn.setRight(insert(nodeIn.getRight(), dataIn));
}
}
return nodeIn;
}
答案 5 :(得分:0)
实际上,对于二叉树,不需要检查插入元素是否大于父节点或者不是父节点。我认为没有必要检查这些条件。我们必须从用户那里获取是否向右或向左插入的输入。
答案 6 :(得分:-1)
如果要将节点插入树的中间,那么所有解决方案都不会考虑到会发生什么。你假设它也将是最小的或最大的。当您在树的中间插入一些东西时,您将意识到操作变得更加复杂。