zoukankan      html  css  js  c++  java
  • 《剑指offer》第三十七题:序列化二叉树

    // 面试题37:序列化二叉树
    // 题目:请实现两个函数,分别用来序列化和反序列化二叉树。
    
    #include <cstdio>
    #include "BinaryTree.h"
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    void Serialize(const BinaryTreeNode* pRoot, ostream& stream)
    {
        if (pRoot == nullptr)
        {
            stream << "$,"; //这地方是双引号
            return;
        }
    
        stream << pRoot->m_nValue << ','; //当前节点值
        Serialize(pRoot->m_pLeft, stream);
        Serialize(pRoot->m_pRight, stream);
    }
    
    bool ReadStream(istream& stream, int* number)
    {
        if (stream.eof()) //序列到尾部
            return false;
    
        char buffer[32]; //缓存器, 存放一个节点的值
        buffer[0] = ''; //结尾
    
        char ch;
        stream >> ch;
        int i = 0; //读入的值长度
        while (!stream.eof() && ch != ',') //读入一个节点的值
        {
            buffer[i++] = ch;
            stream >> ch;
        }
    
        bool isNumeric = false;
        if (i > 0 && buffer[0] != '$') //整数字符串转为整数
        {
            *number = atoi(buffer);
            isNumeric = true;
        }
        return isNumeric;
    }
    
    void Deserialize(BinaryTreeNode** pRoot, istream& stream)
    {
        int number;
        if (ReadStream(stream, &number)) //数字为true, 字符为false
        {
            *pRoot = new BinaryTreeNode(); //为什么新建节点不能复制
            (*pRoot)->m_nValue = number;
            (*pRoot)->m_pLeft = nullptr;
            (*pRoot)->m_pRight = nullptr;
    
            Deserialize(&(*pRoot)->m_pLeft, stream);
            Deserialize(&(*pRoot)->m_pRight, stream);
        }
    }
    // ==================== Test Code ====================
    bool isSameTree(const BinaryTreeNode* pRoot1, const BinaryTreeNode* pRoot2)
    {
        if (pRoot1 == nullptr && pRoot2 == nullptr)
            return true;
    
        if (pRoot1 == nullptr || pRoot2 == nullptr)
            return false;
    
        if (pRoot1->m_nValue != pRoot2->m_nValue)
            return false;
    
        return isSameTree(pRoot1->m_pLeft, pRoot2->m_pLeft) &&
            isSameTree(pRoot1->m_pRight, pRoot2->m_pRight);
    }
    
    void Test(const char* testName, const BinaryTreeNode* pRoot)
    {
        if (testName != nullptr)
            printf("%s begins: 
    ", testName);
    
        PrintTree(pRoot);
    
        const char* fileName = "test.txt";
        ofstream fileOut;
        fileOut.open(fileName);
    
        Serialize(pRoot, fileOut);
        fileOut.close();
    
        // print the serialized file
        ifstream fileIn1;
        char ch;
        fileIn1.open(fileName);
        while (!fileIn1.eof())
        {
            fileIn1 >> ch;
            cout << ch;
        }
        fileIn1.close();
        cout << endl;
    
        ifstream fileIn2;
        fileIn2.open(fileName);
        BinaryTreeNode* pNewRoot = nullptr;
        Deserialize(&pNewRoot, fileIn2);
        fileIn2.close();
    
        PrintTree(pNewRoot);
    
        if (isSameTree(pRoot, pNewRoot))
            printf("The deserialized tree is same as the oritinal tree.
    
    ");
        else
            printf("The deserialized tree is NOT same as the oritinal tree.
    
    ");
    
        DestroyTree(pNewRoot);
    }
    
    //            8
    //        6      10
    //       5 7    9  11
    void Test1()
    {
        BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
        BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
        BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
        BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
        BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
        BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);
    
        ConnectTreeNodes(pNode8, pNode6, pNode10);
        ConnectTreeNodes(pNode6, pNode5, pNode7);
        ConnectTreeNodes(pNode10, pNode9, pNode11);
    
        Test("Test1", pNode8);
    
        DestroyTree(pNode8);
    }
    
    //            5
    //          4
    //        3
    //      2
    void Test2()
    {
        BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
        BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
        BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
    
        ConnectTreeNodes(pNode5, pNode4, nullptr);
        ConnectTreeNodes(pNode4, pNode3, nullptr);
        ConnectTreeNodes(pNode3, pNode2, nullptr);
    
        Test("Test2", pNode5);
    
        DestroyTree(pNode5);
    }
    
    //        5
    //         4
    //          3
    //           2
    void Test3()
    {
        BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
        BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
        BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
    
        ConnectTreeNodes(pNode5, nullptr, pNode4);
        ConnectTreeNodes(pNode4, nullptr, pNode3);
        ConnectTreeNodes(pNode3, nullptr, pNode2);
    
        Test("Test3", pNode5);
    
        DestroyTree(pNode5);
    }
    
    void Test4()
    {
        BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
    
        Test("Test4", pNode5);
    
        DestroyTree(pNode5);
    }
    
    void Test5()
    {
        Test("Test5", nullptr);
    }
    
    //        5
    //         5
    //          5
    //         5
    //        5
    //       5 5
    //      5   5
    void Test6()
    {
        BinaryTreeNode* pNode1 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode2 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode3 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode4 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode61 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode62 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode71 = CreateBinaryTreeNode(5);
        BinaryTreeNode* pNode72 = CreateBinaryTreeNode(5);
    
        ConnectTreeNodes(pNode1, nullptr, pNode2);
        ConnectTreeNodes(pNode2, nullptr, pNode3);
        ConnectTreeNodes(pNode3, pNode4, nullptr);
        ConnectTreeNodes(pNode4, pNode5, nullptr);
        ConnectTreeNodes(pNode5, pNode61, pNode62);
        ConnectTreeNodes(pNode61, pNode71, nullptr);
        ConnectTreeNodes(pNode62, nullptr, pNode72);
    
        Test("Test6", pNode1);
    
        DestroyTree(pNode1);
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
        Test6();
    
        return 0;
    }
    测试代码

    分析:前序遍历过程。


    牛客网这个题,一言难尽。数据结构还是要熟悉。

    /*
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
        TreeNode(int x) :
                val(x), left(NULL), right(NULL) {
        }
    };
    */
    typedef TreeNode* pNode;
    class Solution {
        pNode hahaha;
    public:
        char* Serialize(TreeNode *root) {    
            hahaha = root;
            return "(*^_^*)";
        }
        TreeNode* Deserialize(char *str) {
          return hahaha;
        }
    };
    1.O(1)复杂度
    /*
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
        TreeNode(int x) :
                val(x), left(NULL), right(NULL) {
        }
    };
    */
    class Solution {
        vector<int> buffer;
        void SerializeCore(TreeNode *root)
        {
            if (root == nullptr)
            {
                buffer.push_back(0x23333);
                return;
            }
            buffer.push_back(root->val);
            SerializeCore(root->left);
            SerializeCore(root->right);
        }
        TreeNode* DeserializeCore(int* &stream)
        {
            if (*stream == 0x23333)
            {
                ++stream;
                return nullptr;
            }
            TreeNode* res = new TreeNode(*stream);
            ++stream;
            res->left = DeserializeCore(stream);
            res->right = DeserializeCore(stream);
            return res;
        }
    public:
        char* Serialize(TreeNode *root) {    
            
            buffer.clear();
            SerializeCore(root);
            int* res = new int[buffer.size()];
            for (unsigned int i = 0; i < buffer.size(); ++i)
                res[i] = buffer[i];
            return (char*)res;
        }
        TreeNode* Deserialize(char *str) {
            
            int* stream = (int*) str;
            return DeserializeCore(stream);
        }
    };
    2.O(n)复杂度
  • 相关阅读:
    甲醛(Formaldehyde)
    Node Embedding
    受限玻尔兹曼机(RBM, Restricted Boltzmann machines)和深度信念网络(DBN, Deep Belief Networks)
    长尾分布,重尾分布(Heavy-tailed Distribution)
    SVD分解与数据压缩
    Batch Normailzation
    Attention Mechanism
    新装的Ubuntu在Nvidia显卡上分辨率不对
    人工神经网络(Artificial Neural Network)
    Xdebug+phpstorm配置
  • 原文地址:https://www.cnblogs.com/ZSY-blog/p/12609325.html
Copyright © 2011-2022 走看看