每天算法 -- serialize and deserialize binary tree - medium

博客围绕二叉树的序列化与反序列化展开。指出利用递归思想解题,借鉴计算器思路,用特定表示法将二叉树简化为字符串,如 1 2 # # 3 # #。还阐述了反序列化的递归算法逻辑,即根据字符串元素情况生成树的结点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Google:

Given the root to a binary tree, implement serialize(root), 

which serialize the tree into a string, and deserialize(s), which deserialize the string back into the tree.

For example, given the following Node class

class Node:
    def __int__(self, val, left=None, right=None)
        self.val = val
        self.left = left
        self.right = right

The following test should pass:

node = Node('root', Node('left', Node('left.left')), Node('right'))

assert deserialize(serialize(node)).left.left.val == 'left.left' 

分析:所有的二叉树的题,都要利用递归的思想来解。

这个题难就难在如何巧妙的找到二叉树正确的序列化表示。

栈/函数调用 ,二叉树 -->递归, 想到这里,我不由得想到了计算器。计算器输入的其实就是一串字符串,然后输出结果,对于复杂的结合律,不就是通过栈/树来解决的吗?那这里为什么不能沿用它的思想呢?

树的两个左右子树不就是操作符的两个操作数吗?

对于以下的这颗树:

 

用()表示结点的子树,空格表示元素之间的分隔,那么,用 1 (2  () ())  (3 () ()), 我们完全可以用这种表示来表达一个树。为了简化起见,我们将空的子树()转化成 #, 那么二叉树就被简化成 1 2 # # 3 # #. 

好,那如何重新变成二叉树呢?

1 2 # # 3 # #

deserialize同样需要递归,那么如何设计这个递归函数呢?输入是字符串,返回则是树的结点。

算法逻辑:

对于该字符串,如果找到的第一个元素是#, 直接返回空,并将字符串关于#的那部分裁掉。若不是#,则新建一个结点,将元素的值存储到这个结点上,并对剩余的字符串递归调用生成该结点的左子树和右子树。

同样,代码附上,以供参考:

#include <iostream>
#include <string>

class BinaryTree
{
public:
    BinaryTree(std::string val, BinaryTree *left = nullptr, BinaryTree *right = nullptr)
    {
        this->val = val;
        this->left = left;
        this->right = right;
    }
    ~BinaryTree()
    {
        delete this->left;
        delete this->right;
    }
    
    std::string serialize()
    {
        std::string retVal = this->val;
        retVal += this->left ? (" " + this->left->serialize()) : " #";
        retVal += this->right ? (" " + this->right->serialize()) : " #";
        return retVal;
    }

    BinaryTree* deserialize(std::string& val)
    {
        if(val.empty())
            return nullptr;
        BinaryTree *retVal = new BinaryTree("");

        int pos = 0;
        pos = val.find_first_of(" ", pos);
        std::string element = val.substr(0, pos);
        val = val.substr(pos+1, val.length() -pos -1);

        if(element == "#")
            return nullptr;
        retVal->val = element;

        retVal->left = deserialize(val);
        retVal->right = deserialize(val);

        return retVal;
    }

private:
    std::string val;
    BinaryTree* left = nullptr;
    BinaryTree* right = nullptr;
}; 

int main()
{
    BinaryTree *biTree = new BinaryTree("1", new BinaryTree("2"), new BinaryTree("3"));
    std::string encodedBinaryTree = biTree->serialize();
    std::cout << "serialize: " + encodedBinaryTree << std::endl;
    BinaryTree * deBiTree = biTree->deserialize(encodedBinaryTree);
    std::cout << "serialize deserialized: " + deBiTree->serialize() << std::endl;

    delete biTree;
    delete deBiTree;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值