我有我确定的基本逻辑错误,但我似乎无法修复它。我在使用未排序(postorder)和排序(inorder)列表创建树之前对GenericSimpleArrayList进行排序。当我对其中一个列表进行排序时,它们对它们进行排序?我不确定为什么。
public static <AnyType extends Comparable<? super AnyType>> BinaryNode<AnyType>constructBST ( GenericSimpleArrayList<AnyType> postorder ){
GenericSimpleArrayList <AnyType> g = postorder;
quicksort(postorder, new SortFunctor()); //this is where i sort the list.
GenericSimpleArrayList <AnyType> inorder = postorder;
return constructTree(inorder, g);
}
任何人都可以帮我解决这个问题吗?当我只对邮购进行排序时,为什么它会对g和后序排序?感谢。
编辑:添加了constructTree。
public static <AnyType> BinaryNode<AnyType> constructTree(GenericSimpleArrayList<AnyType> inorder, GenericSimpleArrayList<AnyType> postorder) {
int nodes = postorder.size();
AnyType root = postorder.get(nodes-1);
BinaryNode<AnyType> left = null;
BinaryNode<AnyType> right = null;
if (nodes > 1) {
int rootPos = 0;
for (int loop = 0; loop <= nodes-1; loop++) {
if (inorder.get(loop).equals(root)) {
rootPos = loop;
//System.out.println(loop);
} else {
//System.out.println("Not found at pos: " + loop);
}
}
if (rootPos != 0) {
GenericSimpleArrayList <AnyType> leftInorder = new GenericSimpleArrayList();//(AnyType) new Object[rootPos];
GenericSimpleArrayList <AnyType> leftPostorder = new GenericSimpleArrayList();//(AnyType[]) new Object[rootPos];
for (int loop = 0; loop < rootPos; loop++) {
leftInorder.add(inorder.get(loop));
leftPostorder.add(postorder.get(loop));
}
left = constructTree(leftInorder, leftPostorder );
}
if (rootPos < nodes-1){
GenericSimpleArrayList <AnyType> rightInorder = new GenericSimpleArrayList();//(AnyType[]) new Object[nodes - rootPos - 1];
GenericSimpleArrayList <AnyType> rightPostorder = new GenericSimpleArrayList();//(AnyType[]) new Object[rightInorder.length];
for (int loop = 0; loop < nodes-rootPos-1; loop++){
rightInorder.add(inorder.get(rootPos + loop + 1));
rightPostorder.add(postorder.get(rootPos + loop));
}
right = constructTree(rightInorder, rightPostorder);
}
}
return new BinaryNode<AnyType>(root, left, right);
}
答案 0 :(得分:3)
为什么在我只对邮购进行排序时,它会对g和后序排序?
GenericSimpleArrayList <AnyType> g = postorder;
postorder
是对象的引用。复制此引用时,您现在有两个引用到对象。但是仍然只有一个对象。
我不知道自定义ArrayList的API,但我认为你可以做
GenericSimpleArrayList<AnyType> g = new GenericSimpleArrayList<AnyType>(postorder);
或
GenericSimpleArrayList<AnyType> g = new GenericSimpleArrayList<AnyType>();
for(AnyType at: postorder)
g.add(at);
您的排序实用程序很可能会对集合进行排序。这对sort
函数来说非常常见,可以改变原始列表。
如果您想保留原始订单并对列表进行排序,我建议先复制一份清单。
改进之处是使用不同的结构(如TreeMap)以排序顺序记录字符串和原始位置的索引。
答案 1 :(得分:2)
GenericSimpleArrayList <AnyType> g = postorder;
GenericSimpleArrayList <AnyType> inorder = postorder;
在这两个陈述中,所有三个变量最初都将引用postorder
所引用的相同引用。因为您正在进行引用分配并且在一个对象状态下更新将反映到所有引用变量中。
constructTree(inorder, g);
因此,当您进行上述调用时,您将传递相同的引用。
答案 2 :(得分:2)
在这一行:
GenericSimpleArrayList <AnyType> g = postorder;
您只为相同的对象定义新名称g
。如果您希望g
成为不同的列表,则需要重新创建它(实际上是调用构造函数)并将postorder
的内容复制到其中