二叉树重建系列
二叉树重建
二叉树重建的关键思想是递归重建。
根据不同遍历的序列重建
- 从前序与中序遍历序列中重建二叉树(LeetCode 105)
题目描述:
分析:前序遍历是每次先遍历根节点,在遍历左子树和右子树。因此前序遍历序列的第一个元素就是根节点,然后递归建立左右子树。
代码:
class Solution {
public:
TreeNode* generate(vector<int>& preorder,int pos,vector<int>& inorder,int L2,int R2){
if(L2>R2)
return nullptr;
TreeNode* root=new TreeNode(preorder[pos]); //根节点
int k;
/*在中序遍历序列中寻找根节点,则此节点的左边是左子树,右边是右子树*/
for(int i=L2;i<=R2;i++)
if(inorder[i]==preorder[pos])
k=i;
root->left=generate(preorder,pos+1,inorder,L2,k-1); //递归建立左子树
root->right=generate(preorder,pos+k-L2+1,inorder,k+1,R2); //递归建立右子树
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size()==0||inorder.size()==0)
return nullptr;
return generate(preorder,0,inorder,0,inorder.size()-1);
}
};
- 从中序与后序遍历序列中重建二叉树(LeetCode 106)
分析:
- 后续遍历的根节点在postorder数组的最后一个
- 根据根节点的值找到根节点在中序遍历数组中的位置。
- 此时,中序遍历根节点的左边为左子树,右边为右子树。
- 将以上三步进入递归。生成二叉树
代码
class Solution {
public:
TreeNode* generate(vector<int>& inorder, int iS, int iE, vector<int>& postorder, int pS, int pE){
if(iS > iE || pS > pE) return NULL;
int rooot = postorder[pE];
int id = 0;
while(rooot != inorder[id]) ++ id;
TreeNode* root = new TreeNode(rooot);
root -> left = generate(inorder, iS, id - 1, postorder, pS, pS + id -iS -1);
root -> right = generate(inorder,id + 1, iE, postorder, pS + id - iS, pE - 1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.empty()) return NULL;
return generate(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);
}
};
根据数组或者链表重建
- 将有序数组转换成二叉搜索树(108)
分析:找到中点,作为根节点,进入递归.
代码
class Solution {
public:
TreeNode* generate(vector<int>& nums,int l,int r){
if(l>r)
return nullptr;
int mid=l+((r-l) >>1);
TreeNode* root=new TreeNode(nums[mid]);
root->left=generate(nums,l,mid-1);
root->right=generate(nums,mid+1,r);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
if(nums.size()==0) return nullptr;
return generate(nums,0,nums.size()-1);
}
};
- 有序链表转换成二叉搜索树(109)
分析:同108,每次找到中点,将中点作为根节点,重建二叉树
代码
class Solution {
public:
ListNode* mid(ListNode* head,ListNode* tail){ //寻找链表中点
ListNode *fast=head;
ListNode* low=head;
while(fast != tail && fast->next != tail)
{
fast=fast->next->next;
low=low->next;
}
return low;
}
TreeNode* generate(ListNode* head,ListNode* tail){
if(head==tail) return nullptr;
ListNode* mi=mid(head,tail);
TreeNode* root=new TreeNode(mi->val);
ListNode* head2;
head2=mi->next;
root->left=generate(head,mi);
root->right=generate(head2,tail);
return root;
}
TreeNode* sortedListToBST(ListNode* head) {
if(head==nullptr)
return nullptr;
return generate(head,nullptr);
}
};