开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
二叉搜索树与双向链表
把一个二叉树变成一个有序的双向链表,首先有序是很简单的,因为二叉搜索树的中序遍历就是有序的,那么把二叉树进行中序遍历,然后改变节点的指向。 我们用两个指针,一个指针
cur指向当前节点的位置,另一个指针pre指向中序遍历过程中当前节点的上一个节点(该节点要设成引用,因为要保证该节点在递归过程中是不变的)。cur->left=pre,pre->right=cur,然后pre要到当前cur的位置。
class Solution {
void inorder(TreeNode* root,TreeNode* & pre)
{
if(root==nullptr)
return ;
inorder(root->left, pre);
root->left=pre;
if(pre)
{
pre->right=root;
}
pre=root;
inorder(root->right, pre);
}
public:
TreeNode* Convert(TreeNode* pRootOfTree) {
if(!pRootOfTree)
return nullptr;
TreeNode* pre=nullptr;
TreeNode* root=pRootOfTree;
while(root->left)
root=root->left;
inorder(pRootOfTree,pre);
return root;
}
};
从前序与中序遍历序列构造二叉树
前序遍历是确定了根节点,中序遍历把根节点分成左右子树。 对于该到题目,我们把前序遍历的每一个元素看成一个根节点,然后利用中序遍历把左右子树确定,而左右子树又可以用该方法确定——子树递归即可。
class Solution {
TreeNode* create(vector<int>& preorder,vector<int>& inorder,int& i,int L,int R)
{
if(L>R||L<0||R<0)
return nullptr;
TreeNode* root=new TreeNode(preorder[i]);
int mid;
for(mid=L;mid<=R;mid++)
{
if(preorder[i]==inorder[mid])
break;
}
i++;
root->left=create(preorder,inorder,i,L,mid-1);
root->right=create(preorder,inorder,i,mid+1,R);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int i=0;
return create(preorder,inorder,i,0,preorder.size()-1);
}
};
从中序与后序遍历序列构造二叉树
该道题目和上一道题目差不多,只不过后序遍历的最后访问根节点。所以我们只需要把上道题目的遍历逆过来就行。注意:该题目先处理右树,在处理左树,因为后序遍历从后往左为:根,右,左。
class Solution {
TreeNode* create(vector<int>& postorder,vector<int>& inorder,int & i,int L,int R)
{
if(L>R||L<0||R<0)
return nullptr;
TreeNode* root=new TreeNode(postorder[i]);
int mid;
for(mid=L;mid<=R;mid++)
{
if(postorder[i]==inorder[mid])
break;
}
i--;
root->right=create(postorder,inorder,i,mid+1,R);
root->left=create(postorder,inorder,i,L,mid-1);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
int i=inorder.size()-1;
return create(postorder,inorder,i,0,inorder.size()-1);
}
};