-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path37_Serialize_Tree.cpp
More file actions
237 lines (179 loc) · 5.04 KB
/
37_Serialize_Tree.cpp
File metadata and controls
237 lines (179 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
//
// Created by mark on 2019/7/18.
// Copyright © 2019年 mark. All rights reserved.
//
/*
说明:
1. 问题:37.序列化,和反序列化二叉树。(序列化指的是将一棵二叉树保存到文件中,反序列化就是从文件中读取二叉树结点值重构原来的二叉树)。
2. 思路:选择合适的遍历算法,然后进行字符串和整数的转换,把文件中字符生成树;或者把树存储到文件中。
*/
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <assert.h>
#include <cstdio>
#include <fstream>
using namespace std;
struct BinaryTreeNode
{
int val;
struct BinaryTreeNode *left;
struct BinaryTreeNode *right;
};
// --------------------------------------------------------------------------
// 序列化,先序遍历二叉树,然后写入文件
void Serialize(BinaryTreeNode* root, ostream& stream)
{
if(root == nullptr)
{
stream << "$,";
return;
}
stream << root->val << ",";
Serialize(root->left, stream);
Serialize(root->right, stream);
}
// 反序列化,从文件中读取,然后生成二叉树
// ReadStream每次从流中读出一个字符,是数字返回true,$返回false
bool ReadStream(istream& stream, int* number)
{
if(stream.eof())
return false;
char buffer[32];
buffer[0] = '\0';
char ch;
stream >> ch;
int i = 0;
while(!stream.eof() && ch != ',') // 不断读入
{
buffer[i++] = ch;
stream >> ch;
}
bool isNumeric = false;
if(i > 0 && buffer[0] != '$')
{
*number = atoi(buffer);
isNumeric = true;
}
return isNumeric;
}
// 反序列化
void DeSerialize(BinaryTreeNode** pRoot, istream& stream)
{
int number;
if(ReadStream(stream, &number))
{
*pRoot = new BinaryTreeNode();
(*pRoot)->val = number;
(*pRoot)->left = nullptr;
(*pRoot)->right = nullptr;
DeSerialize(&(*pRoot)->left, stream);
DeSerialize(&(*pRoot)->right, stream);
}
}
//辅助函数 ------------------------------------------------------------------------------------------------------------------------
// 构建树节点
BinaryTreeNode* CreateTreeNode(int val)
{
BinaryTreeNode* pNode = new BinaryTreeNode();
pNode->val = val;
pNode->left = nullptr;
pNode->right = nullptr;
return pNode;
}
// 连接树节点
void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
{
if(pParent != nullptr)
{
pParent->left = pLeft;
pParent->right = pRight;
}
}
// 销毁树
void DestroyTree(BinaryTreeNode* root)
{
if(root != nullptr)
{
BinaryTreeNode* left = root->left;
BinaryTreeNode* right = root->right;
delete root;
root = nullptr;
DestroyTree(left);
DestroyTree(right);
}
}
// 先序打印树
void PrintPreOrder(BinaryTreeNode* root)
{
if(root == nullptr)
return;
cout << root->val << " ";
PrintPreOrder(root->left);
PrintPreOrder(root->right);
}
//测试函数 ------------------------------------------------------------------------------------------------------------------------
// 序列化测试函数
char* test_Serialize(BinaryTreeNode* root)
{
// 序列化
char* filename = "text.txt";
ofstream fileOut;
fileOut.open(filename);
Serialize(root, fileOut);
fileOut.close();
return filename;
}
// 打印序列化之后,文件的内容
void print_SerializeFile(char* filename)
{
ifstream fileIn1;
char ch;
fileIn1.open(filename);
while(!fileIn1.eof())
{
fileIn1 >> ch;
cout << ch;
}
fileIn1.close();
cout << endl;
}
// 反序列化,从文件中生成二叉树
BinaryTreeNode* test_DeSerialize(char* filename) // 传入文件名
{
ifstream fileIn;
fileIn.open(filename);
BinaryTreeNode* pNewRoot = nullptr;
DeSerialize(&pNewRoot, fileIn);
fileIn.close();
return pNewRoot;
}
int main(){
// 8
// 6 10
// 5 7 9 11
BinaryTreeNode* pNode8 = CreateTreeNode(8);
BinaryTreeNode* pNode6 = CreateTreeNode(6);
BinaryTreeNode* pNode10 = CreateTreeNode(10);
BinaryTreeNode* pNode5 = CreateTreeNode(5);
BinaryTreeNode* pNode7 = CreateTreeNode(7);
BinaryTreeNode* pNode9 = CreateTreeNode(9);
BinaryTreeNode* pNode11 = CreateTreeNode(11);
ConnectTreeNodes(pNode8, pNode6, pNode10);
ConnectTreeNodes(pNode6, pNode5, pNode7);
ConnectTreeNodes(pNode10, pNode9, pNode11);
// 测试序列化
char* filename = test_Serialize(pNode8);
// 打印序列化之后文件的内容
cout << "序列化文件为:";
print_SerializeFile(filename);
// 反序列化二叉树文件
BinaryTreeNode* pNewRoot = test_DeSerialize(filename);
cout << "反序列化打印:";
PrintPreOrder(pNewRoot);
cout << endl;
return 0;
}