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)
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