Skip to content

Commit 0cf605d

Browse files
committed
improving tree_traversal.c
1 parent e82ed09 commit 0cf605d

File tree

2 files changed

+167
-119
lines changed

2 files changed

+167
-119
lines changed
Lines changed: 62 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,59 @@
1-
#include <stdio.h>
1+
#include "utility.h"
2+
3+
#include <stddef.h>
24
#include <stdlib.h>
3-
#include <string.h>
5+
#include <stdio.h>
46

5-
typedef struct node {
7+
struct node {
68
struct node *children;
7-
int children_num;
9+
size_t children_size;
810
int id;
9-
} node;
10-
11-
typedef struct node_list {
12-
node n;
13-
struct node_list *last_list, *next_list;
14-
} node_list;
15-
16-
typedef struct node_points {
17-
node_list *start_point, *end_point;
18-
} node_points;
19-
20-
void push(node_points *np, node n) {
21-
node_list *temp = (node_list*)malloc(sizeof(node_list));
22-
temp->n = n;
23-
temp->last_list = temp->next_list = NULL;
24-
25-
if (!np->end_point) {
26-
np->start_point = temp;
27-
} else {
28-
np->end_point->next_list = temp;
29-
temp->last_list = np->end_point;
30-
}
31-
32-
np->end_point = temp;
33-
}
11+
};
3412

