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
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <string.h>


// if you want to copy:
// * understand the algorithm
// * write your code without looking at this code

typedef struct _BSTNode {
    struct _BSTNode* left;
    struct _BSTNode* right;
    char* value;
} BSTNode;

typedef struct {
    struct _BSTNode* root;
    int size;
} BST;

// if you include level and side for a pre-order print,
// can be good for debugging your tree strucutre
void print_pre_order(BSTNode* root, int level, char side) {
    if (root != NULL) {
        for (int i = 0; i < level; i++) {
            fputc(' ', stdout);
        }
        printf("%c: \"%s\"\n", side, root->value);
        print_pre_order(root->left, level + 1, 'L');
        print_pre_order(root->right, level + 1, 'R');
    }
}

// best for printing the full sorted tree, or transferring it to
// an array
void print_in_order(BSTNode* root) {
    if (root != NULL) {
        print_in_order(root->left);
        printf("\"%s\"\n", root->value);
        print_in_order(root->right);
    }
}

// freeing the tree uses a post order traversal
void destroy_bst(BSTNode* root) {
    if (root != NULL) {
        destroy_bst(root->left);
        destroy_bst(root->right);
        free(root);
    }
}

void _bst_insert_recursion(BSTNode** a_root, char* value) {
    if (*a_root == NULL) {
        BSTNode* new_node = malloc(sizeof(*new_node));
        *new_node = (BSTNode) {
            .value = value,
            .left = NULL,
            .right = NULL
        };
        *a_root = new_node;
        // if a < b    is written as:
        // if strcmp(a, b) < 0
    } else if (strcmp(value, (*a_root)->value) < 0) {
        _bst_insert_recursion(&((*a_root)->left), value);
    } else {
        _bst_insert_recursion(&((*a_root)->right), value);
    }
}

void bst_insert(BST* a_bst, char* value) {
    _bst_insert_recursion(&(a_bst->root), value);
    a_bst->size += 1;
}


int main(int argc, char* argv[]) {
    BST bst = { .root = NULL, .size = 0 };

    bst_insert(&bst, "cranberry");
    bst_insert(&bst, "apple");
    bst_insert(&bst, "banana");
    bst_insert(&bst, "cherry");
    bst_insert(&bst, "dewberry");
    bst_insert(&bst, "strawberry");
    bst_insert(&bst, "mango");


    printf("Pre order:\n");
    print_pre_order(bst.root, 0, 'R');
    printf("In order:\n");
    print_in_order(bst.root);

    destroy_bst(bst.root);

    return EXIT_SUCCESS;
}
/* vim: set tabstop=4 shiftwidth=4 fileencoding=utf-8 noexpandtab: */

© Copyright 2024 Alexander J. Quinn & David Burnett         This content is protected and may not be shared, uploaded, or distributed.