数据结构之美--树(01)

1.重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回

思路:前序(根左右)遍历的第一个节点就是根节点,于是我们在中序(左根右)遍历中找到该节点,于是该节点就把树划分成了左子树和右子树,之后递归求解即可

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution
{
  public:
	TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder)
	{
		auto pre_size = preorder.size();
		auto in_size = inorder.size();

		if (pre_size != in_size || pre_size == 0 || in_size == 0)
			return nullptr;

		return fun(preorder, 0, pre_size - 1, inorder, 0, in_size - 1);
	}
	TreeNode *fun(vector<int> &preorder, int preL, int preR, 
		vector<int> &inorder, int inderL, int inderR)
	{
		if (preL > preR)
			return nullptr;
		TreeNode *root = new TreeNode(preorder[preL]);

		int i = 0;
		for (; i <= inderR; i++)
		{
			if (inorder[i] == preorder[preL])
				break;
		}

		int left_size = i - inderL;
		int right_size = inderR - i;

		root->left = fun(preorder, preL + 1, preL + left_size, 
			inorder, inderL, i - 1);

		root->right = fun(preorder, preL + left_size + 1, preR, 
			inorder, i + 1, inderR);

		return root;
	}
};

4. 序列化二叉树

题目:实现两个函数,分别用来序列化和反序列化二叉树
题解:首先,前序遍历化为一个序列! 
反序列化时,第一个就是root,之后前半部分是左子树,后半部分是右子树,遇到一个’#'就得回到前面去找其

class Codec
{
  public:
    // Encodes a tree to a single string.
    string serialize(TreeNode *root)
    {
        if (root == nullptr)
            return "#";
        return to_string(root->val) + "," + serialize(root->left) +","+ serialize(root->right);
    };
    // Decodes your encoded data to tree.
    TreeNode *deserialize(string data)
    {
        return fun(data);
    }

  private:
    TreeNode *fun(string &data)
    {
        if (data == "")
            return nullptr;
        if (data[0] == '#')
        {
            data = data.substr(data.find(',')+1);
            return nullptr;
        }

        size_t idx=0;
        int x = stoi(data,&idx);
         data = data.substr(idx + 1);
        
        TreeNode *root = new TreeNode(x);
        
        root->left = fun(data);
        root->right = fun(data);
        return root;
    }
};

这是最骚的:

class Codec {
    private:
    TreeNode* _root;
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        _root = root;
        return string();
    }
    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        return _root;
    }
};

3. BST的后序遍历序列

题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同

后序遍历(左右根).最后一个节点一定是整个树的根节点,根据树与递归的关系,泛化而讲,他会是的根节点(包括左子树,右子树等等).所以我们的思路就是先找到根,然后判断前部分(相当于左子树)是否小于根,后部分(相当于右子树)是否大于根即可

class Solution
{
  public:
    bool VerifySquenceOfBST(vector<int> sequence)
    {
        int sz = sequence.size();
        if (sz == 0)
            return false;
        return IsBST(sequence, 0, sz - 1);
    }
    //第一部分是左子树结点的值,它们都比根结点的值小
    bool IsBST(const vector<int> &sequence, int left, int right)
    {
        if (left >= right)
            return true;
        int mid, tp = left;
        int root = sequence.at(right);
        /*先找左子树*/
        while (tp < right && sequence.at(tp) < root)
        {
            tp++;
        }
        if (tp < right)
        {
            mid = tp;
            //第二部分是右子树结点的值,它们都比根结点的值大
            // 查找右子树是否符合要求
            while (tp < right)
            {
                if (sequence.at(tp) < root)
                {
                    return false;
                }
                tp++;
            }
        }
        // 递归的判断左右子树是否符合要求
        return IsBST(sequence, left, mid - 1) && IsBST(sequence, mid, right - 1);
    }
};

posted @ 2019-01-14 18:11  Tattoo_Welkin  阅读(184)  评论(0编辑  收藏  举报