diff options
| author | mo khan <mo.khan@gmail.com> | 2020-09-27 13:11:12 -0600 |
|---|---|---|
| committer | mo khan <mo.khan@gmail.com> | 2020-09-27 13:11:12 -0600 |
| commit | fc3968bcecc579c331ad01645def3f8e379984c4 (patch) | |
| tree | 6e1b701c0b2458d5a6b1a49c2381b5e988353da1 | |
| parent | 1fdac316bde6e192a6ebf51148af0ee66a6ae831 (diff) | |
docs: document each function
| -rw-r--r-- | src/03/btree.c | 38 | ||||
| -rw-r--r-- | src/03/graph.c | 37 | ||||
| -rw-r--r-- | src/03/matrix.c | 12 | ||||
| -rw-r--r-- | src/03/meldable_heap.c | 48 | ||||
| -rw-r--r-- | src/03/rb_tree.c | 134 | ||||
| -rw-r--r-- | src/03/sort.c | 50 |
6 files changed, 319 insertions, 0 deletions
diff --git a/src/03/btree.c b/src/03/btree.c index a7b960d..22f0021 100644 --- a/src/03/btree.c +++ b/src/03/btree.c @@ -2,6 +2,12 @@ #include <stdio.h> #include <stdlib.h> +/** + * Print a visual representation of an binary tree. + * + * @param tree The subtree to print + * @param level The level in the tree that this subtree is in + */ static void inspect(BTree *tree, int level) { if (!tree) return; @@ -14,6 +20,12 @@ static void inspect(BTree *tree, int level) { inspect(tree->right, level + 1); } +/** + * Initializes an instance of an binary tree. + * + * @param data The value to assign to the new node in the tree. + * @return Returns the new binary tree node instance. + */ BTree *btree_initialize(int data) { BTree *tree = malloc(sizeof(BTree)); tree->left = NULL; @@ -22,6 +34,13 @@ BTree *btree_initialize(int data) { return tree; } +/** + * Inserts a new value into a binary subtree. + * + * @param tree The subtree to attempt to insert a new value into. + * @param data The data to insert into the tree. + * @return Returns the new root of the subtree. + */ BTree *btree_insert(BTree *tree, int data) { if (!tree) return btree_initialize(data); @@ -39,6 +58,12 @@ BTree *btree_insert(BTree *tree, int data) { return tree; } +/** + * Returns the height of a binary subtree. + * + * @param tree The subtree to interrogate. + * @return The height of the subtree + */ int btree_height(BTree *tree) { if (tree == NULL) return 0; @@ -49,6 +74,12 @@ int btree_height(BTree *tree) { return (left > right) ? left + 1 : right + 1; } +/** + * Prints a visual inspection of + * a binary tree for debugging purposes to stdout. + * + * @param tree The tree to visualize + */ void btree_inspect(BTree *tree) { inspect(tree, 0); } int btree_leaves(BTree *tree) { @@ -61,6 +92,13 @@ int btree_leaves(BTree *tree) { return btree_leaves(tree->left) + btree_leaves(tree->right); } +/** + * Generates a binary tree with a desired number of leaf + * nodes. + * + * @param leaves The total number of leaf nodes to generate in the tree. + * @return Returns a new binary tree. + */ BTree *btree_generate(int leaves) { BTree *tree = NULL; diff --git a/src/03/graph.c b/src/03/graph.c index 2286101..808043b 100644 --- a/src/03/graph.c +++ b/src/03/graph.c @@ -2,12 +2,23 @@ #include <stdio.h> #include <stdlib.h> +/** + * Creates a new Vertex for use in a Graph. + * + * @param label The label to attach to the node. + * @return Returns a new vertex + */ Vertex *vertex_initialize(char label) { Vertex *item = malloc(sizeof(Vertex)); item->label = label; return item; }; +/** + * Initializes a new Graph + * + * @return Returns a new instance of a Graph. + */ Graph *graph_initialize(void) { Graph *item = malloc(sizeof(Graph)); for (int i = 0; i < 128; ++i) @@ -15,16 +26,42 @@ Graph *graph_initialize(void) { return item; } +/** + * Inserts a new vertex into a graph with the provided label. + * + * @param graph The graph to insert a new vertex into + * @param label The label to apply to the new vertex. + * @return Returns the new vertex + */ Vertex *graph_add_vertex(Graph *graph, char label) { Vertex *item = vertex_initialize(label); graph->vertices[(int)label] = item; return item; } +/** + * Updates a adjacency matrix to indicate that an edge exists + * between two vertexes. + * + * @param graph The graph to modify. + * @param a The vertex that points to vertex b. + * @param b The vertex that vertex a points to. + */ void graph_add_edge(Graph *graph, Vertex *a, Vertex *b) { graph->edges[a->label][b->label] = true; } +/** + * Returns true or false to specify if vertex `a` + * in a graph is connected to vertex `b` in the same + * graph. + * + * @param graph The graph to investigate + * @param a The starting vertext to check + * @param b The vertex that vertex a might be pointing at. + * @return Returns true if an edge exists between the two vertexes otherwise + * false. + */ bool graph_has_edge(Graph *graph, Vertex *a, Vertex *b) { return graph->edges[a->label][b->label]; } diff --git a/src/03/matrix.c b/src/03/matrix.c index 9398cae..1e4d310 100644 --- a/src/03/matrix.c +++ b/src/03/matrix.c @@ -5,6 +5,11 @@ char labels[26] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; +/** + * Traverses a graph represented as an adjacency matrix + * to visit every vertex in the graph and traverse each + * edge in both directions only once. + */ void matrix_traverse(int n, int graph[n][n], int visited[n], int vertex) { printf("->(%c)", labels[vertex]); visited[vertex] = 1; @@ -27,6 +32,13 @@ void matrix_traverse(int n, int graph[n][n], int visited[n], int vertex) { } } +/** + * Prints a visual representation of an + * adjacency matrix to stdout out for debugging purposes. + * + * @param n The number of vertexes in the graph. + * @param graph The adjacency matrix that represents the graph. + */ void matrix_inspect(int n, int graph[n][n]) { printf("\n"); diff --git a/src/03/meldable_heap.c b/src/03/meldable_heap.c index 373625f..2647425 100644 --- a/src/03/meldable_heap.c +++ b/src/03/meldable_heap.c @@ -3,8 +3,24 @@ #include <stdio.h> #include <stdlib.h> +/** + * Compares two integers and returns -1, 0, 1. + * If a is equal to b then 0 is returned. + * If a is greater than b then 1 is returned. + * If a is less than b then -1 is returned. + * + * @param a An integer + * @param b Another integer + * @return Returns 0, 1, or -1. + */ static int compare(int a, int b) { return (a < b) ? -1 : ((a > b) ? 1 : 0); } +/** + * Print a visual representation of a heap. + * + * @param heap The subtree to print + * @param level The level in the heap that this subtree is in + */ static void print_tree(MeldableHeap *heap, int level) { for (int i = 0; i < level; i++) printf(" "); @@ -21,6 +37,12 @@ static void print_tree(MeldableHeap *heap, int level) { } } +/** + * Initializes an instance of an meldable heap. + * + * @param value The value to assign to the new node in the heap. + * @return Returns the new heap node instance. + */ MeldableHeap *meldable_heap_initialize(int value) { MeldableHeap *heap = malloc(sizeof(MeldableHeap)); heap->left = NULL; @@ -30,6 +52,13 @@ MeldableHeap *meldable_heap_initialize(int value) { return heap; }; +/** + * Adds a new value into a heap. + * + * @param heap The subtree to attempt to insert a new value into. + * @param value The value to insert. + * @return Returns the new root of the subtree. + */ MeldableHeap *meldable_heap_add(MeldableHeap *heap, int value) { MeldableHeap *root = meldable_heap_merge(meldable_heap_initialize(value), heap); @@ -37,6 +66,14 @@ MeldableHeap *meldable_heap_add(MeldableHeap *heap, int value) { return root; } +/** + * Merges to meldable heaps into a single heap and returns the + * root of the new heap. + * + * @param h1 A heap + * @param h2 Another heap + * @return Returns the merged heap + */ MeldableHeap *meldable_heap_merge(MeldableHeap *h1, MeldableHeap *h2) { if (h1 == NULL) return h2; @@ -56,8 +93,19 @@ MeldableHeap *meldable_heap_merge(MeldableHeap *h1, MeldableHeap *h2) { return h1; } +/** + * Prints a visual inspection of + * a heap for debugging purposes to stdout. + * + * @param heap The heap to visualize + */ void meldable_heap_inspect(MeldableHeap *heap) { print_tree(heap, 0); } +/** + * Removes a value from a meldable heap. + * + * @param heap The subtree to remove + */ void meldable_heap_remove(MeldableHeap *heap) { MeldableHeap *replacement = meldable_heap_merge(heap->left, heap->right); diff --git a/src/03/rb_tree.c b/src/03/rb_tree.c index 7db2eed..8803837 100644 --- a/src/03/rb_tree.c +++ b/src/03/rb_tree.c @@ -7,6 +7,13 @@ * * https://en.wikipedia.org/wiki/Red%E2%80%93black_tree#Insertion */ +/** + * Returns the larger integer between the two provided as arguments. + * + * @param a An integer value to compare + * @param b Another integer value to compare + * @return Returns the larger value + */ static int max(int a, int b) { return a == b ? a : (a > b ? a : b); } /** @@ -26,10 +33,28 @@ static int depth(RBTree *tree) { return total; } +/** + * Determines if a provided subtree is the root. + * + * @param node The subtree to investigate + * @param Returns tree when the node is the root otherwise false. + */ static bool is_root(RBTree *node) { return node->parent == NULL; } +/** + * Returns the parent node of a node. + * + * @param node The node to investigate. + * @return The parent of the node or NULL. + */ static RBTree *parent_of(RBTree *node) { return node ? node->parent : NULL; } +/** + * Returns the root of a subtree + * + * @param node The subtree to investigate + * @return Returns the root of the subtree + */ static RBTree *root_of(RBTree *node) { RBTree *current = node; RBTree *next = parent_of(current); @@ -41,10 +66,22 @@ static RBTree *root_of(RBTree *node) { return current; } +/** + * Returns the grand parent node of a node. + * + * @param node The node to investigate. + * @return The grand parent of the node or NULL. + */ static RBTree *grand_parent_of(RBTree *node) { return parent_of(parent_of(node)); } +/** + * Returns a sibling node of a given node. + * + * @param node The node to investigate. + * @return The sibling of the node or NULL. + */ static RBTree *sibling_of(RBTree *node) { RBTree *parent = parent_of(node); @@ -54,6 +91,12 @@ static RBTree *sibling_of(RBTree *node) { return node == parent->left ? parent->right : parent->left; } +/** + * Returns a pibling (aunt/uncle) node of a given node. + * + * @param node The node to investigate. + * @return The pibling of the node or NULL. + */ static RBTree *pibling_of(RBTree *node) { return sibling_of(parent_of(node)); } static void rb_rotate_left(RBTree *tree) { @@ -76,6 +119,11 @@ static void rb_rotate_left(RBTree *tree) { tmp->parent = parent; } +/** + * Performs a right rotation on a subtree + * + * @param tree The subtree to perform the rotation on + */ static void rb_rotate_right(RBTree *tree) { RBTree *tmp = tree->left; RBTree *parent = parent_of(tree); @@ -96,6 +144,11 @@ static void rb_rotate_right(RBTree *tree) { tmp->parent = parent; } +/** + * Performs any repairs necessary on a subtree + * + * @param tree The subtree to perform a repair on + */ static void repair_from(RBTree *tree) { RBTree *parent = parent_of(tree); RBTree *pibling = pibling_of(tree); @@ -137,8 +190,24 @@ static void repair_from(RBTree *tree) { } } +/** + * Compares two integers and returns -1, 0, 1. + * If a is equal to b then 0 is returned. + * If a is greater than b then 1 is returned. + * If a is less than b then -1 is returned. + * + * @param a An integer + * @param b Another integer + * @return Returns 0, 1, or -1. + */ static int compare(int a, int b) { return a == b ? 0 : a < b ? -1 : 1; } +/** + * Inserts a new node into a subtree. + * + * @param tree The subtree to attempt to insert a new value into. + * @param node The new node to insert. + */ static void insert(RBTree *root, RBTree *node) { if (!root) return; @@ -160,6 +229,12 @@ static void insert(RBTree *root, RBTree *node) { } } +/** + * Print a visual representation of a tree. + * + * @param tree The subtree to print + * @param level The level in the tree that this subtree is in + */ static void print_tree(RBTree *tree, int level) { for (int i = 0; i < level; i++) printf(" "); @@ -177,6 +252,13 @@ static void print_tree(RBTree *tree, int level) { } } +/** + * Initializes an instance of a tree. + * + * @param value The value to assign to the new node in the tree. + * @param color The colour to assign to the new node in the tree. + * @return Returns the new tree node instance. + */ RBTree *rb_tree_initialize_with(int value, enum Colour colour) { RBTree *tree = malloc(sizeof(RBTree)); tree->colour = colour; @@ -187,10 +269,23 @@ RBTree *rb_tree_initialize_with(int value, enum Colour colour) { return tree; } +/** + * Initializes an instance of a tree with a default colour of black. + * + * @param value The value to assign to the new node in the tree. + * @return Returns the new tree node instance. + */ RBTree *rb_tree_initialize(int value) { return rb_tree_initialize_with(value, black); } +/** + * Inserts a new value into a subtree. + * + * @param tree The subtree to attempt to insert a new value into. + * @param value The value to insert. + * @return Returns the new root of the subtree. + */ RBTree *rb_tree_insert(RBTree *tree, int value) { if (tree == NULL) return rb_tree_initialize(value); @@ -201,6 +296,12 @@ RBTree *rb_tree_insert(RBTree *tree, int value) { return root_of(node); } +/** + * Prints a visual inspection of + * a tree for debugging purposes to stdout. + * + * @param tree The tree to visualize + */ void rb_tree_inspect(RBTree *tree) { print_tree(tree, 0); } int rb_tree_size(RBTree *tree) { @@ -214,6 +315,15 @@ int rb_tree_size(RBTree *tree) { return total + 1; } +/** + * Determines if two trees are equal by verifying + * that each descendant node in each subtree have + * the same value and colour. + * + * @param tree A tree to compare + * @param other_tree Another tree to compare + * @return Returns true when both subtrees are equal otherwise false + */ bool rb_equals(RBTree *tree, RBTree *other_tree) { if (!tree || !other_tree) return tree == other_tree; @@ -233,6 +343,17 @@ bool rb_equals(RBTree *tree, RBTree *other_tree) { rb_equals(tree->right, other_tree->right); } +/** + * Determines if a tree matches the properties + * necessary to claim to be a valid Red Black tree. + * + * 1. root must be black + * 2. there are the same # of black nodes on every root to the leaf path. + * 3. No two red nodes are adjacent. + * + * @param tree The tree to investigate + * @return Returns true if the tree meets the criteria otherwise false. + */ bool rb_tree_is_valid(RBTree *tree) { if (tree == NULL) return true; @@ -249,6 +370,12 @@ bool rb_tree_is_valid(RBTree *tree) { return rb_tree_is_valid(tree->left) && rb_tree_is_valid(tree->right); } +/** + * Returns the height of a subtree. + * + * @param tree The subtree to investigate + * @return Returns the height of the subtree + */ int rb_tree_height(RBTree *tree) { if (!tree) return 1; @@ -256,6 +383,13 @@ int rb_tree_height(RBTree *tree) { return 1 + max(rb_tree_height(tree->left), rb_tree_height(tree->right)); } +/** + * Searches for a node in a subtree with a particular value. + * + * @param t The subtree to search. + * @param value The value to search for + * @returns Returns the node containing the value otherwise NULL + */ RBTree *rb_tree_find(RBTree *t, int value) { if (!t) return NULL; diff --git a/src/03/sort.c b/src/03/sort.c index 61b12de..d1ae704 100644 --- a/src/03/sort.c +++ b/src/03/sort.c @@ -1,6 +1,13 @@ #include <stdio.h> #include <stdlib.h> +/** + * Prints a visual dump of an array of + * items to stdout out for debugging. + * + * @param items The items to inspect + * @param n The total # of items in the array. + */ static void dump(int *items, int n) { printf("["); for (int i = 0; i < n; ++i) @@ -8,6 +15,14 @@ static void dump(int *items, int n) { printf("]\n"); } +/** + * Merges two subsequences of an array. + * + * @params items A pointer to the start of an array of items + * @param min The starting index of the left sub sequence. + * @param mid The starting index of the right sub sequence. + * @param max The ending index of the right sub sequence. + */ static void _merge(int *items, int min, int mid, int max) { int length = (max - min) + 1; int tmp[length]; @@ -29,6 +44,13 @@ static void _merge(int *items, int min, int mid, int max) { items[min + i] = tmp[i]; } +/** + * Performs a recursive merge sort of items in an array. + * + * @param items An array of integers. + * @param min The starting index of a subsequence to sort + * @param max The ending index of a subsequence to sort + */ static void _merge_sort(int *items, int min, int max) { if (min >= max) return; @@ -39,6 +61,15 @@ static void _merge_sort(int *items, int min, int max) { _merge(items, min, mid + 1, max); } +/** + * Partitions a sequence into two subsequences. + * + * @param items An array of integers to partition + * @param min The starting index of the sequence to partition + * @param max The ending index of the sequence to partition + * @return Returns the index that can be used as the partition point for the + * sequence. + */ static int partition(int *items, int min, int max) { int pivot = items[max]; int index = min - 1; @@ -59,6 +90,13 @@ static int partition(int *items, int min, int max) { return index + 1; } +/** + * Performs a recursive quick sort on an array of items. + * + * @param items An array of integers + * @param min The starting index of a subsequence to sort + * @param max The ending index of a subsequence to sort + */ static void _quick_sort(int *items, int min, int max) { if (min >= max) return; @@ -68,6 +106,12 @@ static void _quick_sort(int *items, int min, int max) { _quick_sort(items, index + 1, max); } +/** + * Performs a merge sort on an array of integers. + * + * @param items An array of integers + * @param length The # of items in the array of integers + */ void merge_sort(int *items, int length) { if (!items || length <= 0) return; @@ -75,6 +119,12 @@ void merge_sort(int *items, int length) { _merge_sort(items, 0, length - 1); } +/** + * Performs a quick sort on an array of integers. + * + * @param items An array of integers + * @param length The # of items in the array of integers + */ void quick_sort(int *items, int length) { if (!items || length <= 0) return; |