35-
void stack_pop(node_points *np) {
36-
node_list *temp;
37-
temp = np->end_point;
13+
struct node create_tree(int rows, size_t num_children) {
14+
struct node n = {NULL, 0, rows};
3815

39-
if (temp) {
40-
np->end_point = temp->last_list;
41-
if (!np->end_point) {
42-
np->start_point = NULL;
16+
if (rows > 0) {
17+
n.children = (struct node*)malloc(num_children * sizeof(struct node));
18+
n.children_size = num_children;
19+
for (size_t i = 0; i < num_children; ++i) {
20+
n.children[i] = create_tree(rows - 1, num_children);
4321
}
44-
45-
free(temp);
4622
}
47-
}
48-
49-
void queue_pop(node_points *np) {
50-
node_list *temp;
51-
temp = np->start_point;
52-
if (temp) {
53-
np->start_point = temp->next_list;
54-
if (!np->start_point) {
55-
np->end_point = NULL;
56-
}
5723

58-
free(temp);
59-
}
24+
return n;
6025
}
6126

62-
void create_tree(node *n, int num_row, int num_child) {
63-
n->id = num_row;
64-
if (num_row == 0) {
65-
n->children_num = 0;
66-
return;
67-
}
27+
void destroy_tree(struct node n) {
28+
if (n.id > 0) {
29+
for (size_t i = 0; i < n.children_size; ++i) {
30+
destroy_tree(n.children[i]);
31+
}
6832

69-
n->children = (node *)malloc(num_child * sizeof(*n->children));
70-
n->children_num = num_child;
71-
for (int i = 0; i < num_child; ++i) {
72-
node child;
73-
create_tree(&child, num_row - 1, num_child);
74-
*(n->children + i) = child;
33+
free(n.children);
7534
}
7635
}
7736

78-
void dfs_recursive(node n) {
37+
void dfs_recursive(struct node n) {
7938
printf("%d\n", n.id);
80-
if (!n.children) {
81-
return;
82-
}
8339

84-
for (int i = 0; i < n.children_num; ++i) {
85-
dfs_recursive(n.children[i]);
40+
if (n.children) {
41+
for (size_t i = 0; i < n.children_size; ++i) {
42+
dfs_recursive(n.children[i]);
43+
}
8644
}
8745
}
8846

89-
void dfs_recursive_postorder(node n) {
90-
for (int i = 0; i < n.children_num; ++i) {
47+
void dfs_recursive_postorder(struct node n) {
48+
for (size_t i = 0; i < n.children_size; ++i) {
9149
dfs_recursive_postorder(n.children[i]);
9250
}
9351

9452
printf("%d\n", n.id);
9553
}
9654

97-
void dfs_recursive_inorder_btree(node n) {
98-
switch (n.children_num) {
55+
void dfs_recursive_inorder_btree(struct node n) {
56+
switch (n.children_size) {
9957
case 2:
10058
dfs_recursive_inorder_btree(n.children[0]);
10159
printf("%d\n", n.id);
@@ -114,65 +72,50 @@ void dfs_recursive_inorder_btree(node n) {
11472
}
11573
}
11674

117-
void dfs_stack(node n) {
118-
node_points stack;
119-
memset(&stack, 0, sizeof(node_points));
120-
push(&stack, n);
121-
node temp;
122-
123-
while (stack.start_point != NULL) {
124-
temp = stack.end_point->n;
125-
printf("%d\n", temp.id);
126-
stack_pop(&stack);
127-
for (int i = 0; i < temp.children_num; ++i) {
128-
if (!temp.children) {
129-
break;
130-
}
131-
132-
push(&stack, temp.children[i]);
75+
void dfs_stack(struct node n) {
76+
struct stack stk = get_stack(sizeof(struct node*));
77+
stack_push(&stk, &n);
78+
struct node *tmp;
79+
80+
while (!stack_empty(&stk)) {
81+
tmp = (struct node*)stack_pop(&stk);
82+
if (!tmp) {
83+
break;
13384
}
134-
}
135-
}
13685

137-
void bfs_queue(node n) {
138-
node_points queue;
139-
memset(&queue, 0, sizeof(node_points));
140-
push(&queue, n);
141-
node temp;
142-
143-
while (queue.start_point != NULL) {
144-
temp = queue.start_point->n;
145-
printf("%d\n", temp.id);
146-
queue_pop(&queue);
147-
for (int i = 0; i < temp.children_num; ++i) {
148-
if (!temp.children) {
149-
break;
150-
}
151-
152-
push(&queue, temp.children[i]);
86+
printf("%d\n", tmp->id);
87+
for (size_t i = 0; i < tmp->children_size; ++i) {
88+
stack_push(&stk, &tmp->children[i]);
15389
}
15490
}
91+
92+
free_stack(stk);
15593
}
15694

157-
void destroy_tree(node *n) {
158-
if (n->id == 0) {
159-
return;
160-
}
95+
void bfs_queue(struct node n) {
96+
struct queue q = get_queue(sizeof(struct node*));
97+
enqueue(&q, &n);
98+
struct node *tmp;
16199

162-
for (int i = 0; i < n->children_num; ++i) {
163-
destroy_tree(n->children + i);
100+
while (!queue_empty(&q)) {
101+
tmp = (struct node*)dequeue(&q);
102+
if (!tmp) {
103+
break;
104+
}
105+
106+
printf("%d\n", tmp->id);
107+
for (size_t i = 0; i < tmp->children_size; ++i) {
108+
enqueue(&q, &tmp->children[i]);
109+
}
164110
}
165111

166-
free(n->children);
112+
free_queue(q);
167113
}
168114

169115
int main() {
170-
node root;
171-
create_tree(&root, 3, 3);
172-
dfs_recursive(root);
173-
//dfs_stack(root);
174-
//bfs_queue(root);
175-
destroy_tree(&root);
116+
struct node root = create_tree(3, 3);
117+
bfs_queue(root);
118+
destroy_tree(root);
176119

177120
return 0;
178121
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#ifndef UTILITY_H
2+
#define UTILITY_H
3+
4+
#include <stdbool.h>
5+
#include <stddef.h>
6+
#include <stdlib.h>
7+
#include <string.h>
8+
9+
struct stack {
10+
void **data;
11+
size_t top, capacity, size;
12+
};
13+
14+
struct queue {
15+
void **data;
16+
size_t front, back, capacity;
17+
};
18+
19+
struct stack get_stack(size_t size) {
20+
struct stack stk;
21+
22+
stk.data = malloc(4 * size);
23+
stk.capacity = 4;
24+
stk.top = 0;
25+
26+
return stk;
27+
}
28+
29+
bool stack_empty(struct stack *stk) {
30+
return stk->top == 0;
31+
}
32+
33+
void stack_push(struct stack *stk, void *element) {
34+
if (stk->top == stk->capacity) {
35+
stk->capacity *= 2;
36+
stk->data = realloc(stk->data, stk->capacity * sizeof(stk->data[0]));
37+
}
38+
39+
stk->data[stk->top++] = element;
40+
}
41+
42+
void *stack_pop(struct stack *stk) {
43+
if (stack_empty(stk)) {
44+
return NULL;
45+
}
46+
47+
return stk->data[--stk->top];
48+
}
49+
50+
void free_stack(struct stack stk) {
51+
free(stk.data);
52+
}
53+
54+
struct queue get_queue(size_t size) {
55+
struct queue q;
56+
57+
q.data = calloc(4, size);
58+
q.front = 0;
59+
q.back = 0;
60+
q.capacity = 4;
61+
62+
return q;
63+
}
64+
65+
bool queue_empty(struct queue *q) {
66+
return q->front == q->back;
67+
}
68+
69+
void queue_resize(struct queue *q) {
70+
size_t size = sizeof(q->data[0]);
71+
void **tmp = calloc((q->capacity * 2), size);
72+
memcpy(tmp, q->data + q->front, (q->capacity - q->front) * size);
73+
memcpy(tmp + q->capacity - q->front, q->data, (q->front - 1) * size);
74+
75+
q->data = tmp;
76+
q->back = q->capacity - 1;
77+
q->front = 0;
78+
q->capacity *= 2;
79+
}
80+
81+
void enqueue(struct queue *q, void *element) {
82+
if (q->front == (q->back % q->capacity) + 1) {
83+
queue_resize(q);
84+
}
85+
86+
q->data[q->back] = element;
87+
q->back = (q->back + 1) % q->capacity;
88+
}
89+
90+
void *dequeue(struct queue *q) {
91+
if (queue_empty(q)) {
92+
return NULL;
93+
}
94+
95+
void *ret = q->data[q->front];
96+
q->front = (q->front + 1) % q->capacity;
97+
98+
return ret;
99+
}
100+
101+
void free_queue(struct queue q) {
102+
free(q.data);
103+
}
104+
105+
#endif //UTILITY_H

0 commit comments

Comments
 (0)