问题
I want to write a function to construct a full binary tree from a given preorder and postorder array. I found that link http://www.geeksforgeeks.org/full-and-complete-binary-tree-from-given-preorder-and-postorder-traversals/ which proposes the following C code :
struct node* constructTreeUtil (int pre[], int post[], int* preIndex,
int l, int h, int size)
{
// Base case
if (*preIndex >= size || l > h)
return NULL;
// The first node in preorder traversal is root. So take the node at
// preIndex from preorder and make it root, and increment preIndex
struct node* root = newNode ( pre[*preIndex] );
++*preIndex;
// If the current subarry has only one element, no need to recur
if (l == h)
return root;
// Search the next element of pre[] in post[]
int i;
for (i = l; i <= h; ++i)
if (pre[*preIndex] == post[i])
break;
// Use the index of element found in postorder to divide postorder array in
// two parts. Left subtree and right subtree
if (i <= h)
{
root->left = constructTreeUtil (pre, post, preIndex, l, i, size);
root->right = constructTreeUtil (pre, post, preIndex, i + 1, h, size);
}
return root;
}
// The main function to construct Full Binary Tree from given preorder and
// postorder traversals. This function mainly uses constructTreeUtil()
struct node *constructTree (int pre[], int post[], int size)
{
int preIndex = 0;
return constructTreeUtil (pre, post, &preIndex, 0, size - 1, size);
}
I tried to rewrite this code in Java. Here is my code :
private static TreeNode constructTree(int[] preorder, int[] postorder, Index index, int lowIndex, int highIndex){
// Base case
if (index.index >= preorder.length || lowIndex > highIndex){
return null;
}
// The first node in preorder traversal is root. So take the node at
// preIndex from preorder and make it root, and increment preIndex
TreeNode root = new TreeNode (preorder[lowIndex]);
index.index++;
// If the current subarry has only one element, no need to recur
if (lowIndex == highIndex){
return root;
}
// Search the next element of pre[] in post[]
int i = 0;
for (i = lowIndex; i <= highIndex; ++i)
if (preorder[i]== postorder[lowIndex])
break;
// Use the index of element found in postorder to divide postorder array in
// two parts. Left subtree and right subtree
if (i <= highIndex) {
root.left = constructTree(preorder, postorder, index, lowIndex, i);
root.right = constructTree(preorder, postorder, index, i + 1, highIndex);
}
return root;
}
//The main function to construct Full Binary Tree from given preorder and
//postorder traversals. This function mainly uses constructTreeUtil()
public static TreeNode constructTree (int preorder[], int postorder[]) {
return constructTree (preorder, postorder, new Index(), 0, preorder.length - 1);
}
But I got a continuous loop in the root node (it didn't pass to the other nodes which have to be its child). Can you help me please to see where is the error in my Java code?
I'm not really sure but I think that the error maybe comes from these lines :
int i = 0;
for (i = lowIndex; i <= highIndex; ++i)
if (preorder[i]== postorder[lowIndex])
break;
I didn't understand very well the correspond lines in the original C code. Especially in this part
回答1:
Here are the bugs:
- Line
if (preorder[i]== postorder[lowIndex])
has two errors: the first is that you search in preorder instead of in postorder, and the second is that you use lowIndex instead of preIndex. This line should be:if (preorder[index.index]== postorder[i])
- Line
TreeNode root = new TreeNode (preorder[lowIndex]);
- lowIndex is used again instead of preIndex. This line should be:TreeNode root = new TreeNode (preorder[index.index]);
Pay attention to the fact that this code would work only for full binary trees
回答2:
Assuming that your code written in C works, then my guess is that for this part
// Search the next element of pre[] in post[]
int i = 0;
for (i = lowIndex; i <= highIndex; ++i)
if (preorder[i]== postorder[lowIndex])
break;
you'd want to use the same variables that you use in the C version. In this case, your if statement should be
if (preorder[index.index]== postorder[i])
回答3:
First make your TreeNode into a class, since it is the java equivalent of a struct
public class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val){
this.val = val;
}
}
Then make your TreeUtil class
public class TreeUtil{
private static TreeNode constructTree(int[] preorder, int[] postorder, int index, int lowIndex, int highIndex){
// Base case
if (index >= preorder.length || lowIndex > highIndex){
return null;
}
// The first node in preorder traversal is root. So take the node at
// preIndex from preorder and make it root, and increment preIndex
TreeNode root = new TreeNode (preorder[index]);
index++;
// If the current subarry has only one element, no need to recur
if (lowIndex == highIndex){
return root;
}
// Search the next element of pre[] in post[]
for (int i = lowIndex; i <= highIndex; i++)
if (preorder[index]== postorder[i]){
// Use the index of element found in postorder to divide postorder array in
// two parts. Left subtree and right subtree
root.left = constructTree(preorder, postorder, index, lowIndex, i);
root.right = constructTree(preorder, postorder, index, i + 1, highIndex);
break;
}
}
return root;
}
//The main function to construct Full Binary Tree from given preorder and
//postorder traversals. This function mainly uses constructTreeUtil()
public static TreeNode constructTree (int preorder[], int postorder[]){
return constructTree (preorder, postorder, 0, 0, preorder.length - 1);
}
}
Errors in your code were if (preorder[i]== postorder[lowIndex]
and TreeNode root = new TreeNode (preorder[lowIndex]);
as mentioned by aviad. I changed your code for you to be slightly less confusing. Using the Index is a great way to confuse yourself especially since an int will work fine. Also ++i increments before you run the loop and isn't conventionally used in java and java lets you declare variables a part of your loop definition so I changed that for loop to be more what your are looking for.
来源:https://stackoverflow.com/questions/37197476/rewrite-a-c-code-in-java-to-construct-full-binary-tree