二叉搜索树与双向链表,从前序与中序遍历序列构造二叉树,从中序与后序遍历序列构造二叉树

173 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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);
    }
};