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

Commit f77f090

Browse files
bst level order traversal
Signed-off-by: begeekmyfriend <begeekmyfriend@gmail.com>
1 parent ebc3bcf commit f77f090

File tree

4 files changed

+447
-0
lines changed

4 files changed

+447
-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 bst_zigzag.c
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
#define BST_MAX_LEVEL 800
6+
7+
#define container_of(ptr, type, member) \
8+
((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))
9+
10+
#define list_entry(ptr, type, member) \
11+
container_of(ptr, type, member)
12+
13+
#define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field)
14+
#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field)
15+
16+
#define list_for_each(p, head) \
17+
for (p = (head)->next; p != (head); p = p->next)
18+
19+
#define list_for_each_reverse(p, head) \
20+
for (p = (head)->prev; p != (head); p = p->prev)
21+
22+
#define list_for_each_safe(p, n, head) \
23+
for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next)
24+
25+
#define list_for_each_safe_reverse(p, n, head) \
26+
for (p = (head)->prev, n = p->prev; p != (head); p = n, n = p->prev)
27+
28+
struct TreeNode {
29+
int val;
30+
struct TreeNode *left;
31+
struct TreeNode *right;
32+
};
33+
34+
struct list_head {
35+
struct list_head *next, *prev;
36+
};
37+
38+
static inline void INIT_LIST_HEAD(struct list_head *list)
39+
{
40+
list->next = list->prev = list;
41+
}
42+
43+
static inline int list_empty(const struct list_head *head)
44+
{
45+
return head->next == head;
46+
}
47+
48+
static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
49+
{
50+
next->prev = new;
51+
new->next = next;
52+
new->prev = prev;
53+
prev->next = new;
54+
}
55+
56+
static inline void list_add(struct list_head *_new, struct list_head *head)
57+
{
58+
__list_add(_new, head, head->next);
59+
}
60+
61+
static inline void list_add_tail(struct list_head *_new, struct list_head *head)
62+
{
63+
__list_add(_new, head->prev, head);
64+
}
65+
66+
static inline void __list_del(struct list_head *entry)
67+
{
68+
entry->next->prev = entry->prev;
69+
entry->prev->next = entry->next;
70+
}
71+
72+
static inline void list_del(struct list_head *entry)
73+
{
74+
__list_del(entry);
75+
entry->next = entry->prev = NULL;
76+
}
77+
78+
struct bfs_node {
79+
struct TreeNode *node;
80+
struct list_head link;
81+
};
82+
83+
static struct bfs_node *node_new(struct list_head *free_list, struct TreeNode *node)
84+
{
85+
struct bfs_node *new;
86+
if (list_empty(free_list)) {
87+
new = malloc(sizeof(*new));
88+
} else {
89+
new = list_first_entry(free_list, struct bfs_node, link);
90+
list_del(&new->link);
91+
}
92+
new->node = node;
93+
return new;
94+
}
95+
96+
static void queue(struct list_head *parents, struct list_head *children, int reverse,
97+
struct list_head *free_list, int **results, int *col_sizes, int level)
98+
{
99+
struct list_head *p, *n;
100+
struct bfs_node *new, *parent;
101+
102+
list_for_each(p, parents) {
103+
parent = list_entry(p, struct bfs_node, link);
104+
if (parent->node->left != NULL) {
105+
new = node_new(free_list, parent->node->left);
106+
list_add_tail(&new->link, children);
107+
}
108+
if (parent->node->right != NULL) {
109+
new = node_new(free_list, parent->node->right);
110+
list_add_tail(&new->link, children);
111+
}
112+
col_sizes[level]++;
113+
}
114+
115+
int i = 0;
116+
results[level] = malloc(col_sizes[level] * sizeof(int));
117+
if (reverse) {
118+
list_for_each_safe_reverse(p, n, parents) {
119+
parent = list_entry(p, struct bfs_node, link);
120+
results[level][i++] = parent->node->val;
121+
list_del(p);
122+
list_add(p, free_list);
123+
}
124+
} else {
125+
list_for_each_safe(p, n, parents) {
126+
parent = list_entry(p, struct bfs_node, link);
127+
results[level][i++] = parent->node->val;
128+
list_del(p);
129+
list_add(p, free_list);
130+
}
131+
}
132+
}
133+
134+
/**
135+
** Return an array of arrays of size *returnSize.
136+
** The sizes of the arrays are returned as *columnSizes array.
137+
** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
138+
**/
139+
static int** zigzagLevelOrder(struct TreeNode* root, int** columnSizes, int* returnSize)
140+
{
141+
if (root == NULL) {
142+
*returnSize = 0;
143+
return NULL;
144+
}
145+
146+
struct list_head free_list;
147+
struct list_head q0;
148+
struct list_head q1;
149+
INIT_LIST_HEAD(&free_list);
150+
INIT_LIST_HEAD(&q0);
151+
INIT_LIST_HEAD(&q1);
152+
153+
int **results = malloc(BST_MAX_LEVEL * sizeof(int *));
154+
*columnSizes = malloc(BST_MAX_LEVEL * sizeof(int));
155+
memset(*columnSizes, 0, BST_MAX_LEVEL * sizeof(int));
156+
157+
int level = 0;
158+
struct bfs_node *new = node_new(&free_list, root);
159+
list_add_tail(&new->link, &q0);
160+
161+
while (!list_empty(&q0) || !list_empty(&q1)) {
162+
if (level & 0x1) {
163+
queue(&q1, &q0, 1, &free_list, results, *columnSizes, level);
164+
} else {
165+
queue(&q0, &q1, 0, &free_list, results, *columnSizes, level);
166+
}
167+
level++;
168+
}
169+
170+
*returnSize = level;
171+
return results;
172+
}
173+
174+
int main(void)
175+
{
176+
#if 1
177+
struct TreeNode root;
178+
root.val = 3;
179+
180+
struct TreeNode node1[2];
181+
node1[0].val = 9;
182+
node1[1].val = 20;
183+
184+
struct TreeNode node2[4];
185+
node2[2].val = 15;
186+
node2[3].val = 7;
187+
188+
root.left = &node1[0];
189+
root.right = &node1[1];
190+
191+
node1[0].left = NULL;
192+
node1[0].right = NULL;
193+
node1[1].left = &node2[2];
194+
node1[1].right = &node2[3];
195+
#else
196+
struct TreeNode root;
197+
root.val = 1;
198+
199+
struct TreeNode node1[2];
200+
node1[0].val = 2;
201+
node1[1].val = 3;
202+
203+
struct TreeNode node2[4];
204+
node2[0].val = 4;
205+
node2[3].val = 5;
206+
207+
root.left = &node1[0];
208+
root.right = &node1[1];
209+
210+
node1[0].left = &node2[0];
211+
node1[0].right = NULL;
212+
node1[1].left = NULL;
213+
node1[1].right = &node2[3];
214+
#endif
215+
216+
node2[0].left = NULL;
217+
node2[0].right = NULL;
218+
node2[1].left = NULL;
219+
node2[1].right = NULL;
220+
node2[2].left = NULL;
221+
node2[2].right = NULL;
222+
node2[3].left = NULL;
223+
node2[3].right = NULL;
224+
225+
int i, j, count = 0, *col_sizes;
226+
int **lists = zigzagLevelOrder(&root, &col_sizes, &count);
227+
for (i = 0; i < count; i++) {
228+
for (j = 0; j < col_sizes[i]; j++) {
229+
printf("%d ", lists[i][j]);
230+
}
231+
printf("\n");
232+
}
233+
234+
return 0;
235+
}
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 bst_bfs.c

0 commit comments

Comments
 (0)