FlyingPenguin
Leaning. Thinking. Doing.

今天练习算法,在leetcode上做了一道练习,照着上面的分析写了下面的代码,编译执行也都没有问题,在这里写写。

这里采用二叉树的先序遍历方式作为序列化和反序列化的主要思路,对空的子树用'#'进行记录。

在序列化的时候,使用递归进行先序遍历,递归执行到空节点,则保存'#'并返回;否则记录当前节点的值,并继续对其左右节点进行遍历。

同样,在反序列化的时候,当前读到的值作为新子树的根节点root,下一个读到的节点则为root节点的左子树root->left,并将当前索引值的引用传入下一步的递归,直到读到'#'递归层层返回;因为递归调用传入了当前值的引用,所以递归返回到root时,下一个读到的值将会用来初始化root的右子树root->right。

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <fstream>
  4 #include <vector>
  5 #include <cstring>
  6 #include <vld.h>
  7 
  8 using namespace std;
  9 
 10 struct TreeNode
 11 {
 12     int i_val;
 13     TreeNode *p_left;
 14     TreeNode *p_right;
 15     TreeNode() : i_val(0), p_left(0), p_right(0) {}
 16     TreeNode(int val) : i_val(val), p_left(0), p_right(0) {}
 17     TreeNode(const TreeNode &treeNode) : i_val(treeNode.i_val), p_left(treeNode.p_left), p_right(treeNode.p_right) {}
 18     TreeNode &operator=(const TreeNode &treeNode)
 19     {
 20         if(this != &treeNode)
 21         {
 22             this->i_val = treeNode.i_val;
 23             this->p_left = treeNode.p_left;
 24             this->p_right = treeNode.p_right;
 25         }
 26         return *this;
 27     }
 28 };
 29 
 30 // 读到的字符是否是分隔符
 31 inline bool isToken(char c, string &token)
 32 {
 33     for(string::iterator it = token.begin(); it != token.end(); ++it)
 34     {
 35         if(c == (*it))
 36         {
 37             return true;
 38         }
 39     }
 40     return false;
 41 }
 42 
 43 // 读到的内容是否是数字
 44 inline bool isNumber(string &str)
 45 {
 46     if(str.size() == 0)
 47     {
 48         return false;
 49     }
 50     for(int i = 0; i < str.size(); ++i)
 51     {
 52         if(str[i] < '0' || str[i] > '9')
 53         {
 54             return false;
 55         }
 56     }
 57     return true;
 58 }
 59 
 60 // 字符串转数字
 61 int str2int(string &str)
 62 {
 63     int ret = 0;
 64     for(int i = 0; i < str.size(); ++i)
 65     {
 66         ret = ret * 10 + (str[i] - '0');
 67     }
 68     return ret;
 69 }
 70 
 71 // 从文件中读序列化后的内容
 72 // 这里读到的内容是
 73 // 30 10 50 # # # 20 45 # # 35 # #
 74 vector<string> readFile(ifstream &in, string &token)
 75 {
 76     if(!in.is_open())
 77     {
 78         cout << "Error during opening the file." << endl;
 79         exit(1);
 80     }
 81     char c;
 82     string word;
 83     vector<string> vec_Str;
 84     while(in.get(c))
 85     {
 86         if(!isToken(c, token))
 87         {
 88             word.push_back(c);
 89             continue;
 90         }
 91 
 92         if(word.length() > 0)
 93         {
 94             vec_Str.push_back(string(word.begin(), word.end()));
 95             word.clear();
 96         }
 97     }
 98     if(word.length() > 0)
 99     {
100         vec_Str.push_back(string(word.begin(), word.end()));
101     }
102 
103     return vec_Str;
104 }
105 
106 // 反序列化二叉树
107 TreeNode *DeserializeTree(int &cur, vector<string> &vec_SerialTree)
108 {
109     if(cur < 0 || cur >= vec_SerialTree.size() || vec_SerialTree.size() == 0 || !isNumber(vec_SerialTree[cur]))
110     {
111         return 0;
112     }
113     TreeNode *p_Node = new TreeNode(str2int(vec_SerialTree[cur]));
114     cur = cur + 1;
115     p_Node->p_left = DeserializeTree(cur, vec_SerialTree);
116     cur = cur + 1;
117     p_Node->p_right = DeserializeTree(cur, vec_SerialTree);
118 
119     return p_Node;
120 }
121 
122 // 序列化二叉树
123 void SerializeTree(TreeNode *p_Root, ostream &out)
124 {
125     if(!p_Root)
126     {
127         out << "# ";
128     }
129     else
130     {
131         out << p_Root->i_val << " ";
132         SerializeTree(p_Root->p_left, out);
133         SerializeTree(p_Root->p_right, out);
134     }
135 }
136 
137 // 释放资源
138 void DestroyTree(TreeNode **p_Root)
139 {
140     if(!p_Root || !(*p_Root))
141     {
142         return;
143     }
144     DestroyTree(&((*p_Root)->p_left));
145     DestroyTree(&((*p_Root)->p_right));
146     delete *p_Root;
147     p_Root = 0;
148 }
149 
150 int main()
151 {
152     string token(" ");
153     ifstream in("D:/Lab/clab/file/1.txt");
154     ofstream out("D:/Lab/clab/file/2.txt");
155 
156     vector<string> vec_SerialTree = readFile(in, token);
157 
158     int cur = 0;
159     TreeNode *p_Root = DeserializeTree(cur, vec_SerialTree);
160 
161     if(out)
162     {
163         SerializeTree(p_Root, out);
164     }
165 
166     DestroyTree(&p_Root);
167 
168     return 0;
169 }

 

posted on 2015-03-01 15:17  FlyingPenguin  阅读(266)  评论(0编辑  收藏  举报