Want to save binary tree to disk for “20 questions” game

后端 未结 8 2026

In short, I\'d like to learn/develop an elegant method to save a binary tree to disk (a general tree, not necessarily a BST). Here is the description of my problem:

I\'

8条回答
  •  青春惊慌失措
    2021-02-06 15:33

    Here is the C++ code using PreOrder DFS:

    void SaveBinaryTreeToStream(TreeNode* root, ostringstream& oss)
    {
        if (!root)
        {
            oss << '#';
            return;
        }
    
        oss << root->data;
        SaveBinaryTreeToStream(root->left, oss);
        SaveBinaryTreeToStream(root->right, oss);
    }
    TreeNode* LoadBinaryTreeFromStream(istringstream& iss)
    {
        if (iss.eof())
            return NULL;
    
        char c;
        if ('#' == (c = iss.get()))
            return NULL;
    
        TreeNode* root = new TreeNode(c, NULL, NULL);
        root->left  = LoadBinaryTreeFromStream(iss);
        root->right = LoadBinaryTreeFromStream(iss);
    
        return root;
    }
    

    In main(), you can do:

    ostringstream oss;
    root = MakeCharTree();
    PrintVTree(root);
    SaveBinaryTreeToStream(root, oss);
    ClearTree(root);
    cout << oss.str() << endl;
    istringstream iss(oss.str());
    cout << iss.str() << endl;
    root = LoadBinaryTreeFromStream(iss);
    PrintVTree(root);
    ClearTree(root);
    
    /* Output:
                   A
    
           B               C
    
       D               E       F
    
         G           H   I
    ABD#G###CEH##I##F##
    ABD#G###CEH##I##F##
                   A
    
           B               C
    
       D               E       F
    
         G           H   I
     */
    

    The DFS is easier to understand.

    *********************************************************************************
    

    But we can use level scan BFS using a queue

    ostringstream SaveBinaryTreeToStream_BFS(TreeNode* root)
    {
        ostringstream oss;
    
        if (!root)
            return oss;
    
        queue q;
        q.push(root);
    
        while (!q.empty())
        {
            TreeNode* tn = q.front(); q.pop();
    
            if (tn)
            {
                q.push(tn->left);
                q.push(tn->right);
                oss << tn->data;
            }
            else
            {
                oss << '#';
            }
        }
    
        return oss;
    }
    TreeNode* LoadBinaryTreeFromStream_BFS(istringstream& iss)
    {
        if (iss.eof())
            return NULL;
    
        TreeNode* root = new TreeNode(iss.get(), NULL, NULL);
        queue q; q.push(root); // The parents from upper level
        while (!iss.eof() && !q.empty())
        {
            TreeNode* tn = q.front(); q.pop();
    
            char c = iss.get();
            if ('#' == c)
                tn->left = NULL;
            else
                q.push(tn->left = new TreeNode(c, NULL, NULL));
    
            c = iss.get();
            if ('#' == c)
                tn->right = NULL;
            else
                q.push(tn->right = new TreeNode(c, NULL, NULL));
        }
    
        return root;
    }
    

    In main(), you can do:

    root = MakeCharTree();
    PrintVTree(root);
    ostringstream oss = SaveBinaryTreeToStream_BFS(root);
    ClearTree(root);
    cout << oss.str() << endl;
    istringstream iss(oss.str());
    cout << iss.str() << endl;
    root = LoadBinaryTreeFromStream_BFS(iss);
    PrintVTree(root);
    ClearTree(root);
    
    /* Output:
                   A
    
           B               C
    
       D               E       F
    
         G           H   I
    ABCD#EF#GHI########
    ABCD#EF#GHI########
                   A
    
           B               C
    
       D               E       F
    
         G           H   I
     */
    

提交回复
热议问题