[Likou] Restore the binary tree according to the preorder and inorder traversal results of the binary tree (and postorder and inorder restoration)

A pre-order and in-order restored binary tree

Connection: restore the binary tree according to the preorder and inorder traversal results of the binary tree
insert image description here

The idea is this:

  • The purpose of this algorithm is to reconstruct a binary tree based on the results of preorder traversal and inorder traversal.
  • The characteristic of the preorder traversal is that the first element must be the root node, and the following elements are the preorder traversal of the left subtree and the right subtree.
  • The characteristic of in-order traversal is that the root node is in the middle of the left subtree and the right subtree, the left element is the in-order traversal of the left subtree, and the right element is the in-order traversal of the right subtree.
  • Therefore, we can use the pre-order traversal to determine the root node, and then find the location of the root node in the in-order traversal, thereby dividing the interval between the left subtree and the right subtree.
  • We then recursively do the same for the left and right subtrees until the interval is either empty or has only one element.
  • Finally, we return the root node of the reconstructed binary tree.

Code with comments:

class Solution {
    
     
public: 
  //后序确定根 
  //中序分割左右区间 
  TreeNode* _buildTree(vector<int>& inorder, vector<int>& postorder, int& posti, int ibegin, int iend) {
    
     
    if (ibegin > iend) return nullptr; //如果中序区间为空,返回空指针
    TreeNode* root = new TreeNode(postorder[posti]); //创建根节点,值为后序遍历的最后一个元素
    //分割左右子区间 
    int rooti = ibegin; //找到根节点在中序遍历中的位置
    while (rooti <= iend) {
    
     
      if (inorder[rooti] == postorder[posti]) break; //找到了,跳出循环
      else rooti++; //没找到,继续向右移动
    } 
    --posti; //后序遍历的索引向前移动一位
    root->right = _buildTree(inorder, postorder, posti, rooti+1, iend); //递归构建右子树,中序区间为[rooti+1, iend]
    root->left = _buildTree(inorder, postorder, posti, ibegin, rooti-1); //递归构建左子树,中序区间为[ibegin, rooti-1]
    return root; //返回根节点
  } 
  TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
    
     
    int i = postorder.size()-1; //初始化后序遍历的索引为最后一位
    return _buildTree(inorder, postorder, i, 0, inorder.size()-1); //调用辅助函数,中序区间为[0, inorder.size()-1]
  } 
};

Binary Postorder and Inorder Reduction of Binary Trees

What if the post-order and in-order allow you to restore the binary tree?
Link: post-order and in-order restore a binary tree

It is still the same idea as above, but this time the right subtree needs to be built recursively first, because the characteristic of the post-order traversal is that the last element is the root node, and the previous elements are the post-order traversal of the left subtree and the right subtree , and the right subtree is behind the left subtree. Therefore, we need to recursively build the right subtree first, and then build the left subtree, so as to ensure that the index of post-order traversal is correct

insert image description here

  • The last element of the post-order traversal is the root node of the binary tree.
  • Find the position of the root node in the in-order traversal. The sequence to the left of the root node is the in-order traversal of the left subtree, and the sequence to the right is the in-order traversal of the right subtree.
  • In the post-order traversal, find the corresponding sequence of the left subtree and the right subtree. The length of the left subtree is the same as the length of the left subtree in the in-order traversal, and the same is true for the right subtree.
  • Repeat the above steps recursively for the left and right subtrees until the post-order traversal or in-order traversal is empty.

For example, given postorder traversal [9, 15, 7, 20, 3] and inorder traversal [9, 3, 15, 20, 7], the process of restoring a binary tree is as follows:

  • The last element of the post-order traversal is 3, which is the root node of the binary tree.
  • Find the position of 3 in the inorder traversal, the sequence [9] to the left of it is the inorder traversal of the left subtree, and the sequence [15, 20, 7] to the right is the inorder traversal of the right subtree.
  • Find the sequence of the corresponding left subtree and right subtree in the post-order traversal. The left subtree has only one element [9], and the right subtree has three elements [15, 7, 20].
  • Recursively restore the binary tree to the left subtree. Since the post-order traversal and in-order traversal have only one element, the left child node is 9.
  • Recursively restore the binary tree to the right subtree. Since the post-order traversal and in-order traversal are both empty, repeat the above steps.

code:

class Solution {
    
     
public: 
  //后序确定根 
  //中序分割左右区间 
  TreeNode* _buildTree(vector<int>& inorder, vector<int>& postorder, int& posti, int ibegin, int iend) {
    
     
    if (ibegin > iend) return nullptr; //如果中序区间为空,返回空指针
    TreeNode* root = new TreeNode(postorder[posti]); //创建根节点,值为后序遍历的最后一个元素
    //分割左右子区间 
    int rooti = ibegin; //找到根节点在中序遍历中的位置
    while (rooti <= iend) {
    
     
      if (inorder[rooti] == postorder[posti]) break; //找到了,跳出循环
      else rooti++; //没找到,继续向右移动
    } 
    --posti; //后序遍历的索引向前移动一位
    root->right = _buildTree(inorder, postorder, posti, rooti+1, iend); //递归构建右子树,中序区间为[rooti+1, iend]
    root->left = _buildTree(inorder, postorder, posti, ibegin, rooti-1); //递归构建左子树,中序区间为[ibegin, rooti-1]
    return root; //返回根节点
  } 
  TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
    
     
    int i = postorder.size()-1; //初始化后序遍历的索引为最后一位
    return _buildTree(inorder, postorder, i, 0, inorder.size()-1); //调用辅助函数,中序区间为[0, inorder.size()-1]
  } 
};

end of this section

Guess you like

Origin blog.csdn.net/weixin_62676865/article/details/130466686