1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include "iterative_tree_traversals.h" // struct types and function declarations used in this file
/********************************************************************
|* MAIN function
\*/
int main(int argc, char* argv[]) {
// Empty list
BSTNode* root = NULL;
// Insert a value
insert(4, &root);
insert(2, &root);
insert(6, &root);
insert(1, &root);
insert(3, &root);
insert(5, &root);
insert(7, &root);
printf("Pre-order\n");
print_tree_pre_order(root);
printf("In-order\n");
print_tree_in_order(root);
// Free
destroy_tree(&root);
return EXIT_SUCCESS;
}
/********************************************************************
|* Iterative tree traversals
\*/
void print_tree_in_order(BSTNode* root) { // IN-ORDER traversal: left, root, right
StackNode* top = NULL;
BSTNode* curr = root;
while(curr != NULL || top != NULL) { // *** OR ***
if(curr != NULL) {
stack_push(&top, curr); // "Push the 4 onto the stack:"
curr = curr -> left; // "Go to the left subtree"
}
else {
curr = stack_pop(&top);
printf("curr -> value == %d\n", curr -> value);
curr = curr -> right; // will lead to pushing curr -> right next time
}
}
}
void print_tree_pre_order(BSTNode* root) { // PRE-ORDER traversal: root, left, right
StackNode* top = NULL;
stack_push(&top, root);
while(top != NULL) {
BSTNode* curr = stack_pop(&top);
if(curr != NULL) {
printf("curr -> value == %d\n", curr -> value);
stack_push(&top, curr -> right);
stack_push(&top, curr -> left);
}
}
}
/********************************************************************
|* STACK operations
\*/
void stack_push(StackNode** a_top, BSTNode* value) {
StackNode* new_top = malloc(sizeof(*new_top));
*new_top = (StackNode) { .next = NULL, .value = value }; // Compound literal
if(*a_top != NULL) { // If stack is not initially empty...
new_top -> next = *a_top; // make the new top refer to the existing top
}
*a_top = new_top; // new top becomes the top of the stack
assert(*a_top != NULL); // Just added something, so can't possibly be empty now.
assert((*a_top) -> value == value); // Top should have the character we just pushed.
}
BSTNode* stack_pop(StackNode** a_top) { // Usage: Must not be called with an empty stack.
StackNode* old_top = *a_top;
BSTNode* value = old_top -> value;
*a_top = old_top -> next;
free(old_top);
return value;
}
bool stack_is_empty(StackNode* top) {
return (top == NULL);
}
/********************************************************************
|* BST (binary search tree) operations
\*/
void insert(int value, BSTNode** a_root) {
// If tree is empty, then insert the value as the root of this tree.
if(*a_root == NULL) {
// CREATE new node
BSTNode* new_node = malloc(sizeof(*new_node));
*new_node = (BSTNode) { .value = value, .left = NULL, .right = NULL };
// CONNECT new node to the tree
*a_root = new_node;
}
// Otherwise, insert in either the left or right subtree, depending on the value.
else if(value < (*a_root) -> value) {
insert(value, &((*a_root) -> left));
}
else if(value >= (*a_root) -> value) {
insert(value, &((*a_root) -> right));
}
}
void destroy_tree(BSTNode** a_root) { //
if(*a_root != NULL) {
destroy_tree(&((*a_root) -> left));
assert((*a_root) -> left == NULL); // left subtree has been destroyed and is empty
destroy_tree(&((*a_root) -> right));
assert((*a_root) -> right == NULL);
free(*a_root); // deallocate
*a_root = NULL; // set to NULL to indicate that it is empty
}
assert(*a_root == NULL); // Tree must be empty
}
/* vim: set tabstop=4 shiftwidth=4 fileencoding=utf-8 noexpandtab: */
|
© Copyright 2023 Alexander J. Quinn This content is protected and may not be shared, uploaded, or distributed.