C++中N元樹的序列化和反序列化


假設我們有一棵N元樹,我們需要對其進行序列化和反序列化。眾所周知,序列化是將資料結構或物件轉換為一系列位元的過程,以便我們可以將其儲存在檔案或記憶體緩衝區中,並在以後在相同或不同的計算機環境中重建它。

這裡我們需要設計一個演算法來序列化和反序列化N元樹。N元樹是一棵根樹,其中每個節點最多有N個子節點。

因此,如果輸入如下所示:

則輸出將是序列化:1 #3 2 4 #5 6 ##### 反序列化樹:1[3[5, 6, ], 2, 4, ]

為了解決這個問題,我們將遵循以下步驟:

  • 定義一個函式`createVector()`,它將接收s作為引數。

  • 定義一個二維陣列`ret`

  • 定義一個數組`tempv`

  • `temp :=`空字串

  • 從`i := 0`開始迴圈,當`i < s`的長度時,更新(將i加1),執行:

    • 如果`s[i]`不等於空格並且`s[i]`不等於'#',則:

      • `temp := temp + s[i]`

    • 否則,如果`s[i]`等於空格,則:

      • 將`temp`轉換為整數,並將其新增到`tempv`的末尾。

      • `temp :=`空字串

    • 否則,如果`s[i]`等於'#',則:

      • 將`tempv`新增到`ret`的末尾。

      • `temp :=`空字串

      • 清空`tempv`。

  • 當`ret`不為空且`ret`的最後一個元素等於0時,執行:

    • 從`ret`中刪除最後一個元素。

  • 返回`ret`。

  • 定義一個函式`serialize()`,它將接收根節點作為引數。

  • `ret :=`空字串

  • 如果根節點不為空,則:

    • 返回`ret`。

  • 定義一個佇列`q`。

  • 將根節點插入到`q`中。

  • `rret := ret`連線根節點的值。

  • `ret := ret`連線空格。

  • `ret := ret`連線"#"

  • 當`q`不為空時,執行:

    • `curr = q`的第一個元素。

    • 從`q`中刪除元素。

    • 從`i := 0`開始迴圈,當`i < curr`的子節點陣列的大小時,更新(將i加1),執行:

      • 如果`curr`的`children[i]`存在,則:

        • `ret := ret`連線`curr`的`children[i]`。

        • 將`curr`的`children[i]`插入到`q`中。

      • `ret := ret +`空格

    • `ret := ret`連線"#"

  • 返回`ret`。

  • 定義一個函式`deserialize()`,它將接收資料作為引數。

  • 如果資料的長度等於0,則:

    • 返回`null`。

  • 定義一個二維陣列`v := createVector(data)`。

  • `ret :=`一個值為`v[0, 0]`的新節點。

  • 定義一個佇列`q`。

  • 將`ret`插入到`q`中。

  • `i := 1`

  • 當`q`不為空且`i − v`的長度時,執行:

    • `curr = q`的第一個元素。

    • 從`q`中刪除元素。

    • 從`j := 0`開始迴圈,當`j − v[i]`的長度時,更新(將j加1),執行:

      • `node := v[i, j]`

      • `temp =`一個值為`node`的新節點。

      • 將`temp`新增到`curr`的子節點的末尾。

      • 將`temp`插入到`q`中。

    • 將`i`加1。

  • 返回`ret`。

示例

讓我們看看下面的實現,以便更好地理解:

線上演示

#include <bits/stdc++.h>
using namespace std;
class Node {
public:
   int val;
   vector<Node*> children;
   Node() {}
   Node(int _val) {
      val = _val;
   }
   Node(int _val, vector<Node*> _children) {
      val = _val;
      children = _children;
   }
};
string n_ary_to_str(Node *root){
   string ret = "";
   if(root){
      ret = ret + to_string(root->val);
      if(root->children.size() > 0){
         ret += "[";
         for(Node* child : root->children){
            ret += n_ary_to_str(child) + ", ";
         }
         ret += "]";
      }
   }
   return ret;
}
class Codec {
public:
   vector<vector<int>>createVector(string s) {
      vector<vector<int>> ret;
      vector<int> tempv;
      string temp = "";
      for (int i = 0; i < s.size(); i++) {
         if (s[i] != ' ' && s[i] != '#') {
            temp += s[i];
         }
         else if (s[i] == ' ') {
            tempv.push_back(stoi(temp));
            temp = "";
         }
         else if (s[i] == '#') {
            ret.push_back(tempv);
            temp = "";
            tempv.clear();
         }
      }
      while (!ret.empty() && ret.back().size() == 0)
      ret.pop_back();
      return ret;
   }
   string serialize(Node *root) {
      string ret = "";
      if (!root)
         return ret;
      queue<Node *> q;
      q.push(root);
      ret += to_string(root->val);
      ret += " ";
      ret += "#";
      while (!q.empty()) {
         Node *curr = q.front();
         q.pop();
         for (int i = 0; i < curr->children.size(); i++) {
            if (curr->children[i]) {
               ret += to_string(curr->children[i]->val);
               q.push(curr->children[i]);
            }
            ret += " ";
         }
         ret += "#";
      }
      return ret;
   }
   Node *deserialize(string data) {
      Node *ret;
      if (data.size() == 0)
         return NULL;
         vector<vector<int>> v = createVector(data);
         ret = new Node(v[0][0]);
         queue<Node *> q;
         q.push(ret);
         int i = 1;
         while (!q.empty() && i < v.size()) {
            Node *curr = q.front();
            q.pop();
            for (int j = 0; j < v[i].size(); j++) {
               int node = v[i][j];
                  Node *temp = new Node(node);
                  curr->children.push_back(temp);
                  q.push(temp);
               }
               i++;
            }
            return ret;
         }
 };
main() {
   Codec ob;
   Node n5(5), n6(6);
   Node n3(3); n3.children.push_back(&n5); n3.children.push_back(&n6);
   Node n2(2), n4(4);
   Node n1(1); n1.children.push_back(&n3); n1.children.push_back(&n2);
   n1.children.push_back(&n4);
   cout << "Given Tree: " << n_ary_to_str(&n1) << endl;
   string ser = ob.serialize(&n1);
   cout << "Serialize: " << ser << endl;
   Node *deser = ob.deserialize(ser);
   cout << "Deserialized Tree: " << n_ary_to_str(deser);
}

輸入

Node n5(5), n6(6);
Node n3(3); n3.children.push_back(&n5); n3.children.push_back(&n6);
Node n2(2), n4(4);
Node n1(1); n1.children.push_back(&n3); n1.children.push_back(&n2);
n1.children.push_back(&n4);

輸出

Given Tree: 1[3[5, 6, ], 2, 4, ]
Serialize: 1 #3 2 4 #5 6 #####
Deserialized Tree: 1[3[5, 6, ], 2, 4, ]

更新於:2020年7月21日

341 次瀏覽

開啟你的職業生涯

透過完成課程獲得認證

開始學習
廣告
© . All rights reserved.