我对将可能包含null的对象传递给其他方法的最佳方法有疑问。如果传递的对象为null,则另一个方法将创建一个新实例。我的问题是如何允许第二种方法修改origina初始传递的null对象指针。基本上,我在从文件读取BST并制作树时遇到了这个问题。我认为使用相同的例子来解释这个问题会更加明显:
在下面的代码中,我正在从存储在队列中的所有值中读取并构建BST。 Queue值是我从另一个方法读取的树的按顺序遍历。
TreeNode root2;
public void readBST(Queue<Integer> input){
if (input==null || input.isEmpty()) return;
int i=input.poll();
root2 = new TreeNode(i);
readBSTHelper(root2.leftChild , input, Integer.MIN_VALUE , i-1);
readBSTHelper(root2.rightChild, input, i+1, Integer.MAX_VALUE);
}
private void readBSTHelper(TreeNode curr, Queue<Integer> input, int min, int max){
if (input==null && input.isEmpty()) return;
int i = input.peek();
if (i>=min && i<=max){
input.poll();
curr = new TreeNode(i);
readBSTHelper(curr.leftChild, input, min, i-1);
readBSTHelper(curr.rightChild,input, i+1, max);
}
}
但是,我遇到的问题是,在创建root2
时,leftChild
和rightChild
为null
。事实上,TreeNode(i)
制作TreeNode
data=i
,leftChild
和rightChild
等于null
。当我通过readBSTHelper
调用root2.leftChild
时,它会传递null
指针。由于它是null
指针,因此null
指针的副本将传递给readBSTHelper
。因此,readBSTHelper
的结果将丢失,并且永远不会返回/分配给真实的root2.leftChild
。我们可以通过传递原始指针的引用来防止C ++中出现这样的问题。我能够通过修改代码来暂时解决问题:
TreeNode root2;
public void readBST(Queue<Integer> input){
if (input==null || input.isEmpty()) return;
int i=input.poll();
root2 = new TreeNode(i);
readBSTHelper(root2, "left", input, Integer.MIN_VALUE , i-1);
readBSTHelper(root2, "right", input, i+1, Integer.MAX_VALUE);
}
private void readBSTHelper(TreeNode curr, String side, Queue<Integer> input, int min, int max){
if (input.isEmpty()) return;
int i = input.peek();
if (i>=min && i<=max){
input.poll();
if (side.equals("left")) {
curr.leftChild = new TreeNode(i);
readBSTHelper(curr.leftChild,"left", input, min, i-1);
readBSTHelper(curr.leftChild, "right", input, i+1, max);
} else {
curr.rightChild = new TreeNode(i);
readBSTHelper(curr.rightChild,"left", input, min, i-1);
readBSTHelper(curr.rightChild, "right", input, i+1, max);
}
}
}
但这段代码看起来很难看。关于如何使第一个代码工作的任何建议?
答案 0 :(得分:2)
选项1:包装
class NodeWrapper
{
TreeNode node;
}
class TreeNode
{
...
TreeNode(int num)
{
leftChild = new NodeWrapper();
rightChild = new NodeWrapper();
...
}
NodeWrapper leftChild, rightChild;
}
void readBSTHelper(NodeWrapper curr, Queue<Integer> input, int min, int max)
{
...
}
选项2:在构造函数中初始化子项
我建议有一个专门用于此目的的单独构造函数(不在下面),否则你的insert函数会错误地创建子代。
class TreeNode
{
...
TreeNode()
{
val = null;
}
TreeNode(int num)
{
init(num);
}
init(int num)
{
leftChild = new TreeNode();
rightChild = new TreeNode();
val == num;
}
Integer val;
}
public void readBST(Queue<Integer> input){
if (input==null || input.isEmpty()) return;
int i=input.poll();
root2 = new TreeNode(i);
if (!readBSTHelper(root2.leftChild , input, Integer.MIN_VALUE , i-1))
root2.leftChild = null; // delete child if not populated
if (!readBSTHelper(root2.rightChild, input, i+1, Integer.MAX_VALUE))
root2.rightChild = null; // delete child if not populated
}
boolean readBSTHelper(TreeNode curr, Queue<Integer> input, int min, int max){
if (input==null && input.isEmpty()) return false;
int i = input.peek();
if (i>=min && i<=max){
input.poll();
curr.init(i);
if (!readBSTHelper(curr.leftChild, input, min, i-1))
curr.leftChild = null;
if (!readBSTHelper(curr.rightChild, input, i+1, max))
curr.rightChild = null;
return true;
}
return false;
}