leetcode:Construct Binary Tree from Inorder and Postorder Traversal

来源:互联网 发布:令狐冲 知乎 编辑:程序博客网 时间:2024/06/06 00:39

Construct Binary Tree from Inorder and Postorder Traversal 

原题目连接地址:https://oj.leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
Runtime: 194 ms

一、实例

后序遍历 DGJHEBIFCA 中序遍历 DBGEHJACIF  请构造二叉树。

二、分析

            1、根据后序遍历的特点,'A' 为树第一层根节点,那么由中序遍历即可得 ‘DBGEHJ’ 和 ‘CIF’ 分别为左右子树;
            2、继续往前扫描后序遍历序列,'C' 为 'A' 右子树根节点,即第二层根节点,‘NULL’ 和 'IF' 分别为 'C' 的左右子树;
            3、继续往前扫描后序遍历序列,'F' 为 'C' 右子树根节点,即第三层根节点,'I' 和 'NULL' 分别为 'F' 的左右子树;
            4、继续往前扫描后序遍历序列,'I' 为 'F' 左子树根节点,即第四层根节点,'NULL' 和 'NULL' 分别为 'I' 的左右子树;
            5、继续往前扫描后序遍历序列,'B' 为 ‘A’ 左子树根节点,即第二层根节点,以此类推得到完整左子树,结果如图。



三、总结

            1、树以递归实现比较清晰易懂简短,但是消耗空间,一般情况下oj平台难以通过。实现思路如下,
                  递归步,以根节点为中心,建立第一层根节点,先构建其右子树,再构建其左子树;再以右子树根节点为中心,递归调用构建右、左子树;直到构建完整树。
                  递归基,如果子树为空,则返回NULL(表示不建立节点);如果子树有一个值,则构建叶节点。
            2、将递归代码转成非递归代码,需要用到栈。实现思路如下,
                  递归步,以根节点为中心,构建第一层根节点,声明定义左子树、右子树,压入栈,同时需要将中序遍历序列中左右子树部分的头尾序号压入栈中;再取出子树,以  其为中心,构建右、左子树,同时将左右子树序号压入栈中;直到构建完整树;
  递归基,如果子树为空,则返回NULL(表示不建立节点);如果子树有一个值,则构建叶节点。
                  此外,还需要加入边界值的判断,如空树、只有根节点的树;其次如果子树为空,需要将已经声明定义好的左右子树delete。
 

四、实现方案


递归实现方案:
<pre name="code" class="cpp">#include<vector>using namespace std;struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}};class Solution {public:TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {if (inorder.size() == 0){return NULL;}if (inorder.size() == 1){struct TreeNode *tree = new TreeNode(inorder[0]);return tree;}int i;for (i = 0; i < inorder.size(); i++){if (inorder[i] == postorder.back())break;}vector<int> postorderCopy = postorder;int rootNode = postorderCopy.back();postorderCopy.pop_back();struct TreeNode *tree = new TreeNode(rootNode);vector<int> inorderLeft, inorderRight;if (0 <= i - 1){//inorderLeft.assign(inorder.begin(), inorder.begin() + i - 1);for (int j = 0; j < i; j++)inorderLeft.push_back(inorder[j]);}tree->left = buildTree(inorderLeft, postorderCopy);if (i + 1 <= inorder.size() - 1){//inorderRight.assign(inorder.begin() + i + 1, inorder.end());for (int j = i + 1; j < inorder.size(); j++)inorderRight.push_back(inorder[j]);}tree->right = buildTree(inorderRight, postorderCopy);return tree;}};void preorder_travel(TreeNode *tree){if (tree == NULL){cout << "# ";return;}cout << tree->val <<  " ";preorder_travel(tree->left);preorder_travel(tree->right);}int main(int argc, char **argv[]){vector<int> io = { 2, 3, 1 };vector<int> po = { 3, 2, 1 };Solution s;preorder_travel(s.buildTree(io, po));cout << endl;return 0;}


</pre><pre>
非递归的实现方案:
<pre name="code" class="cpp">class Solution {public:bool deleteNode(TreeNode *root, TreeNode *tree){if (root != NULL){if (root->right == tree){delete tree;root->right = NULL;return true;}if (root->left == tree){delete tree;root->left = NULL;return true;}deleteNode(root->right, tree);deleteNode(root->left, tree);return false;}}TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {if (inorder.size() != postorder.size())return NULL;if (inorder.size() == 0 && postorder.size() == 0)return NULL;if (inorder.size() == 1 && postorder.size() == 1){TreeNode *tree = new TreeNode(inorder[0]);return tree;}vector <int> stack;TreeNode *tree = new TreeNode(0);vector <TreeNode *> treeStack;treeStack.push_back(tree);stack.push_back(0);stack.push_back(postorder.size() - 1);while (treeStack.size() > 0){int right = stack.back(); stack.pop_back();int left = stack.back(); stack.pop_back();TreeNode *tree2 = treeStack.back();treeStack.pop_back();if (left > right){deleteNode(tree, tree2);continue;}if (left == right){tree2->val = postorder.back();postorder.pop_back();continue;}int i;for (i = 0; i < inorder.size(); i++){if (inorder[i] == postorder.back())break;}tree2->val = postorder.back();postorder.pop_back();TreeNode *treeLeft = new TreeNode(0);tree2->left = treeLeft;treeStack.push_back(treeLeft);stack.push_back(left);stack.push_back(i - 1);TreeNode * treeRight = new TreeNode(0);tree2->right = treeRight;treeStack.push_back(treeRight);stack.push_back(i + 1);stack.push_back(right);}return tree;}};


五、对比提升

          在网上找到一个43ms的方案,用递归实现。其充分利用了后序遍历和中序遍历序列的特点,即两者的左右子树序列是对应的,只要递归的调用构造子树即可完成整棵树的建立,其优点是直接建立节点,如果保存的 start下标 > end下标,则不建立节点。这样子省略了很多变量,值得学习。 如下图:
         原文地址:http://blog.csdn.net/zjull/article/details/11686973 

0 0
原创粉丝点击