您的位置:首页 > 其它

105. Construct Binary Tree from Preorder and Inorder Traversal

2016-09-04 07:08 267 查看
Given preorder and inorder traversal of a tree, construct the binary tree.

Note: You may assume that duplicates do not exist in the tree.

首先可以自己写出一个既定二叉树的两种遍历,然后看看如何我们是怎么从输出倒推回输入的。拿这题为例,前序结果的第一个一定是root, 然后再中序里找到root值(这里假设了没有重复),中序里root左侧为其左子树的中序输出,右侧为其右子树的中序输出,所以在知道左右子树的输出长度后,我们在前序输出里找到左右子树的根节点,因为对于前序里的输出片段来说,根节点同样是第一个,依次类推,整个过程在中序输出里有点像binary search,这也是个明细的递归规律。传递数组下标在不同段落内实行同样的规律确立根节点。

方法一:递归

TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return helper(preorder, inorder, 0, inorder.size()-1, 0, preorder.size()-1);
}
TreeNode* helper(vector<int>& preorder, vector<int>& inorder, int instart, int inend, int prestart, int preend) {
if (instart > inend) return NULL;
int rootval = preorder[prestart];
int i;
for (i = instart; i <= inend; i++) {
if (inorder[i] == rootval) break;
}
TreeNode* res = new TreeNode(rootval);
res->left = helper(preorder, inorder, instart, i-1, prestart+1, prestart+(i-instart));
res->right = helper(preorder, inorder, i+1, inend, prestart+(i-instart)+1, preend);
return res;
}


方法二:queue实现

递归实现的本质也是使用了栈来存储,所以我们在这也模仿一下,用数据结构来存储后续信息,用迭代的过程来实现一边这个规律。

private:
struct NewNode {
TreeNode* node;
int rootindex;
int leftindex;
int rightindex;
NewNode(TreeNode* treenode): node(treenode), rootindex(0), leftindex(0), rightindex(0) {}
};
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.size() == 0 || inorder.size() == 0) return NULL;
queue<NewNode*> queueNode;
TreeNode *root = new TreeNode(preorder[0]);
NewNode *Root = new NewNode(root);
Root->rightindex = inorder.size() - 1;
queueNode.push(Root);
int leftval, rightval, rootval;
while (!queueNode.empty()) {
NewNode* curNode = queueNode.front();
queueNode.pop();
if (curNode->leftindex >= curNode->rightindex) continue
a414
;
rootval = preorder[curNode->rootindex];
for (int i = curNode->leftindex; i <= curNode->rightindex; i++) {
if (inorder[i] == rootval) {
if (i > curNode->leftindex) {
TreeNode* leftnode = new TreeNode(preorder[curNode->rootindex+1]);
NewNode* leftNode = new NewNode(leftnode);
leftNode->rootindex = curNode->rootindex + 1;
leftNode->leftindex = curNode->leftindex;
leftNode->rightindex = i-1;
curNode->node->left = leftnode;
queueNode.push(leftNode);
}
if (i < curNode->rightindex) {
TreeNode* rightnode = new TreeNode(preorder[curNode->rootindex+i-curNode->leftindex+1]);
NewNode* rightNode = new NewNode(rightnode);
rightNode->rootindex = curNode->rootindex+i-curNode->leftindex+1;
rightNode->leftindex = i+1;
rightNode->rightindex = curNode->rightindex;
curNode->node->right = rightnode;
queueNode.push(rightNode);
}
}
}
}
return root;
}


这里我们自己建了一个新的NewNode来存储基本的TreeNode以及这个node为根节点的子树范围,我们记录了在preorder里的根节点的位置,和在inorder里的范围,这样就可以类似于binary search一样的划分下一个左右子树。然后我们建了一个queue来存储后续节点,重复过程直到queue为空为止。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: