我正在尝试构造一个二叉树(不平衡),给定它的遍历。我目前正在预订+订购,但是当我想出这个问题后,订购后就没有问题了。
我意识到这个话题已经存在一些问题,但他们似乎都没有回答我的问题。我有一个递归方法,它采用二阶树的Preorder和Inorder来重构它,但由于某种原因无法将根节点与后续子节点链接起来。
注意:我不想要解决方案。我一直在试图弄清楚这几个小时,甚至在纸上记下了递归,一切看起来都很好......所以我必须错过一些微妙的东西。这是代码:
public static <T> BinaryNode<T> prePlusIn( T[] pre, T[] in)
{
if(pre.length != in.length)
throw new IllegalArgumentException();
BinaryNode<T> base = new BinaryNode();
base.element = pre[0]; // * Get root from the preorder traversal.
int indexOfRoot = -1 ;
if(pre.length == 0 && in.length == 0)
return null;
if(pre.length == 1 && in.length == 1 && pre[0].equals(in[0]))
return base; // * If both arrays are of size 1, element is a leaf.
for(int i = 0; i < in.length -1; i++){
if(in[i].equals(pre[0])){ // * Get the index of the root
indexOfRoot = i; // in the inorder traversal.
break;
}
} // * If we cannot, the tree cannot be constructed as the traversals differ.
if (indexOfRoot == -1) throw new IllegalArgumentException();
// * Now, we recursively set the left and right subtrees of
// the above "base" root node to whatever the new preorder
// and inorder traversals end up constructing.
T[] preleft = Arrays.copyOfRange(pre, 1, indexOfRoot + 1);
T[] preright = Arrays.copyOfRange(pre, indexOfRoot + 1, pre.length);
T[] inleft = Arrays.copyOfRange(in, 0, indexOfRoot);
T[] inright = Arrays.copyOfRange(in, indexOfRoot + 1, in.length);
base.left = prePlusIn( preleft, inleft); // * Construct left subtree.
base.right = prePlusIn( preright, inright); // * Construc right subtree.
return base; // * Return fully constructed tree
}
基本上,我构造了另外的数组,它们包含左右子树的预先和顺序遍历(这看起来非常低效,但我想不出更好的方法,没有帮助方法)。
任何想法都会非常感激。
旁注:在调试时,根音注释似乎永远不会收到与其他节点的连接(它们保持为空)。从我所看到的情况来看,这不应该发生......
编辑:为了澄清,该方法抛出了else
循环的IllegalArgumentException @第21行(for
分支,如果遍历包含不同,则应该仅抛出元件。
EDIT2 :感谢来自@Philip的有用帖子(巧合的是,我们有相同的名字......好玩!)。但是,如果有人提出任何提高效率的建议,我将不胜感激。
答案 0 :(得分:2)
这段代码对我非常怀疑
for(int i = 0; i < in.length -1; i++){
if(in[i].equals(base.element)){ // * Get the index of the root
indexOfRoot = i; // in the inorder traversal.
break;
} // * If we cannot, the tree cannot be constructed as the traversals differ.
else throw new IllegalArgumentException();
}
您进入循环并且i
设置为0,如果i
小于in.length - 1
,则评估循环体是if表达式。在这一点上,将发生两件事之一
in[i]
等于base.element
,在这种情况下,indexOfRoot
将设为0,您将摆脱循环无论哪种方式,你都不会实际增加i
尝试重做这个循环来做你想要的,因为它肯定没有做你想要的。您可以尝试类似
的内容int indexOfRoot = -1; //an impossible value
for(int i = 0; i < in.length -1; i++){
if(in[i].equals(base.element)){ // * Get the index of the root
indexOfRoot = i; // in the inorder traversal.
break;
}
}
if(indexOfRoot == -1){//if the root was never set
throw new IllegalArgumentException();
}
虽然这仍然有点难看(但有一点,base.element
永远不会改变,所以你可能想要使用pre[0]
来表示清晰度。并且,我绝不确定它是完全正确的。不过,它可能更接近你想要的东西