题目描述
Construct Binary Tree from Preorder and Inorder Traversal
Given preorder and inorder traversal of a tree, construct the binary tree.Note:
You may assume that duplicates do not exist in the tree.
题目大意
根据给出的先序遍历和中序遍历顺序,画出他们所确定的二叉树。
思路分析
先序遍历:NLR,中序遍历:LNR。根据这个特点,可以根据先序遍历的次序确定根结点,再由根节点在中序遍历中的位置确定它的位置,或者说将中序遍历分成左子树部分和右子树部分。
这里我采用了利用栈实现非递归的算法,关键在于如何处理结点在中序遍历中的位置和二叉树中的位置之间的关系。
利用栈,若该结点的位置在中序遍历中处于栈顶结点的左侧(<栈顶结点的位置),那么它就是栈顶结点的左结点,将其链接起来并入栈;当该结点的位置在中序遍历中处于栈顶结点的右侧,说明它是栈顶结点或其祖先结点的右结点,关键就在于找到这个祖先结点。观察得知,这个祖先结点应该是栈中最后一个位于该结点左侧的结点,所以只要一直出栈来,就可以找到这个祖先结点。
关键代码
int findX(vector<int> v, int x) {
int n = v.size();
for (int i = 0; i < n; i++) {
if (v[i] == x) return i;
}
return -1;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n = preorder.size();
if (n == 0) return NULL;
TreeNode *root = new TreeNode(preorder[0]);
stack<TreeNode*> stackTN;
stack<int> stackPos;
stackTN.push(root);
stackPos.push(findX(inorder, preorder[0]));
for (int i = 1; i < n; i++) {
int temp = findX(inorder, preorder[i]);
TreeNode *tempNode = new TreeNode(preorder[i]);
TreeNode *tobe;
if (temp < stackPos.top()) {
stackTN.top()->left = tempNode;
stackTN.push(tempNode);
stackPos.push(temp);
} else {
while (!stackPos.empty() && temp > stackPos.top()) { // 寻找祖先结点
tobe = stackTN.top();
stackPos.pop();
stackTN.pop();
}
tobe->right = tempNode;
stackTN.push(tempNode);
stackPos.push(temp);
}
}
return root;
}
总结
这是二叉树的经典操作,与此同时,还顺便复习了利用栈实现非递归的算法。