1. 程式人生 > >LintCode 7 二叉樹的序列化和反序列化

LintCode 7 二叉樹的序列化和反序列化

題目:serialize and deserialize

要求:

設計一個演算法,並編寫程式碼來序列化和反序列化二叉樹。將樹寫入一個檔案被稱為“序列化”,讀取檔案後重建同樣的二叉樹被稱為“反序列化”。
如何反序列化或序列化二叉樹是沒有限制的,你只需要確保可以將二叉樹序列化為一個字串,並且可以將字串反序列化為原來的樹結構。

樣例:

給出一個測試資料樣例, 二叉樹{3,9,20,#,#,15,7},表示如下的樹結構:

  3
 / \
9  20
  /  \
 15   7

輸入{1,#,2}
輸出{1,#,2}

演算法要求:

解題思路:

需要了解什麼是二叉樹,其序列化和反序列化是什麼。這道題的序列化和反序列化都是用先序遍歷來進行的。首先,我們需要解析字串,提取出有用的部分,存在vector
容器中,再利用create函式進行遞迴建立二叉樹。 本題的難點在於,解析字串和輸出字串的處理。

演算法如下:


public:
    string serialize(TreeNode *root) {//反序列化
        stringstream data;
        data << "{";
        data << serialize2(root);
        data << "}";
        string temp = data.str();
        string::iterator itStr;
        itStr = temp.end();
        itStr-=2
; //去除結尾多餘的,和# while (itStr != temp.begin()) { if (*itStr == '#') { temp.erase(itStr); } else if (*itStr == ',') { temp.erase(itStr); } else { break; } itStr--; } return
temp; } TreeNode *deserialize(string data) {//序列化 if (data.size() == 2) { return NULL; } int start = data.find('{', 0); int end = data.find(',', 0); nums.clear();//清空容器 string tempStr = data.substr(start + 1, end - start - 1); //如果沒有找到,相當於到了最後一個數,(start + 1)為數字位置,(data.size()- start - 2)為數字長度 if (end == -1) { tempStr = data.substr(start + 1, data.size()- start - 2); } else { tempStr = data.substr(start + 1, end - start - 1); } nums.push_back(tempStr); while (end != -1) { start = end; end = data.find(',', start+1); //如果沒有找到,相當於到了最後一個數,(start + 1)為數字位置,(data.size()- start - 2)為數字長度 if (end == -1) { tempStr = data.substr(start + 1, data.size()- start - 2); } else { tempStr = data.substr(start + 1, end - start - 1); } nums.push_back(tempStr); } it = nums.begin(); TreeNode *root = creat(root); return root; } private: vector<string> nums; vector<string>::iterator it; string serialize2(TreeNode *root) {//遞迴先序遍歷,並返回字串 // write your code here stringstream data;//此為字串流,用法語cout,cin相似,集二者為一體,在這裡用是為了方便操作 if (root == NULL) { data << "#,"; return data.str(); } data << root->val << ','; data << serialize2(root->left); data << serialize2(root->right); return data.str(); } int stoi(string str) {//字串轉化為整型 int num; stringstream ss;//此為字串流,用法語cout,cin相似,集二者為一體,在這裡用是為了整型轉換 ss << *it; ss >> num; return num; } TreeNode *creat(TreeNode *bt) {//先序遍歷,遞迴建立 if (it == nums.end()) {//因為序列化需要將多餘的#省略,所以如果字串結束,那麼代表後面全是空結點。 return NULL; } if (*it == "#") { it++; return NULL; } else { bt = new TreeNode(stoi(*it)); it++; bt->left = creat(bt->left); bt->right = creat(bt->right); return bt; } }