forked from MaskRay/LeetCode
-
Notifications
You must be signed in to change notification settings - Fork 1
/
serialize-and-deserialize-binary-tree.cc
101 lines (99 loc) · 2.2 KB
/
serialize-and-deserialize-binary-tree.cc
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
// Serialize and Deserialize Binary Tree
class Codec {
void encode(TreeNode *x, string &s) {
if (! x)
s += ".,";
else {
s += to_string(x->val)+",";
encode(x->left, s);
encode(x->right, s);
}
}
TreeNode *decode(istringstream &ss) {
string t;
getline(ss, t, ',');
if (t == ".")
return NULL;
auto r = new TreeNode(stoi(t));
r->left = decode(ss);
r->right = decode(ss);
return r;
}
public:
string serialize(TreeNode* root) {
string s;
encode(root, s);
return s;
}
TreeNode* deserialize(string data) {
istringstream ss(data);
return decode(ss);
}
};
/// O(1) extra space, Morris pre-order traversal + edge crawling (resembling Schorr-Waite graph marking algorithm)
class Codec {
int tag(TreeNode *x) {
return ptrdiff_t(x) & 3;
}
TreeNode *pointer(TreeNode *x) {
return (TreeNode *)(ptrdiff_t(x) & -4);
}
public:
string serialize(TreeNode *x) {
string s;
while (x) {
auto y = x->left;
if (y) {
while (y->right && y->right != x)
y = y->right;
if (y->right == x) {
y->right = NULL;
s += ".,";
} else {
s += to_string(x->val)+",";
y->right = x;
x = x->left;
continue;
}
} else
s += to_string(x->val)+",.,";
x = x->right;
}
s += ".,";
return s;
}
TreeNode* deserialize(string data) {
istringstream ss(data);
string t;
getline(ss, t, ',');
if (t == ".")
return NULL;
TreeNode *x = new TreeNode(stoi(t)), *y, *p = NULL;
for(;;) {
int xt = tag(x);
auto xp = pointer(x);
if (xt < 2) {
x = (TreeNode *)(ptrdiff_t(xp) | xt+1);
getline(ss, t, ',');
y = t == "." ? NULL : new TreeNode(stoi(t));
if (y) {
(xt ? xp->right : xp->left) = p;
p = x;
x = y;
} else
(xt ? xp->right : xp->left) = NULL;
} else {
x = pointer(x);
if (! p) break;
y = x;
x = p;
xp = pointer(x);
if (tag(x) == 1)
p = xp->left, xp->left = y;
else
p = xp->right, xp->right = y;
}
}
return x;
}
};