{"id":19329148,"url":"https://github.com/ngugimuchangi/binary_trees","last_synced_at":"2026-04-17T06:02:56.827Z","repository":{"id":114735126,"uuid":"538738312","full_name":"ngugimuchangi/binary_trees","owner":"ngugimuchangi","description":"Binary trees","archived":false,"fork":false,"pushed_at":"2023-09-11T16:47:57.000Z","size":105,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-06T07:49:31.624Z","etag":null,"topics":["avl-tree","binary-search-tree","binary-tree","dsa","heapsort"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ngugimuchangi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-19T23:50:17.000Z","updated_at":"2023-08-14T22:07:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"fc39a9b1-d0cb-422c-aadf-64a7a508862b","html_url":"https://github.com/ngugimuchangi/binary_trees","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngugimuchangi%2Fbinary_trees","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngugimuchangi%2Fbinary_trees/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngugimuchangi%2Fbinary_trees/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngugimuchangi%2Fbinary_trees/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngugimuchangi","download_url":"https://codeload.github.com/ngugimuchangi/binary_trees/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240434194,"owners_count":19800548,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avl-tree","binary-search-tree","binary-tree","dsa","heapsort"],"created_at":"2024-11-10T02:26:49.330Z","updated_at":"2026-04-17T06:02:51.739Z","avatar_url":"https://github.com/ngugimuchangi.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 0x1D. C - Binary trees\n\n## About\n\nThis is project to explore the following concepts:\n\n- What is a binary tree\n- What is the difference between a binary tree and a Binary Search Tree\n- What is the possible gain in terms of time complexity compared to linked lists\n- What are the depth, the height, the size of a binary tree\n- What are the different traversal methods to go through a binary tree\n- What is a complete, a full, a perfect, a balanced binary tree\n\n## Requirements\n\n- Ubuntu 20.04 LTS\n- gcc 4.8.4\n\n## Compiling\n\n```\n$ gcc -Wall -Werror -Wextra -pedantic -std=gnu89 *.c -o \u003coutput file name\u003e\n```\n\n## File Descriptions\n\n### [binary_trees.h](./binary_trees.h)\n\n- Header file containing definitions and prototypes for all types and functions\n  written for the project.\n\n### [binary_tree_print.c](utils/binary_tree_print.c)\n\n- Function to print binary trees\n\n### [tests](tests)\n\n- Folder containing the test files for all the tasks.\n\n## Tasks\n\n### [0. New node](./0-binary_tree_node.c)\n\n- Write a function that creates a binary tree node\n  - Prototype:\n    `binary_tree_t *binary_tree_node(binary_tree_t *parent, int value);`\n  - `parent` is a pointer to the parent node of the node to create\n  - `value` is the value to put in the new node\n  - When created, a node does not have any children\n  - Your function must return a pointer to the new node, or `NULL` on failure\n\n### [1. Insert left](./1-binary_tree_insert_left.c)\n\n- Write a function that inserts a node as the left-child of another node\n  - Prototype:\n    `binary_tree_t *binary_tree_insert_left(binary_tree_t *parent, int value);`\n  - `parent` is a pointer to the node to insert the left-child in\n  - `value` is the value to store in the new node\n  - Your function must return a pointer to the created node, or `NULL` on\n    failure or if `parent` is `NULL`\n  - If `parent` already has a left-child, the new node must take its place, and\n    the old left-child must be set as the left-child of the new node.\n\n### [2. Insert right](./2-binary_tree_insert_right.c)\n\n- Write a function that inserts a node as the right-child of another node\n  - Prototype:\n    `binary_tree_t *binary_tree_insert_right(binary_tree_t *parent, int value);`\n  - `parent` is a pointer to the node to insert the right-child in\n  - `value` is the value to store in the new node\n  - Your function must return a pointer to the created node, or `NULL` on\n    failure or if `parent` is `NULL`\n  - If `parent` already has a right-child, the new node must take its place, and\n    the old right-child must be set as the right-child of the new node.\n\n### [3. Delete](./3-binary_tree_delete.c)\n\n- Write a function that deletes an entire binary tree\n  - Prototype: `void binary_tree_delete(binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to delete\n  - If `tree` is `NULL`, do nothing\n\n### [4. Is leaf](./4-binary_tree_is_leaf.c)\n\n- Write a function that checks if a node is a leaf\n  - Prototype: `int binary_tree_is_leaf(const binary_tree_t *node);`\n  - `node` is a pointer to the node to check\n  - Your function must return `1` if `node` is a leaf, otherwise `0`\n  - If `node` is `NULL`, return `0`\n\n### [5. Is root](./5-binary_tree_is_root.c)\n\n- Write a function that checks if a given node is a root\n  - Prototype: `int binary_tree_is_root(const binary_tree_t *node);`\n  - `node` is a pointer to the node to check\n  - Your function must return `1` if `node` is a root, otherwise `0`\n  - If `node` is `NULL`, return `0`\n\n### [6. Pre-order traversal](./6-binary_tree_preorder.c)\n\n- Write a function that goes through a binary tree using pre-order traversal\n  - Prototype:\n    `void binary_tree_preorder(const binary_tree_t *tree, void (*func)(int));`\n  - `tree` is a pointer to the root node of the tree to traverse\n  - `func` is a pointer to a function to call for each node. The value in the\n    node must be passed as a parameter to this function.\n  - If `tree` or `func` is `NULL`, do nothing\n\n### [7. In-order traversal](./7-binary_tree_inorder.c)\n\n- Write a function that goes through a binary tree using in-order traversal\n  - Prototype:\n    `void binary_tree_inorder(const binary_tree_t *tree, void (*func)(int));`\n  - `tree` is a pointer to the root node of the tree to traverse\n  - `func` is a pointer to a function to call for each node. The value in the\n    node must be passed as a parameter to this function.\n  - If `tree` or `func` is `NULL`, do nothing\n\n### [8. Post-order traversal](./8-binary_tree_postorder.c)\n\n- Write a function that goes through a binary tree using post-order traversal\n  - Prototype:\n    `void binary_tree_postorder(const binary_tree_t *tree, void (*func)(int));`\n  - `tree` is a pointer to the root node of the tree to traverse\n  - `func` is a pointer to a function to call for each node. The value in the\n    node must be passed as a parameter to this function.\n  - If `tree` or `func` is `NULL`, do nothing\n\n### [9. Height](./9-binary_tree_height.c)\n\n- Write a function that measures the height of a binary tree\n  - Prototype: `size_t binary_tree_height(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to measure the height.\n  - If `tree` is `NULL`, your function must return `0`\n\n### [10. Depth](./10-binary_tree_depth.c)\n\n- Write a function that measures the depth of a node in a binary tree\n  - Prototype: `size_t binary_tree_depth(const binary_tree_t *tree);`\n  - `tree` is a pointer to the node to measure the depth\n  - If `tree` is `NULL`, your function must return `0`\n\n### [11. Size](./11-binary_tree_size.c)\n\n- Write a function that measures the size of a binary tree\n  - Prototype: `size_t binary_tree_size(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to measure the size\n  - If `tree` is `NULL`, the function must return `0`\n\n### [12. Leaves](./12-binary_tree_leaves.c)\n\n- Write a function that counts the leaves in a binary tree\n  - Prototype: `size_t binary_tree_leaves(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to count the number of\n    leaves\n  - If `tree` is `NULL`, the function must return `0`\n  - A `NULL` pointer is not a leaf\n\n### [13. Nodes](./13-binary_tree_nodes.c)\n\n- Write a function that counts the nodes with at least 1 child in a binary tree\n  - Prototype: `size_t binary_tree_nodes(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to count the number of\n    nodes\n  - If `tree` is `NULL`, the function must return `0`\n  - A `NULL` pointer is not a node\n\n### [14. Balance factor](./14-binary_tree_balance.c)\n\n- Write a function that measures the balance factor of a binary tree\n  - Prototype: `int binary_tree_balance(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to measure the balance\n    factor\n  - If `tree` is `NULL`, return `0`\n\n### [15. Is full](./15-binary_tree_is_full.c)\n\n- Write a function that checks if a binary tree is full\n  - Prototype: `int binary_tree_is_full(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to check\n  - If `tree` is `NULL`, your function must return `0`\n\n### [16. Is perfect](./16-binary_tree_is_perfect.c)\n\n- Write a function that checks if a binary tree is perfect\n  - Prototype: `int binary_tree_is_perfect(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to check\n  - If `tree` is `NULL`, your function must return `0`\n\n### [17. Sibling](./17-binary_tree_sibling.c)\n\n- Write a function that finds the sibling of a node\n  - Prototype: `binary_tree_t *binary_tree_sibling(binary_tree_t *node);`\n  - `node` is a pointer to the node to find the sibling\n  - Your function must return a pointer to the sibling node\n  - If `node` is `NULL` or the parent is `NULL`, return `NULL`\n  - If `node` has no sibling, return `NULL`\n\n### [18. Uncle](./18-binary_tree_uncle.c)\n\n- Write a function that finds the uncle of a node\n  - Prototype: `binary_tree_t *binary_tree_uncle(binary_tree_t *node);`\n  - `node` is a pointer to the node to find the uncle\n  - Your function must return a pointer to the uncle node\n  - If `node` is `NULL`, return `NULL`\n  - If `node` has no uncle, return `NULL`\n\n### [19. Lowest common ancestor](./100-binary_trees_ancestor.c)\n\n- Write a function that finds the lowest common ancestor of two nodes\n  - Prototype:\n    `binary_tree_t *binary_trees_ancestor(const binary_tree_t *first, const binary_tree_t *second);`\n  - `first` is a pointer to the first node\n  - `second` is a pointer to the second node\n  - Your function must return a pointer to the lowest common ancestor node of\n    the two given nodes\n  - If no common ancestor was found, your function must return `NULL`\n  - Note: The lowest common ancestor is defined for two nodes `p` and `q` as the\n    lowest node in `T` that has both `p` and `q` as descendants where we allow a\n    node to be a descendant of itself.\n\n### [20. Level-order traversal](./101-binary_tree_levelorder.c)\n\n- Write a function that goes through a binary tree using level-order traversal\n  - Prototype:\n    `void binary_tree_levelorder(const binary_tree_t *tree, void (*func)(int));`\n  - `tree` is a pointer to the root node of the tree to traverse\n  - `func` is a pointer to a function to call for each node. The value in the\n    node must be passed as a parameter to this function.\n  - If `tree` or `func` is `NULL`, do nothing\n\n### [21. Is complete](./102-binary_tree_is_complete.c)\n\n- Write a function that checks if a binary tree is complete\n  - Prototype: `int binary_tree_is_complete(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to check\n  - If `tree` is `NULL`, your function must return `0`\n\n### [22. Rotate left](./103-binary_tree_rotate_left.c)\n\n- Write a function that performs a left-rotation on a binary tree\n  - Prototype: `binary_tree_t *binary_tree_rotate_left(binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to rotate\n  - Your function must return a pointer to the new root node of the tree once\n    rotated\n\n### [23. Rotate right](./104-binary_tree_rotate_right.c)\n\n- Write a function that performs a right-rotation on a binary tree\n  - Prototype: `binary_tree_t *binary_tree_rotate_right(binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to rotate\n  - Your function must return a pointer to the new root node of the tree once\n    rotated\n\n### [24. Is BST](./110-binary_tree_is_bst.c)\n\n- Write a function that checks if a binary tree is a valid Binary Search Tree\n  - Prototype: `int binary_tree_is_bst(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to check\n  - Your function must return `1` if `tree` is a valid BST, and `0` otherwise\n  - If `tree` is `NULL`, return `0`\n\n### [25. BST - Insert](./111-bst_insert.c)\n\n- Write a function that inserts a value in a Binary Search Tree\n  - Prototype: `bst_t *bst_insert(bst_t **tree, int value);`\n  - `tree` is a double pointer to the root node of the BST to insert the value\n  - Once inserted, the tree must be in a valid BST order\n  - If `tree` is `NULL`, the created node must become the root node.\n  - Return a pointer to the created node, or `NULL` on failure\n  - If the address stored in `tree` is `NULL`, the created node must become the\n    root node.\n\n### [26. BST - Array to BST](./112-array_to_bst.c)\n\n- Write a function that builds a Binary Search Tree from an array\n  - Prototype: `bst_t *array_to_bst(int *array, size_t size);`\n  - `array` is a pointer to the first element of the array to be converted\n  - `size` is the number of element in the array\n  - Your function must return a pointer to the root node of the created BST, or\n    `NULL` on failure\n  - If a value of the array is already present in the tree, this value must be\n    ignored\n\n### [27. BST - Search](./113-bst_search.c)\n\n- Write a function that searches for a value in a Binary Search Tree\n  - Prototype: `bst_t *bst_search(const bst_t *tree, int value);`\n  - `tree` is a pointer to the root node of the BST to search\n  - `value` is the value to search in the tree\n  - Your function must return a pointer to the node containing a value equals to\n    `value`\n  - If `tree` is `NULL` or if nothing is found, your function must return `NULL`\n\n### [28. BST - Remove](./114-bst_remove.c)\n\n- Write a function that removes a node from a Binary Search Tree\n  - Prototype: `bst_t *bst_remove(bst_t *root, int value);`\n  - `root` is a pointer to the root node of the tree where you will remove a\n    node\n  - `value` is the value to remove in the tree\n  - Once located, the node containing a value equals to `value` must be removed\n    and freed\n  - If the node to be deleted is a leaf, it can be simply removed\n  - If the node to be deleted is a root node, the root pointer must be updated\n  - When removing a node with two children, it must be replaced with its first\n    in-order successor (not predecessor)\n  - Your function must return a pointer to the new root node of the tree after\n    removing the desired value\n\n### [29. Big O #BST](./115-O)\n\n- What are the average time complexities of those operations on a Binary Search\n  Tree (one answer per line):\n  - Inserting the value `n`\n  - Removing the node with the value `n`\n  - Searching for a node in a BST of size `n`\n\n### [30. Is AVL](./120-binary_tree_is_avl.c)\n\n- Write a function that checks if a binary tree is a valid AVL Tree\n  - Prototype: `int binary_tree_is_avl(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to check\n  - Your function must return `1` if `tree` is a valid AVL Tree, and `0`\n    otherwise\n  - If `tree` is `NULL`, return `0`\n\n### [31. AVL - Insert](./121-avl_insert.c)\n\n- Write a function that inserts a value in an AVL Tree\n  - Prototype: `avl_t *avl_insert(avl_t **tree, int value);`\n  - `tree` is a double pointer to the root node of the AVL tree for inserting\n    the value\n  - Once inserted, the tree must be in a valid AVL Tree order\n  - Rebalancing of nodes is not allowed\n  - You can assume that `value` will be inserted in a binary search tree\n  - `value` won’t appear twice\n  - Return a pointer to the created node, or `NULL` on failure\n  - If the address stored in `tree` is `NULL`, the created node must become the\n    root node.\n\n### [32. AVL - Array to AVL](./122-array_to_avl.c)\n\n- Write a function that builds an AVL tree from an array\n  - Prototype: `avl_t *array_to_avl(int *array, size_t size);`\n  - `array` is a pointer to the first element of the array to be converted\n  - `size` is the number of element in the array\n  - Your function must return a pointer to the root node of the created AVL\n    tree, or `NULL` on failure\n  - If a value of the array is already present in the tree, this value must be\n    ignored\n\n### [33. AVL - Remove](./123-avl_remove.c)\n\n- Write a function that removes a node from an AVL tree\n  - Prototype: `avl_t *avl_remove(avl_t *root, int value);`\n  - `root` is a pointer to the root node of the tree for removing a node\n  - `value` is the value to remove in the tree\n  - Once located, the node containing a value equals to `value` must be removed\n    and freed\n  - If the node to be deleted is a leaf, it can be simply removed\n  - If the node to be deleted has only one child, it should be replaced by its\n    child\n  - When removing a node with two children, it must be replaced with its first\n    in-order successor (not predecessor)\n  - Your function must return a pointer to the new root node of the tree after\n    removing the desired value\n\n### [34. AVL - From sorted array](./124-sorted_array_to_avl.c)\n\n- Write a function that builds an AVL tree from an array\n  - Prototype: `avl_t *sorted_array_to_avl(int *array, size_t size);`\n  - `array` is a pointer to the first element of the array to be converted\n  - `size` is the number of element in the array\n  - Your function must return a pointer to the root node of the created AVL\n    tree, or `NULL` on failure\n  - You can assume there will be no duplicate value in the array\n  - You are not allowed to rotate\n  - You can only have 3 functions in your file\n\n### [35. Big O #AVL Tree](./125-O)\n\n- What are the average time complexities of those operations on an AVL Tree (one\n  answer per line):\n  - Inserting the value `n`\n  - Removing the node with the value `n`\n  - Searching for a node in an AVL tree of size `n`\n\n### [36. Is Binary heap](./130-binary_tree_is_heap.c)\n\n- Write a function that checks if a binary tree is a valid Max Binary Heap\n  - Prototype: `int binary_tree_is_heap(const binary_tree_t *tree);`\n  - `tree` is a pointer to the root node of the tree to check\n  - Your function must return `1` if `tree` is a valid Max Binary Heap, and `0`\n    otherwise\n  - If `tree` is `NULL`, return `0`\n\n### [37. Heap - Insert](./131-heap_insert.c)\n\n- Write a function that inserts a value in Max Binary Heap\n  - Prototype: `heap_t *heap_insert(heap_t **root, int value);`\n  - `root` is a double pointer to the root node of the Heap to insert the value\n  - Once inserted, the tree must be in Max Heap order\n  - You have to respect a `Max Heap` ordering\n  - You are allowed to have up to `6` functions in your file\n\n### [38. Heap - Array to Binary Heap](./132-array_to_heap.c)\n\n- Write a function that builds a Max Binary Heap tree from an array\n  - Prototype: `heap_t *array_to_heap(int *array, size_t size);`\n  - `array` is a pointer to the first element of the array to be converted\n  - `size` is the number of element in the array\n  - Your function must return a pointer to the root node of the created Binary\n    Heap, or `NULL` on failure\n  - If `array` is `NULL` or `size` is `0`, return `NULL`\n  - You can assume there will be no duplicate value in the array\n  - You are allowed to use `printf`\n\n### [39. Heap - Extract](./133-heap_extract.c)\n\n- Write a function that extracts the root node of a Max Binary Heap\n  - Prototype: `int heap_extract(heap_t **root);`\n  - `root` is a double pointer to the root node of the heap\n  - Your function must return the value stored in the root node\n  - The root node must be freed and replace with the last `level-order` node of\n    the heap\n  - Once replaced, the heap must be rebuilt if necessary\n  - If your function fails, return `0`\n\n### [40. Heap - Sort](./134-heap_to_sorted_array.c)\n\n- Write a function that converts a Binary Max Heap to a sorted array of integers\n  - Prototype: `int *heap_to_sorted_array(heap_t *heap, size_t *size);`\n  - `heap` is a pointer to the root node of the heap to convert\n  - `size` is the address to a variable containing the size of the array\n  - Your function must return an array containing all values stored in the heap\n    sorted in ascending order\n  - If your function fails, return `NULL`\n  - You can assume that `size` will be lower than `INT_MAX`\n  - You are allowed to use `malloc` and `free` only once (only one call)\n\n### [41. Big O #Binary Heap](./135-O)\n\n- What are the average time complexities of those operations on a Binary Heap\n  (one answer per line):\n  - Inserting the value `n`\n  - Extracting the root node\n  - Searching for a node in a binary heap of size `n`\n\n---\n\n## Author\n\n- [**Duncan Ngugi**](github.com/ngugimuchangi)\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngugimuchangi%2Fbinary_trees","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngugimuchangi%2Fbinary_trees","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngugimuchangi%2Fbinary_trees/lists"}