Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 88cf82c

Browse files
Construct binary tree from order traversal
Signed-off-by: Leo Ma <begeekmyfriend@gmail.com>
1 parent 466fade commit 88cf82c

File tree

4 files changed

+398
-0
lines changed

4 files changed

+398
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
all:
2+
gcc -O2 -o test binary_tree_build.c
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
struct hlist_node;
5+
6+
struct hlist_head {
7+
struct hlist_node *first;
8+
};
9+
10+
struct hlist_node {
11+
struct hlist_node *next, **pprev;
12+
};
13+
14+
static inline void INIT_HLIST_HEAD(struct hlist_head *h) {
15+
h->first = NULL;
16+
}
17+
18+
static inline void INIT_HLIST_NODE(struct hlist_node *n) {
19+
n->next = NULL;
20+
n->pprev = NULL;
21+
}
22+
23+
static inline int hlist_empty(struct hlist_head *h) {
24+
return !h->first;
25+
}
26+
27+
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
28+
{
29+
if (h->first != NULL) {
30+
h->first->pprev = &n->next;
31+
}
32+
n->next = h->first;
33+
n->pprev = &h->first;
34+
h->first = n;
35+
}
36+
37+
static inline void hlist_del(struct hlist_node *n)
38+
{
39+
struct hlist_node *next = n->next;
40+
struct hlist_node **pprev = n->pprev;
41+
*pprev = next;
42+
if (next != NULL) {
43+
next->pprev = pprev;
44+
}
45+
}
46+
47+
#define container_of(ptr, type, member) \
48+
((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))
49+
50+
#define list_entry(ptr, type, member) \
51+
container_of(ptr, type, member)
52+
53+
#define hlist_for_each(pos, head) \
54+
for (pos = (head)->first; pos; pos = pos->next)
55+
56+
struct TreeNode {
57+
int val;
58+
struct TreeNode *left;
59+
struct TreeNode *right;
60+
};
61+
62+
struct order_node {
63+
struct hlist_node node;
64+
int val;
65+
int index;
66+
};
67+
68+
static int find(int num, int size, struct hlist_head *heads)
69+
{
70+
struct hlist_node *p;
71+
int hash = (num < 0 ? -num : num) % size;
72+
hlist_for_each(p, &heads[hash]) {
73+
struct order_node *on = list_entry(p, struct order_node, node);
74+
if (num == on->val) {
75+
return on->index;
76+
}
77+
}
78+
return -1;
79+
}
80+
81+
static struct TreeNode *node_new(int val)
82+
{
83+
struct TreeNode *tn = malloc(sizeof(*tn));
84+
tn->val = val;
85+
tn->left = NULL;
86+
tn->right = NULL;
87+
return tn;
88+
}
89+
90+
static struct TreeNode *recursive(int *preorder, int pre_low, int pre_high,
91+
int *inorder, int in_low, int in_high,
92+
struct hlist_head *in_heads, int size)
93+
{
94+
if (in_low > in_high || pre_low > pre_high) {
95+
return NULL;
96+
}
97+
struct TreeNode *tn = malloc(sizeof(*tn));
98+
tn->val = preorder[pre_low];
99+
int index = find(preorder[pre_low], size, in_heads);
100+
tn->left = recursive(preorder, pre_low + 1, pre_low + (index - in_low), inorder, in_low, index - 1, in_heads, size);
101+
tn->right = recursive(preorder, pre_high - (in_high - index - 1), pre_high, inorder, index + 1, in_high, in_heads, size);
102+
return tn;
103+
}
104+
105+
static void node_add(int val, int index, int size, struct hlist_head *heads)
106+
{
107+
struct order_node *on = malloc(sizeof(*on));
108+
on->val = val;
109+
on->index = index;
110+
int hash = (val < 0 ? -val : val) % size;
111+
hlist_add_head(&on->node, &heads[hash]);
112+
}
113+
114+
static struct TreeNode *buildTree(int *preorder, int preorderSize, int *inorder, int inorderSize)
115+
{
116+
int i, j;
117+
struct hlist_head *in_heads = malloc(inorderSize * sizeof(*in_heads));
118+
for (i = 0; i < inorderSize; i++) {
119+
INIT_HLIST_HEAD(&in_heads[i]);
120+
}
121+
for (i = 0; i < inorderSize; i++) {
122+
node_add(inorder[i], i, inorderSize, in_heads);
123+
}
124+
125+
#if 0
126+
struct hlist_head *pre_heads = malloc(preorderSize * sizeof(*pre_heads));
127+
for (i = 0; i < preorderSize; i++) {
128+
INIT_HLIST_HEAD(&pre_heads[i]);
129+
}
130+
for (i = 0; i < inorderSize; i++) {
131+
node_add(preorder[i], i, preorderSize, pre_heads);
132+
}
133+
134+
int last_index, level = 0;
135+
struct TreeNode **stack = malloc(preorderSize * sizeof(*stack));
136+
struct TreeNode *tn, *root = NULL;
137+
for (i = 0; i < preorderSize; i++) {
138+
if (i == 0) {
139+
tn = root = node_new(preorder[0]);
140+
last_index = find(preorder[0], inorderSize, in_heads);
141+
stack[level++] = root;
142+
} else {
143+
int index = find(preorder[i], inorderSize, in_heads);
144+
if (index < last_index) {
145+
tn->left = node_new(preorder[i]);
146+
tn = tn->left;
147+
} else {
148+
for (j = index - 1; j >= 0; j--) {
149+
if (find(inorder[j], preorderSize, pre_heads) < i) {
150+
break;
151+
}
152+
}
153+
/* find the parent of the right child */
154+
while (stack[--level]->val != inorder[j]) {}
155+
tn = stack[level++];
156+
tn->right = node_new(preorder[i]);
157+
tn = tn->right;
158+
}
159+
stack[level++] = tn;
160+
last_index = index;
161+
}
162+
}
163+
164+
return root;
165+
#else
166+
return recursive(preorder, 0, preorderSize - 1, inorder, 0, inorderSize - 1, in_heads, inorderSize);
167+
#endif
168+
}
169+
170+
static void dump(struct TreeNode *node)
171+
{
172+
if (node == NULL) {
173+
printf("# ");
174+
return;
175+
}
176+
printf("%d ", node->val);
177+
dump(node->left);
178+
dump(node->right);
179+
}
180+
181+
int main(void)
182+
{
183+
//int preorder[] = { 8,4,2,1,3,6,5,7,12,10,9,11,14,13,15 };
184+
//int inorder[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
185+
int preorder[] = { 7,-10,-4,3,-1,2,-8,11 };
186+
int inorder[] = { -4,-10,3,-1,7,11,-8,2 };
187+
//int preorder[] = { 3,2,1 };
188+
//int preorder[] = { 3,1,2 };
189+
//int preorder[] = { 2,1,3 };
190+
//int preorder[] = { 1,3,2 };
191+
//int preorder[] = { 1,2,3 };
192+
//int inorder[] = { 1,2,3 };
193+
int pre_size = sizeof(preorder) / sizeof(*preorder);
194+
int in_size = sizeof(inorder) / sizeof(*inorder);
195+
struct TreeNode *root = buildTree(preorder, pre_size, inorder, in_size);
196+
dump(root);
197+
printf("\n");
198+
return 0;
199+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
all:
2+
gcc -O2 -o test binary_tree_build.c

0 commit comments

Comments
 (0)