Serialize and Deserialize Binary Tree

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

For example, you may serialize the following tree

    1
   / \
  2   3
     / \
    4   5

as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.

 

Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

 

#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <queue>
#include <stdio.h>
#include <cstdlib>

using namespace std;

struct TreeNode {
        int val;
        TreeNode *left;
        TreeNode *right;
        TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

/*
 * 自定义的字符串格式为123#345#
 * 通过#来分割
 * */
class MyString {
private:
    const string delimiter = "#";
    string words;
    int index;
public:
    MyString():words(""),index(0) {}

    string _covert_to_string(int i) {
        char c[8];
        snprintf(c,7, "%d", i);
        return static_cast<string>(c);
    }

    void add_word(int word) {

        if (word != INT_MAX) {
            string s_word = _covert_to_string(word);
            words.append(s_word);
        } else {
            words.append("NULL");
        }
        words.append(delimiter);
    }

    string get_string() {
        return words;
    }

    void set_string(string s) {
        words = s;
    }
    int get_next_word() {
        string res = "";
        if (words[index]== '\0') {
            return INT_MAX;
        }
        while (words[index] != '#') {
            res += words[index];
            index++;
        }
        index++;
        if (res == "NULL") {
            return INT_MAX;
        } else {
            return atoi(res.c_str());
        }
    }
};

class Codec {
public:

    // Encodes a tree to a single string.
    //采用层次遍历来序列化
    string serialize(TreeNode* root) {
        MyString res;
        if (root == NULL) {
            return res.get_string();
        }
        queue<TreeNode*> q_node;
        q_node.push(root);
        while(!q_node.empty()) {
            TreeNode* tmp = q_node.front();
            q_node.pop();
            if (NULL != tmp) {
                res.add_word(tmp->val);
                q_node.push(tmp->left == NULL ? NULL : tmp->left);
                q_node.push(tmp->right == NULL ? NULL : tmp->right);
            } else {
                res.add_word(INT_MAX);
            }
        }
        return res.get_string();
    }

    // Decodes your encoded data to tree.
    //采取广度优先来反序列化
    TreeNode* deserialize(string data) {
        if (data.empty()) {
            return NULL;
        }
        MyString mys;
        mys.set_string(data);
        int i_word;
        i_word = mys.get_next_word();
        TreeNode* root = new TreeNode(i_word);
        queue<TreeNode*> q_node;
        q_node.push(root);
        while (!q_node.empty()) {
            TreeNode* tmp_fater = q_node.front();
            q_node.pop();
            //获取左孩子,如果左孩子不为空,就将左孩子节点放入queue中
            i_word = mys.get_next_word();
            if (INT_MAX != i_word) {
                TreeNode* tmp_left = new TreeNode(i_word);
                tmp_fater->left = tmp_left;
                q_node.push(tmp_left);
            }
            //获取右孩子
            i_word = mys.get_next_word();
            if (INT_MAX != i_word) {
                TreeNode* tmp_right = new TreeNode(i_word);
                tmp_fater->right = tmp_right;
                q_node.push(tmp_right);
            }
        }
        return root;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));

int main() {

    TreeNode* root = new TreeNode(3);
    root->left = new TreeNode(2);
    root->right = new TreeNode(5);
    Codec cc;
    string s1 = cc.serialize(root);
    cout << s1 << endl;
    TreeNode* res = cc.deserialize(s1);
    cout << res->val << endl;
    cout << res->left->val << endl;
    cout << res->right->val << endl;
}

 

posted on 2016-02-22 15:48  walkwalkwalk  阅读(179)  评论(0编辑  收藏  举报

导航