master
1#include "btree.h"
2#include "stack.h"
3#include <stdio.h>
4
5/**
6 * Prints a visual representation of a binary tree
7 *
8 * @param tree The tree or subtree to print
9 * @param level The level in the tree that the subtree belongs to
10 */
11static void inspect(BTree *tree, int level) {
12 if (!tree)
13 return;
14
15 for (int i = 0; i < level; i++)
16 printf(" ");
17
18 printf("%2d\n", tree->data);
19 inspect(tree->left, level + 1);
20 inspect(tree->right, level + 1);
21}
22
23/**
24 * Initializes a new instance of a binary tree.
25 *
26 * @param data The data to bind to the root of the new subtree.
27 * @return Returns the new subtree.
28 */
29BTree *btree_init(int data) {
30 BTree *tree = malloc(sizeof(BTree));
31 tree->left = NULL;
32 tree->right = NULL;
33 tree->data = data;
34 return tree;
35}
36
37/**
38 * Performs and caches the result of a pre order traversal
39 * on a binary tree. Cached results are stored in the root of
40 * the tree and not on each node of the tree.
41 *
42 * @param tree The subtree to perform the traversal on
43 */
44void btree_pre_order_number(BTree *tree) {
45 BTree *original = tree;
46 if (tree == NULL)
47 return;
48
49 Stack *stack = stack_init();
50 int i = 0;
51
52 stack_push(stack, tree);
53 while (stack_size(stack) > 0) {
54 tree = stack_pop(stack);
55 original->pre_order[i++] = tree->data;
56
57 if (tree->right != NULL)
58 stack_push(stack, tree->right);
59 if (tree->left != NULL)
60 stack_push(stack, tree->left);
61 }
62}
63
64/**
65 * Performs and caches the result of an in order traversal
66 * on a binary tree. Cached results are stored in the root of
67 * the tree and not on each node of the tree.
68 *
69 * @param root The subtree to perform the traversal on
70 */
71void btree_in_order_number(BTree *root) {
72 BTree *original = root;
73 if (root == NULL)
74 return;
75
76 Stack *stack = stack_init();
77 int i = 0;
78
79 while (true) {
80 if (root) {
81 stack_push(stack, root);
82 root = root->left;
83 } else {
84 if (stack_size(stack) == 0)
85 break;
86
87 root = stack_pop(stack);
88 original->in_order[i++] = root->data;
89 root = root->right;
90 }
91 }
92}
93
94/**
95 * Performs and caches the result of an post order traversal
96 * on a binary tree. Cached results are stored in the root of
97 * the tree and not on each node of the tree.
98 *
99 * @param root The subtree to perform the traversal on
100 */
101void btree_post_order_number(BTree *root) {
102 BTree *original = root;
103 if (root == NULL)
104 return;
105
106 Stack *s1 = stack_init();
107 Stack *s2 = stack_init();
108
109 stack_push(s1, root);
110
111 while (stack_size(s1) > 0) {
112 root = stack_pop(s1);
113 stack_push(s2, root);
114
115 if (root->left)
116 stack_push(s1, root->left);
117 if (root->right)
118 stack_push(s1, root->right);
119 }
120
121 int i = 0;
122 while (stack_size(s2) > 0) {
123 root = stack_pop(s2);
124 original->post_order[i++] = root->data;
125 }
126}
127
128/**
129 * Insert a new items into a binary tree.
130 *
131 * @param tree The tree to insert the data into.
132 * @param data The data to insert into the tree.
133 * @return Returns the new root of the tree.
134 */
135BTree *btree_insert(BTree *tree, int data) {
136 if (!tree)
137 return btree_init(data);
138
139 if (data <= tree->data)
140 if (tree->left)
141 btree_insert(tree->left, data);
142 else
143 tree->left = btree_init(data);
144 else if (tree->right)
145 btree_insert(tree->right, data);
146 else
147 tree->right = btree_init(data);
148
149 return tree;
150}
151
152/**
153 * Prints a visual representation of a binary tree.
154 *
155 * @param tree The subtree to inspect.
156 */
157void btree_inspect(BTree *tree) { inspect(tree, 0); }