diff --git a/.github/workflows/awesome_workflow.yml b/.github/workflows/awesome_workflow.yml index 60cd98c5..dd3c1d86 100644 --- a/.github/workflows/awesome_workflow.yml +++ b/.github/workflows/awesome_workflow.yml @@ -142,7 +142,7 @@ jobs: print(f"{len(space_files)} files contain space or dash characters:") print("\n".join(space_files) + "\n") - nodir_files = [file for file in cpp_files if file.count(os.sep) != 1 and "project_euler" not in file] + nodir_files = [file for file in cpp_files if file.count(os.sep) != 1 and "project_euler" not in file and "data_structure" not in file] if nodir_files: print(f"{len(nodir_files)} files are not in one and only one directory:") print("\n".join(nodir_files) + "\n") diff --git a/data_structures/binary_trees/binary_search_tree.c b/data_structures/binary_trees/binary_search_tree.c index c80873b4..9af1d5fa 100644 --- a/data_structures/binary_trees/binary_search_tree.c +++ b/data_structures/binary_trees/binary_search_tree.c @@ -1,29 +1,30 @@ +/** + * @file + * @brief A basic unbalanced binary search tree implementation in C. + * @details The implementation has the following functionalities implemented: + * - Insertion + * - Deletion + * - Search by key value + * - Listing of node keys in order of value (from left to right) + */ #include #include -/* A basic unbalanced binary search tree implementation in C, with the following - functionalities implemented: - - Insertion - - Deletion - - Search by key value - - Listing of node keys in order of value (from left to right) -*/ - -// Node, the basic data structure in the tree +/** Node, the basic data structure in the tree */ typedef struct node { - // left child - struct node *left; - - // right child - struct node *right; - - // data of the node - int data; + struct node *left; /**< left child */ + struct node *right; /**< right child */ + int data; /**< data of the node */ } node; -// The node constructor, which receives the key value input and returns a node -// pointer +/** The node constructor, which receives the key value input and returns a node + * pointer + * @param data data to store in a new node + * @returns new node with the provided data + * @note the node must be deleted before program terminates to avoid memory + * leaks + */ node *newNode(int data) { // creates a slug @@ -37,61 +38,82 @@ node *newNode(int data) return tmp; } -// Insertion procedure, which inserts the input key in a new node in the tree +/** Insertion procedure, which inserts the input key in a new node in the tree + * @param root pointer to parent node + * @param data value to store int he new node + * @returns pointer to parent node + */ node *insert(node *root, int data) { // If the root of the subtree is null, insert key here if (root == NULL) + { root = newNode(data); - // If it isn't null and the input key is greater than the root key, insert - // in the right leaf + } else if (data > root->data) + { + // If it isn't null and the input key is greater than the root key, + // insert in the right leaf root->right = insert(root->right, data); - // If it isn't null and the input key is lower than the root key, insert in - // the left leaf + } else if (data < root->data) + { // If it isn't null and the input key is lower than the root key, insert + // in the left leaf root->left = insert(root->left, data); + } // Returns the modified tree return root; } -// Utilitary procedure to find the greatest key in the left subtree +/** Utilitary procedure to find the greatest key in the left subtree + * @param root pointer to parent node + * @returns pointer to parent node + */ node *getMax(node *root) { // If there's no leaf to the right, then this is the maximum key value - if (root->right == NULL) - return root; - else - root->right = getMax(root->right); + if (root->right != NULL) + { + return getMax(root->right); + } + return root; } -// Deletion procedure, which searches for the input key in the tree and removes -// it if present +/** Deletion procedure, which searches for the input key in the tree and removes + * it if present + * @param root pointer to parent node + * @param data value to search for int the node + * @returns pointer to parent node + */ node *delete (node *root, int data) { // If the root is null, nothing to be done if (root == NULL) + { return root; - // If the input key is greater than the root's, search in the right subtree + } else if (data > root->data) + { // If the input key is greater than the root's, search in the right + // subtree root->right = delete (root->right, data); - // If the input key is lower than the root's, search in the left subtree + } else if (data < root->data) + { // If the input key is lower than the root's, search in the left subtree root->left = delete (root->left, data); - // If the input key matches the root's, check the following cases - // termination condition + } else if (data == root->data) { - // Case 1: the root has no leaves, remove the node + // If the input key matches the root's, check the following cases + // termination condition if ((root->left == NULL) && (root->right == NULL)) - { + { // Case 1: the root has no leaves, remove the node free(root); return NULL; } - // Case 2: the root has one leaf, make the leaf the new root and remove - // the old root else if (root->left == NULL) - { + { // Case 2: the root has one leaf, make the leaf the new root and + // remove + // the old root node *tmp = root; root = root->right; free(tmp); @@ -104,10 +126,10 @@ node *delete (node *root, int data) free(tmp); return root; } - // Case 3: the root has 2 leaves, find the greatest key in the left - // subtree and switch with the root's else - { + { // Case 3: the root has 2 leaves, find the greatest key in the left + // subtree and switch with the root's + // finds the biggest node in the left branch. node *tmp = getMax(root->left); @@ -120,30 +142,55 @@ node *delete (node *root, int data) return root; } -// Search procedure, which looks for the input key in the tree and returns 1 if -// it's present or 0 if it's not in the tree +/** Search procedure, which looks for the input key in the tree and returns 1 if + * it's present or 0 if it's not in the tree + * @param root pointer to parent node + * @param data value to store int he new node + * @returns 0 if value not found in the nodes + * @returns 1 if value was found + */ int find(node *root, int data) { // If the root is null, the key's not present if (root == NULL) + { return 0; - // If the input key is greater than the root's, search in the right subtree + } else if (data > root->data) + { + // If the input key is greater than the root's, search in the right + // subtree return find(root->right, data); - // If the input key is lower than the root's, search in the left subtree + } else if (data < root->data) + { + // If the input key is lower than the root's, search in the left subtree return find(root->left, data); - // If the input and the root key match, return 1 + } else if (data == root->data) + { + // If the input and the root key match, return 1 return 1; + } + else + { // unknown result!! + return 0; + } } -// Utilitary procedure to measure the height of the binary tree +/** Utilitary procedure to measure the height of the binary tree + * @param root pointer to parent node + * @param data value to store int he new node + * @returns 0 if value not found in the nodes + * @returns height of nodes to get to data from parent node + */ int height(node *root) { // If the root is null, this is the bottom of the tree (height 0) if (root == NULL) + { return 0; + } else { // Get the height from both left and right subtrees to check which is @@ -154,27 +201,40 @@ int height(node *root) // The final height is the height of the greatest subtree(left or right) // plus 1(which is the root's level) if (right_h > left_h) + { return (right_h + 1); + } else + { return (left_h + 1); + } } } -// Utilitary procedure to free all nodes in a tree +/** Utilitary procedure to free all nodes in a tree + * @param root pointer to parent node + */ void purge(node *root) { if (root != NULL) { if (root->left != NULL) + { purge(root->left); + } if (root->right != NULL) + { purge(root->right); + } free(root); + root = NULL; // reset pointer } } -// Traversal procedure to list the current keys in the tree in order of value -// (from the left to the right) +/** Traversal procedure to list the current keys in the tree in order of value + * (from the left to the right) + * @param root pointer to parent node + */ void inOrder(node *root) { if (root != NULL) @@ -185,7 +245,8 @@ void inOrder(node *root) } } -void main() +/** Main funcion */ +int main() { // this reference don't change. // only the tree changes. @@ -218,7 +279,9 @@ void main() root = delete (root, data); } else + { printf("Tree is already empty!\n"); + } break; case 3: @@ -240,4 +303,6 @@ void main() // deletes the tree from the heap. purge(root); + + return 0; }