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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy