├── .2-binary_tree_insert_right.c.swp ├── .swp ├── 0-binary_tree_node.c ├── 0-main.c ├── 0-node ├── 1-binary_tree_insert_left.c ├── 1-left ├── 1-main.c ├── 10-binary_tree_depth.c ├── 10-depth ├── 10-main.c ├── 100-binary_trees_ancestor.c ├── 101-binary_tree_levelorder.c ├── 102-binary_tree_is_complete.c ├── 103-binary_tree_rotate_left.c ├── 104-binary_tree_rotate_right.c ├── 11-binary_tree_size.c ├── 110-binary_tree_is_bst.c ├── 111-bst_insert ├── 111-bst_insert.c ├── 111-main.c ├── 112-array_to_bst.c ├── 112-bst_array ├── 112-main.c ├── 113-bst_search ├── 113-bst_search.c ├── 113-main.c ├── 114-bst_remove.c ├── 114-bst_rm ├── 114-main.c ├── 115-O ├── 12-binary_tree_leaves.c ├── 120-binary_tree_is_avl.c ├── 120-is_avl ├── 120-main.c ├── 121-avl_insert ├── 121-avl_insert.c ├── 121-main.c ├── 122-array_to_avl.c ├── 122-avl_array ├── 122-main.c ├── 123-avl_remove.c ├── 123-avl_rm ├── 123-main.c ├── 125-O ├── 13-binary_tree_nodes.c ├── 135-O ├── 14-binary_tree_balance.c ├── 15-binary_tree_is_full.c ├── 16-binary_tree_is_perfect.c ├── 17-binary_tree_sibling.c ├── 18-binary_tree_uncle.c ├── 2-binary_tree_insert_right.c ├── 2-main.c ├── 2-right ├── 3-binary_tree_delete.c ├── 3-del ├── 3-main.c ├── 4-binary_tree_is_leaf.c ├── 4-leaf ├── 4-main.c ├── 5-binary_tree_is_root.c ├── 5-main.c ├── 5-root ├── 6-binary_tree_preorder.c ├── 6-main.c ├── 6-pre ├── 7-binary_tree_inorder.c ├── 7-in ├── 7-main.c ├── 8-binary_tree_postorder.c ├── 8-main.c ├── 8-post ├── 9-binary_tree_height.c ├── 9-height ├── 9-main.c ├── README.md ├── binary_tree_print.c └── binary_trees.h /.2-binary_tree_insert_right.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/.2-binary_tree_insert_right.c.swp -------------------------------------------------------------------------------- /.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/.swp -------------------------------------------------------------------------------- /0-binary_tree_node.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_node -A function that Creates a binary tree node. 5 | * @parent: - is a pointer to the parent node of the node to create 6 | * @value: - is the value to put in the new node 7 | * Return: If an error occurs - NULL. 8 | * Otherwise - a pointer to the new node. 9 | */ 10 | 11 | binary_tree_t *binary_tree_node(binary_tree_t *parent, int value) 12 | { 13 | binary_tree_t *new; 14 | 15 | new = malloc(sizeof(binary_tree_t)); 16 | if (new == NULL) 17 | return (NULL); 18 | 19 | new->n = value; 20 | new->parent = parent; 21 | new->left = NULL; 22 | new->right = NULL; 23 | 24 | return (new); 25 | } 26 | -------------------------------------------------------------------------------- /0-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "binary_trees.h" 3 | 4 | /** 5 | * main - Entry point 6 | * 7 | * Return: Always 0 (Success) 8 | */ 9 | int main(void) 10 | { 11 | binary_tree_t *root; 12 | 13 | root = binary_tree_node(NULL, 98); 14 | 15 | root->left = binary_tree_node(root, 12); 16 | root->left->left = binary_tree_node(root->left, 6); 17 | root->left->right = binary_tree_node(root->left, 16); 18 | 19 | root->right = binary_tree_node(root, 402); 20 | root->right->left = binary_tree_node(root->right, 256); 21 | root->right->right = binary_tree_node(root->right, 512); 22 | 23 | binary_tree_print(root); 24 | return (0); 25 | } 26 | -------------------------------------------------------------------------------- /0-node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/0-node -------------------------------------------------------------------------------- /1-binary_tree_insert_left.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_insert_left - Function that Inserts a node as the left-child. 5 | * @parent: - is a pointer to the parent node of the node to create 6 | * @value: - is the value to put in the new node 7 | * Description - If parent has a left-child, the new node must take its place. 8 | * Return: a pointer to the created node, or NULL on failure. 9 | */ 10 | 11 | binary_tree_t *binary_tree_insert_left(binary_tree_t *parent, int value) 12 | { 13 | binary_tree_t *new_tree; 14 | 15 | if (!parent) 16 | return (NULL); 17 | 18 | new_tree = malloc(sizeof(binary_tree_t)); 19 | if (!new_tree) 20 | return (NULL); 21 | 22 | new_tree->n = value; 23 | new_tree->parent = parent; 24 | new_tree->right = NULL; 25 | new_tree->left = parent->left; 26 | parent->left = new_tree; 27 | if (new_tree->left) 28 | new_tree->left->parent = new_tree; 29 | return (new_tree); 30 | } 31 | -------------------------------------------------------------------------------- /1-left: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/1-left -------------------------------------------------------------------------------- /1-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: Always 0 (Success) 9 | */ 10 | int main(void) 11 | { 12 | binary_tree_t *root; 13 | 14 | root = binary_tree_node(NULL, 98); 15 | root->left = binary_tree_node(root, 12); 16 | root->right = binary_tree_node(root, 402); 17 | binary_tree_print(root); 18 | printf("\n"); 19 | binary_tree_insert_left(root->right, 128); 20 | binary_tree_insert_left(root, 54); 21 | binary_tree_print(root); 22 | return (0); 23 | } 24 | -------------------------------------------------------------------------------- /10-binary_tree_depth.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_depth - a function that measures the depth 5 | * of a node in a binary tree. 6 | * @tree: is a pointer to the node to measure the depth. 7 | * Return: If tree is NULL, your function must 8 | * return 0, else return the depth. 9 | */ 10 | 11 | size_t binary_tree_depth(const binary_tree_t *tree) 12 | { 13 | return ((tree && tree->parent) ? 1 + binary_tree_depth(tree->parent) : 0); 14 | } 15 | -------------------------------------------------------------------------------- /10-depth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/10-depth -------------------------------------------------------------------------------- /10-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: Always 0 (Success) 9 | */ 10 | int main(void) 11 | { 12 | binary_tree_t *root; 13 | size_t depth; 14 | 15 | root = binary_tree_node(NULL, 98); 16 | root->left = binary_tree_node(root, 12); 17 | root->right = binary_tree_node(root, 402); 18 | binary_tree_insert_right(root->left, 54); 19 | binary_tree_insert_right(root, 128); 20 | binary_tree_print(root); 21 | 22 | depth = binary_tree_depth(root); 23 | printf("Depth of %d: %lu\n", root->n, depth); 24 | depth = binary_tree_depth(root->right); 25 | printf("Depth of %d: %lu\n", root->right->n, depth); 26 | depth = binary_tree_depth(root->left->right); 27 | printf("Depth of %d: %lu\n", root->left->right->n, depth); 28 | return (0); 29 | } 30 | -------------------------------------------------------------------------------- /100-binary_trees_ancestor.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | size_t depth(const binary_tree_t *tree); 4 | 5 | /** 6 | * binary_trees_ancestor - Finds the lowest common ancestor of two nodes. 7 | * @first: Pointer to the first node. 8 | * @second: Pointer to second node. 9 | * Return: If no common ancestors return NULL, else return common ancestor. 10 | */ 11 | binary_tree_t *binary_trees_ancestor(const binary_tree_t *first, 12 | const binary_tree_t *second) 13 | { 14 | size_t first_depth, second_depth; 15 | 16 | if (first == NULL || second == NULL) 17 | return (NULL); 18 | if (first == second) 19 | return ((binary_tree_t *)first); 20 | if (first->parent == second->parent) 21 | return ((binary_tree_t *)first->parent); 22 | if (first == second->parent) 23 | return ((binary_tree_t *)first); 24 | if (first->parent == second) 25 | return ((binary_tree_t *)second); 26 | 27 | for (first_depth = depth(first); first_depth > 1; first_depth--) 28 | first = first->parent; 29 | for (second_depth = depth(second); second_depth > 1; second_depth--) 30 | second = second->parent; 31 | 32 | if (first == second) 33 | return ((binary_tree_t *)first); 34 | if (first->parent == second->parent) 35 | return ((binary_tree_t *)first->parent); 36 | if (first == second->parent) 37 | return ((binary_tree_t *)first); 38 | if (first->parent == second) 39 | return ((binary_tree_t *)second); 40 | else 41 | return (NULL); 42 | } 43 | 44 | /** 45 | * depth - Measures the depth of a node in a binary tree. 46 | * @tree: A pointer to the node to measure the depth. 47 | * 48 | * Return: If tree is NULL, your function must return 0, else return the depth. 49 | */ 50 | size_t depth(const binary_tree_t *tree) 51 | { 52 | return ((tree->parent != NULL) ? 1 + depth(tree->parent) : 0); 53 | } 54 | -------------------------------------------------------------------------------- /101-binary_tree_levelorder.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | levelorder_queue_t *create_node(binary_tree_t *node); 4 | void free_queue(levelorder_queue_t *head); 5 | void pint_push(binary_tree_t *node, levelorder_queue_t *head, 6 | levelorder_queue_t **tail, void (*func)(int)); 7 | void pop(levelorder_queue_t **head); 8 | void binary_tree_levelorder(const binary_tree_t *tree, void (*func)(int)); 9 | 10 | /** 11 | * create_node - Creates a new levelorder_queue_t node. 12 | * @node: The binary tree node for the new node to contain. 13 | * Return: If an error occurs, NULL. 14 | * Otherwise, a pointer to the new node. 15 | */ 16 | levelorder_queue_t *create_node(binary_tree_t *node) 17 | { 18 | levelorder_queue_t *new; 19 | 20 | new = malloc(sizeof(levelorder_queue_t)); 21 | if (new == NULL) 22 | return (NULL); 23 | 24 | new->node = node; 25 | new->next = NULL; 26 | 27 | return (new); 28 | } 29 | 30 | /** 31 | * free_queue - Frees a levelorder_queue_t queue. 32 | * @head: A pointer to the head of the queue. 33 | */ 34 | void free_queue(levelorder_queue_t *head) 35 | { 36 | levelorder_queue_t *tmp; 37 | 38 | while (head != NULL) 39 | { 40 | tmp = head->next; 41 | free(head); 42 | head = tmp; 43 | } 44 | } 45 | 46 | /** 47 | * pint_push - Runs a function on a given binary tree node and 48 | * pushes its children into a levelorder_queue_t queue. 49 | * @node: The binary tree node to print and push. 50 | * @head: A double pointer to the head of the queue. 51 | * @tail: A double pointer to the tail of the queue. 52 | * @func: A pointer to the function to call on @node. 53 | * 54 | * Description: Upon malloc failure, exits with a status code of 1. 55 | */ 56 | void pint_push(binary_tree_t *node, levelorder_queue_t *head, 57 | levelorder_queue_t **tail, void (*func)(int)) 58 | { 59 | levelorder_queue_t *new; 60 | 61 | func(node->n); 62 | if (node->left != NULL) 63 | { 64 | new = create_node(node->left); 65 | if (new == NULL) 66 | { 67 | free_queue(head); 68 | exit(1); 69 | } 70 | (*tail)->next = new; 71 | *tail = new; 72 | } 73 | if (node->right != NULL) 74 | { 75 | new = create_node(node->right); 76 | if (new == NULL) 77 | { 78 | free_queue(head); 79 | exit(1); 80 | } 81 | (*tail)->next = new; 82 | *tail = new; 83 | } 84 | } 85 | 86 | /** 87 | * pop - Pops the head of a levelorder_queue_t queue. 88 | * @head: A double pointer to the head of the queue. 89 | */ 90 | void pop(levelorder_queue_t **head) 91 | { 92 | levelorder_queue_t *tmp; 93 | 94 | tmp = (*head)->next; 95 | free(*head); 96 | *head = tmp; 97 | } 98 | 99 | /** 100 | * binary_tree_levelorder - Traverses a binary tree using 101 | * level-order traversal. 102 | * @tree: A pointer to the root node of the tree to traverse. 103 | * @func: A pointer to a function to call for each node. 104 | */ 105 | void binary_tree_levelorder(const binary_tree_t *tree, void (*func)(int)) 106 | { 107 | levelorder_queue_t *head, *tail; 108 | 109 | if (tree == NULL || func == NULL) 110 | return; 111 | 112 | head = tail = create_node((binary_tree_t *)tree); 113 | if (head == NULL) 114 | return; 115 | 116 | while (head != NULL) 117 | { 118 | pint_push(head->node, head, &tail, func); 119 | pop(&head); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /102-binary_tree_is_complete.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | levelorder_queue_t *create_node(binary_tree_t *node); 4 | void free_queue(levelorder_queue_t *head); 5 | void push(binary_tree_t *node, levelorder_queue_t *head, 6 | levelorder_queue_t **tail); 7 | void pop(levelorder_queue_t **head); 8 | int binary_tree_is_complete(const binary_tree_t *tree); 9 | 10 | /** 11 | * create_node - Create the new levelorder_queue_t node. 12 | * @node: The binary tree node for a new node to contain. 13 | * 14 | * Return: If an error occurs, NULL. 15 | * Otherwise, a pointer to the new node. 16 | */ 17 | levelorder_queue_t *create_node(binary_tree_t *node) 18 | { 19 | levelorder_queue_t *new; 20 | 21 | new = malloc(sizeof(levelorder_queue_t)); 22 | if (new == NULL) 23 | return (NULL); 24 | 25 | new->node = node; 26 | new->next = NULL; 27 | 28 | return (new); 29 | } 30 | 31 | /** 32 | * free_queue - Frees a levelorder_queue_t queue. 33 | * @head: A pointer to the head of the queue. 34 | */ 35 | void free_queue(levelorder_queue_t *head) 36 | { 37 | levelorder_queue_t *tmp; 38 | 39 | while (head != NULL) 40 | { 41 | tmp = head->next; 42 | free(head); 43 | head = tmp; 44 | } 45 | } 46 | 47 | /** 48 | * push - Pushes a node to the back of a levelorder_queue_t queue. 49 | * @node: The binary tree node to print and push. 50 | * @head: A double pointer to the head of the queue. 51 | * @tail: A double pointer to the tail of the queue. 52 | * 53 | * Description: Upon malloc failure, exits with a status code of 1. 54 | */ 55 | void push(binary_tree_t *node, levelorder_queue_t *head, 56 | levelorder_queue_t **tail) 57 | { 58 | levelorder_queue_t *new; 59 | 60 | new = create_node(node); 61 | if (new == NULL) 62 | { 63 | free_queue(head); 64 | exit(1); 65 | } 66 | (*tail)->next = new; 67 | *tail = new; 68 | } 69 | 70 | /** 71 | * pop - Pops the head of a levelorder_queue_t queue. 72 | * @head: A double pointer to the head of the queue. 73 | */ 74 | void pop(levelorder_queue_t **head) 75 | { 76 | levelorder_queue_t *tmp; 77 | 78 | tmp = (*head)->next; 79 | free(*head); 80 | *head = tmp; 81 | } 82 | 83 | /** 84 | * binary_tree_is_complete - Checks if a binary tree is complete. 85 | * @tree: A pointer to the root node of the tree to traverse. 86 | * 87 | * Return: If the tree is NULL or not complete, 0. 88 | * Otherwise, 1. 89 | * 90 | * Description: Upon malloc failure, exits with a status code of 1. 91 | */ 92 | int binary_tree_is_complete(const binary_tree_t *tree) 93 | { 94 | levelorder_queue_t *head, *tail; 95 | unsigned char flag = 0; 96 | 97 | if (tree == NULL) 98 | return (0); 99 | 100 | head = tail = create_node((binary_tree_t *)tree); 101 | if (head == NULL) 102 | exit(1); 103 | 104 | while (head != NULL) 105 | { 106 | if (head->node->left != NULL) 107 | { 108 | if (flag == 1) 109 | { 110 | free_queue(head); 111 | return (0); 112 | } 113 | push(head->node->left, head, &tail); 114 | } 115 | else 116 | flag = 1; 117 | if (head->node->right != NULL) 118 | { 119 | if (flag == 1) 120 | { 121 | free_queue(head); 122 | return (0); 123 | } 124 | push(head->node->right, head, &tail); 125 | } 126 | else 127 | flag = 1; 128 | pop(&head); 129 | } 130 | return (1); 131 | } 132 | -------------------------------------------------------------------------------- /103-binary_tree_rotate_left.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_rotate_left - Left-rotates a binary tree. 5 | * @tree: A pointer to a root node of the tree to rotate. 6 | * Return: A pointer to a new root node after rotation. 7 | */ 8 | binary_tree_t *binary_tree_rotate_left(binary_tree_t *tree) 9 | { 10 | binary_tree_t *pivot, *tmp; 11 | 12 | if (tree == NULL || tree->right == NULL) 13 | return (NULL); 14 | 15 | pivot = tree->right; 16 | tmp = pivot->left; 17 | pivot->left = tree; 18 | tree->right = tmp; 19 | if (tmp != NULL) 20 | tmp->parent = tree; 21 | tmp = tree->parent; 22 | tree->parent = pivot; 23 | pivot->parent = tmp; 24 | if (tmp != NULL) 25 | { 26 | if (tmp->left == tree) 27 | tmp->left = pivot; 28 | else 29 | tmp->right = pivot; 30 | } 31 | 32 | return (pivot); 33 | } 34 | -------------------------------------------------------------------------------- /104-binary_tree_rotate_right.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_rotate_right - Right-rotates a binary tree. 5 | * @tree: A pointer to a root node of the tree to rotate. 6 | * Return: A pointer to the new root node after rotation. 7 | */ 8 | binary_tree_t *binary_tree_rotate_right(binary_tree_t *tree) 9 | { 10 | binary_tree_t *pivot, *tmp; 11 | 12 | if (tree == NULL || tree->left == NULL) 13 | return (NULL); 14 | 15 | pivot = tree->left; 16 | tmp = pivot->right; 17 | pivot->right = tree; 18 | tree->left = tmp; 19 | if (tmp != NULL) 20 | tmp->parent = tree; 21 | tmp = tree->parent; 22 | tree->parent = pivot; 23 | pivot->parent = tmp; 24 | if (tmp != NULL) 25 | { 26 | if (tmp->left == tree) 27 | tmp->left = pivot; 28 | else 29 | tmp->right = pivot; 30 | } 31 | 32 | return (pivot); 33 | } 34 | -------------------------------------------------------------------------------- /11-binary_tree_size.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_size - a function that measures the size of a binary tree. 5 | * @tree: is a pointer to the root node of the tree to measure the size. 6 | * Return: 0. 7 | */ 8 | 9 | size_t binary_tree_size(const binary_tree_t *tree) 10 | { 11 | size_t size = 0; 12 | 13 | if (tree) 14 | { 15 | size += 1; 16 | size += binary_tree_size(tree->left); 17 | size += binary_tree_size(tree->right); 18 | } 19 | return (size); 20 | } 21 | -------------------------------------------------------------------------------- /110-binary_tree_is_bst.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | #include "limits.h" 3 | 4 | /** 5 | * is_bst_helper - Checks if a binary tree is a valid binary search tree. 6 | * @tree: A pointer to the root node of the tree to check. 7 | * @lo: The value of a smallest node visited thus far. 8 | * @hi: The value of a largest node visited this far. 9 | * Return: If the tree is a valid BST, 1, otherwise, 0. 10 | */ 11 | int is_bst_helper(const binary_tree_t *tree, int lo, int hi) 12 | { 13 | if (tree != NULL) 14 | { 15 | if (tree->n < lo || tree->n > hi) 16 | return (0); 17 | return (is_bst_helper(tree->left, lo, tree->n - 1) && 18 | is_bst_helper(tree->right, tree->n + 1, hi)); 19 | } 20 | return (1); 21 | } 22 | 23 | /** 24 | * binary_tree_is_bst - Checks if a binary tree is a valid binary search tree. 25 | * @tree: A pointer to the root node of the tree to check. 26 | * 27 | * Return: 1 if tree is a valid BST, and 0 otherwise 28 | */ 29 | int binary_tree_is_bst(const binary_tree_t *tree) 30 | { 31 | if (tree == NULL) 32 | return (0); 33 | return (is_bst_helper(tree, INT_MIN, INT_MAX)); 34 | } 35 | -------------------------------------------------------------------------------- /111-bst_insert: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/111-bst_insert -------------------------------------------------------------------------------- /111-bst_insert.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * bst_insert - a function that inserts a value in a Binary Search Tree. 5 | * @tree: is a double pointer to the root node of the BST to insert the value. 6 | * @value: is the value to store in the node to be inserted. 7 | * Return: A pointer to the created node, or NULL on failure. 8 | */ 9 | 10 | bst_t *bst_insert(bst_t **tree, int value) 11 | { 12 | bst_t *curr, *new; 13 | 14 | if (tree != NULL) 15 | { 16 | curr = *tree; 17 | 18 | if (curr == NULL) 19 | { 20 | new = binary_tree_node(curr, value); 21 | if (new == NULL) 22 | return (NULL); 23 | return (*tree = new); 24 | } 25 | 26 | if (value < curr->n) 27 | { 28 | if (curr->left != NULL) 29 | return (bst_insert(&curr->left, value)); 30 | 31 | new = binary_tree_node(curr, value); 32 | if (new == NULL) 33 | return (NULL); 34 | return (curr->left = new); 35 | } 36 | if (value > curr->n) 37 | { 38 | if (curr->right != NULL) 39 | return (bst_insert(&curr->right, value)); 40 | 41 | new = binary_tree_node(curr, value); 42 | if (new == NULL) 43 | return (NULL); 44 | return (curr->right = new); 45 | } 46 | } 47 | return (NULL); 48 | } 49 | -------------------------------------------------------------------------------- /111-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: Always 0 (Success) 9 | */ 10 | int main(void) 11 | { 12 | bst_t *root; 13 | bst_t *node; 14 | 15 | root = NULL; 16 | node = bst_insert(&root, 98); 17 | printf("Inserted: %d\n", node->n); 18 | node = bst_insert(&root, 402); 19 | printf("Inserted: %d\n", node->n); 20 | node = bst_insert(&root, 12); 21 | printf("Inserted: %d\n", node->n); 22 | node = bst_insert(&root, 46); 23 | printf("Inserted: %d\n", node->n); 24 | node = bst_insert(&root, 128); 25 | printf("Inserted: %d\n", node->n); 26 | node = bst_insert(&root, 256); 27 | printf("Inserted: %d\n", node->n); 28 | node = bst_insert(&root, 512); 29 | printf("Inserted: %d\n", node->n); 30 | node = bst_insert(&root, 1); 31 | printf("Inserted: %d\n", node->n); 32 | node = bst_insert(&root, 128); 33 | printf("Node should be nil -> %p\n", (void *)node); 34 | binary_tree_print(root); 35 | return (0); 36 | } 37 | -------------------------------------------------------------------------------- /112-array_to_bst.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * array_to_bst - a function that builds a Binary Search Tree from an array. 5 | * @array: is a pointer to the first element of the array to be converted. 6 | * @size: is the number of element in the array. 7 | * Return: A pointer to the root node of the created BST, or NULL upon failure. 8 | */ 9 | 10 | bst_t *array_to_bst(int *array, size_t size) 11 | { 12 | bst_t *tree = NULL; 13 | size_t i, j; 14 | 15 | if (array == NULL) 16 | return (NULL); 17 | 18 | for (i = 0; i < size; i++) 19 | { 20 | for (j = 0; j < i; j++) 21 | { 22 | if (array[j] == array[i]) 23 | break; 24 | } 25 | if (j == i) 26 | { 27 | if (bst_insert(&tree, array[i]) == NULL) 28 | return (NULL); 29 | } 30 | } 31 | 32 | return (tree); 33 | } 34 | -------------------------------------------------------------------------------- /112-bst_array: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/112-bst_array -------------------------------------------------------------------------------- /112-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "binary_trees.h" 3 | 4 | /** 5 | * main - Entry point 6 | * 7 | * Return: 0 on success, error code on failure 8 | */ 9 | int main(void) 10 | { 11 | bst_t *tree; 12 | int array[] = { 13 | 79, 47, 68, 87, 84, 91, 21, 32, 34, 2, 14 | 20, 22, 98, 1, 62, 95 15 | }; 16 | size_t n = sizeof(array) / sizeof(array[0]); 17 | 18 | tree = array_to_bst(array, n); 19 | if (!tree) 20 | return (1); 21 | binary_tree_print(tree); 22 | return (0); 23 | } 24 | -------------------------------------------------------------------------------- /113-bst_search: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/113-bst_search -------------------------------------------------------------------------------- /113-bst_search.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * bst_search - a function that searches for a value in a Binary Search Tree. 5 | * @tree: is a pointer to the root node of the BST to search. 6 | * @value: is the value to search in the tree. 7 | * Return: If tree is NULL or if nothing is found, 8 | * your function must return NULL. 9 | */ 10 | 11 | bst_t *bst_search(const bst_t *tree, int value) 12 | { 13 | if (tree != NULL) 14 | { 15 | if (tree->n == value) 16 | return ((bst_t *)tree); 17 | if (tree->n > value) 18 | return (bst_search(tree->left, value)); 19 | return (bst_search(tree->right, value)); 20 | } 21 | return (NULL); 22 | } 23 | -------------------------------------------------------------------------------- /113-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: 0 on success, error code on failure 9 | */ 10 | int main(void) 11 | { 12 | bst_t *tree; 13 | int array[] = { 14 | 79, 47, 68, 87, 84, 91, 21, 32, 34, 2, 15 | 20, 22, 98, 1, 62, 95 16 | }; 17 | size_t n = sizeof(array) / sizeof(array[0]); 18 | bst_t *node; 19 | 20 | tree = array_to_bst(array, n); 21 | if (!tree) 22 | return (1); 23 | binary_tree_print(tree); 24 | node = bst_search(tree, 32); 25 | printf("Found: %d\n", node->n); 26 | binary_tree_print(node); 27 | node = bst_search(tree, 512); 28 | printf("Node should be nil -> %p\n", (void *)node); 29 | return (0); 30 | } 31 | -------------------------------------------------------------------------------- /114-bst_remove.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | bst_t *inorder_successor(bst_t *root); 4 | bst_t *bst_delete(bst_t *root, bst_t *node); 5 | bst_t *bst_remove_recursive(bst_t *root, bst_t *node, int value); 6 | bst_t *bst_remove(bst_t *root, int value); 7 | 8 | /** 9 | * inorder_successor - A function Returns the minimum value 10 | * of a binary search tree. 11 | * @root: is a pointer to the root node of the BST to search. 12 | * Return: The minimum value in @tree. 13 | */ 14 | 15 | bst_t *inorder_successor(bst_t *root) 16 | { 17 | while (root->left != NULL) 18 | root = root->left; 19 | return (root); 20 | } 21 | 22 | /** 23 | * bst_delete -A function Deletes a node from a binary search tree. 24 | * @root: is a pointer to the root node of the BST. 25 | * @node: is a pointer to the node to delete from the BST. 26 | * Return: A pointer to the new root node after deletion. 27 | */ 28 | 29 | bst_t *bst_delete(bst_t *root, bst_t *node) 30 | { 31 | bst_t *parent = node->parent, *successor = NULL; 32 | 33 | /* No children or right-child only */ 34 | if (node->left == NULL) 35 | { 36 | if (parent != NULL && parent->left == node) 37 | parent->left = node->right; 38 | else if (parent != NULL) 39 | parent->right = node->right; 40 | if (node->right != NULL) 41 | node->right->parent = parent; 42 | free(node); 43 | return (parent == NULL ? node->right : root); 44 | } 45 | 46 | /* Left-child only */ 47 | if (node->right == NULL) 48 | { 49 | if (parent != NULL && parent->left == node) 50 | parent->left = node->left; 51 | else if (parent != NULL) 52 | parent->right = node->left; 53 | if (node->left != NULL) 54 | node->left->parent = parent; 55 | free(node); 56 | return (parent == NULL ? node->left : root); 57 | } 58 | 59 | /* Two children */ 60 | successor = inorder_successor(node->right); 61 | node->n = successor->n; 62 | 63 | return (bst_delete(root, successor)); 64 | } 65 | 66 | /** 67 | * bst_remove_recursive - A function that Removes a node from 68 | * a binary search tree recursively. 69 | * @root: is a pointer to the root node of the BST to remove a node from. 70 | * @node: is a pointer to the current node in the BST. 71 | * @value: The value to remove from the BST. 72 | * Return: A pointer to the root node after deletion. 73 | */ 74 | 75 | bst_t *bst_remove_recursive(bst_t *root, bst_t *node, int value) 76 | { 77 | if (node != NULL) 78 | { 79 | if (node->n == value) 80 | return (bst_delete(root, node)); 81 | if (node->n > value) 82 | return (bst_remove_recursive(root, node->left, value)); 83 | return (bst_remove_recursive(root, node->right, value)); 84 | } 85 | return (NULL); 86 | } 87 | 88 | /** 89 | * bst_remove - A function that Removes a node from a binary search tree. 90 | * @root: is a pointer to the root node of the BST to remove a node from. 91 | * @value: The value to remove in the BST. 92 | * Return: A pointer to the new root node after deletion. 93 | */ 94 | 95 | bst_t *bst_remove(bst_t *root, int value) 96 | { 97 | return (bst_remove_recursive(root, root, value)); 98 | } 99 | -------------------------------------------------------------------------------- /114-bst_rm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/114-bst_rm -------------------------------------------------------------------------------- /114-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: 0 on success, error code on failure 9 | */ 10 | int main(void) 11 | { 12 | bst_t *tree; 13 | int array[] = { 14 | 79, 47, 68, 87, 84, 91, 21, 32, 34, 2, 15 | 20, 22, 98, 1, 62, 95 16 | }; 17 | size_t n = sizeof(array) / sizeof(array[0]); 18 | 19 | tree = array_to_bst(array, n); 20 | if (!tree) 21 | return (1); 22 | binary_tree_print(tree); 23 | 24 | tree = bst_remove(tree, 79); 25 | printf("Removed 79...\n"); 26 | binary_tree_print(tree); 27 | 28 | tree = bst_remove(tree, 21); 29 | printf("Removed 21...\n"); 30 | binary_tree_print(tree); 31 | 32 | tree = bst_remove(tree, 68); 33 | printf("Removed 68...\n"); 34 | binary_tree_print(tree); 35 | binary_tree_delete(tree); 36 | return (0); 37 | } 38 | -------------------------------------------------------------------------------- /115-O: -------------------------------------------------------------------------------- 1 | O(log(n)) 2 | O(log(n)) 3 | O(log(n)) 4 | -------------------------------------------------------------------------------- /12-binary_tree_leaves.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_leaves - Counts leaves in a binary tree. 5 | * @tree: A pointer to the root node of the tree to count the leaves of. 6 | * Return: leaves in the tree. 7 | */ 8 | 9 | size_t binary_tree_leaves(const binary_tree_t *tree) 10 | { 11 | size_t leaves = 0; 12 | 13 | if (tree) 14 | { 15 | leaves += (!tree->left && !tree->right) ? 1 : 0; 16 | leaves += binary_tree_leaves(tree->left); 17 | leaves += binary_tree_leaves(tree->right); 18 | } 19 | return (leaves); 20 | } 21 | -------------------------------------------------------------------------------- /120-binary_tree_is_avl.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | #include "limits.h" 3 | 4 | size_t height(const binary_tree_t *tree); 5 | int is_avl_helper(const binary_tree_t *tree, int lo, int hi); 6 | int binary_tree_is_avl(const binary_tree_t *tree); 7 | 8 | /** 9 | * height - A function that Measures the height of a binary tree. 10 | * @tree: is pointer to the root node of the tree to measure the height. 11 | * Return: If tree is NULL, your function must return 0, else return height. 12 | */ 13 | 14 | size_t height(const binary_tree_t *tree) 15 | { 16 | if (tree) 17 | { 18 | size_t l = 0, r = 0; 19 | 20 | l = tree->left ? 1 + height(tree->left) : 1; 21 | r = tree->right ? 1 + height(tree->right) : 1; 22 | return ((l > r) ? l : r); 23 | } 24 | return (0); 25 | } 26 | 27 | /** 28 | * is_avl_helper - A function that Checks if a binary tree 29 | * is a valid AVL tree. 30 | * @tree: is a pointer to the root node of the tree to check. 31 | * @lo: The value of the smallest node visited thus far. 32 | * @hi: The value of the largest node visited this far. 33 | * Return: If the tree is a valid AVL tree, 1, otherwise, 0. 34 | */ 35 | 36 | int is_avl_helper(const binary_tree_t *tree, int lo, int hi) 37 | { 38 | size_t lhgt, rhgt, diff; 39 | 40 | if (tree != NULL) 41 | { 42 | if (tree->n < lo || tree->n > hi) 43 | return (0); 44 | lhgt = height(tree->left); 45 | rhgt = height(tree->right); 46 | diff = lhgt > rhgt ? lhgt - rhgt : rhgt - lhgt; 47 | if (diff > 1) 48 | return (0); 49 | return (is_avl_helper(tree->left, lo, tree->n - 1) && 50 | is_avl_helper(tree->right, tree->n + 1, hi)); 51 | } 52 | return (1); 53 | } 54 | 55 | /** 56 | * binary_tree_is_avl - A function that Checks if 57 | * a binary tree is a valid AVL tree. 58 | * @tree: is a pointer to the root node of the tree to check. 59 | * Return: 1 if tree is a valid AVL tree, and 0 otherwise 60 | */ 61 | 62 | int binary_tree_is_avl(const binary_tree_t *tree) 63 | { 64 | if (tree == NULL) 65 | return (0); 66 | return (is_avl_helper(tree, INT_MIN, INT_MAX)); 67 | } 68 | -------------------------------------------------------------------------------- /120-is_avl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/120-is_avl -------------------------------------------------------------------------------- /120-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * basic_tree - Build a basic binary tree 7 | * 8 | * Return: A pointer to the created tree 9 | */ 10 | binary_tree_t *basic_tree(void) 11 | { 12 | binary_tree_t *root; 13 | 14 | root = binary_tree_node(NULL, 98); 15 | root->left = binary_tree_node(root, 12); 16 | root->right = binary_tree_node(root, 128); 17 | root->left->right = binary_tree_node(root->left, 54); 18 | root->right->right = binary_tree_node(root, 402); 19 | root->left->left = binary_tree_node(root->left, 10); 20 | return (root); 21 | } 22 | 23 | /** 24 | * main - Entry point 25 | * 26 | * Return: Always 0 (Success) 27 | */ 28 | int main(void) 29 | { 30 | binary_tree_t *root; 31 | int avl; 32 | 33 | root = basic_tree(); 34 | 35 | binary_tree_print(root); 36 | avl = binary_tree_is_avl(root); 37 | printf("Is %d avl: %d\n", root->n, avl); 38 | avl = binary_tree_is_avl(root->left); 39 | printf("Is %d avl: %d\n", root->left->n, avl); 40 | 41 | root->right->left = binary_tree_node(root->right, 97); 42 | binary_tree_print(root); 43 | avl = binary_tree_is_avl(root); 44 | printf("Is %d avl: %d\n", root->n, avl); 45 | 46 | root = basic_tree(); 47 | root->right->right->right = binary_tree_node(root->right->right, 430); 48 | binary_tree_print(root); 49 | avl = binary_tree_is_avl(root); 50 | printf("Is %d avl: %d\n", root->n, avl); 51 | 52 | root->right->right->right->left = binary_tree_node(root->right->right->right, 420); 53 | binary_tree_print(root); 54 | avl = binary_tree_is_avl(root); 55 | printf("Is %d avl: %d\n", root->n, avl); 56 | return (0); 57 | } 58 | -------------------------------------------------------------------------------- /121-avl_insert: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/121-avl_insert -------------------------------------------------------------------------------- /121-avl_insert.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | size_t height(const binary_tree_t *tree); 4 | int balance(const binary_tree_t *tree); 5 | avl_t *avl_insert_recursive(avl_t **tree, avl_t *parent, 6 | avl_t **new, int value); 7 | avl_t *avl_insert(avl_t **tree, int value); 8 | 9 | /** 10 | * height - Measures the height of a binary tree. 11 | * @tree: A pointer to the root node of the tree to measure the height. 12 | * 13 | * Return: If tree is NULL, your function must return 0, else return height. 14 | */ 15 | size_t height(const binary_tree_t *tree) 16 | { 17 | if (tree != NULL) 18 | { 19 | size_t l = 0, r = 0; 20 | 21 | l = tree->left ? 1 + binary_tree_height(tree->left) : 1; 22 | r = tree->right ? 1 + binary_tree_height(tree->right) : 1; 23 | return ((l > r) ? l : r); 24 | } 25 | return (0); 26 | } 27 | 28 | /** 29 | * balance - Measures the balance factor of a binary tree. 30 | * @tree: A pointer to the root node of the tree to measure the balance factor. 31 | * 32 | * Return: If tree is NULL, return 0, else return balance factor. 33 | */ 34 | int balance(const binary_tree_t *tree) 35 | { 36 | return (tree != NULL ? height(tree->left) - height(tree->right) : 0); 37 | } 38 | 39 | /** 40 | * avl_insert_recursive - a function that Inserts a value 41 | * into an AVL tree recursively. 42 | * @tree: is a double pointer to the root node of 43 | * the AVL tree to insert into. 44 | * @parent: The parent node of the current working node. 45 | * @new: is a double pointer to store the new node. 46 | * @value: The value to insert into the AVL tree. 47 | * Return: A pointer to the new root 48 | * after insertion, or NULL on failure. 49 | */ 50 | 51 | avl_t *avl_insert_recursive(avl_t **tree, avl_t *parent, 52 | avl_t **new, int value) 53 | { 54 | int b_factor; 55 | 56 | if (*tree == NULL) 57 | return (*new = binary_tree_node(parent, value)); 58 | 59 | if ((*tree)->n > value) 60 | { 61 | (*tree)->left = avl_insert_recursive(&(*tree)->left, *tree, new, value); 62 | if ((*tree)->left == NULL) 63 | return (NULL); 64 | } 65 | else if ((*tree)->n < value) 66 | { 67 | (*tree)->right = avl_insert_recursive(&(*tree)->right, *tree, new, value); 68 | if ((*tree)->right == NULL) 69 | return (NULL); 70 | } 71 | else 72 | return (*tree); 73 | 74 | b_factor = balance(*tree); 75 | if (b_factor > 1 && (*tree)->left->n > value) 76 | *tree = binary_tree_rotate_right(*tree); 77 | else if (b_factor < -1 && (*tree)->right->n < value) 78 | *tree = binary_tree_rotate_left(*tree); 79 | else if (b_factor > 1 && (*tree)->left->n < value) 80 | { 81 | (*tree)->left = binary_tree_rotate_left((*tree)->left); 82 | *tree = binary_tree_rotate_right(*tree); 83 | } 84 | else if (b_factor < -1 && (*tree)->right->n > value) 85 | { 86 | (*tree)->right = binary_tree_rotate_right((*tree)->right); 87 | *tree = binary_tree_rotate_left(*tree); 88 | } 89 | 90 | return (*tree); 91 | } 92 | 93 | /** 94 | * avl_insert - Is a function that Inserts a value into an AVL tree. 95 | * @tree: Is a double pointer to the root node of the AVL tree to insert into. 96 | * @value: The value to insert into the AVL tree. 97 | * Return: A pointer to the inserted node, or NULL on failure. 98 | */ 99 | 100 | avl_t *avl_insert(avl_t **tree, int value) 101 | { 102 | avl_t *new = NULL; 103 | 104 | if (tree == NULL) 105 | return (NULL); 106 | if (*tree == NULL) 107 | { 108 | *tree = binary_tree_node(NULL, value); 109 | return (*tree); 110 | } 111 | avl_insert_recursive(tree, *tree, &new, value); 112 | return (new); 113 | } 114 | -------------------------------------------------------------------------------- /121-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: 0 on success, error code on failure 9 | */ 10 | int main(void) 11 | { 12 | avl_t *root; 13 | avl_t *node; 14 | 15 | root = NULL; 16 | node = avl_insert(&root, 98); 17 | printf("Inserted: %d\n", node->n); 18 | binary_tree_print(root); 19 | node = avl_insert(&root, 402); 20 | printf("\nInserted: %d\n", node->n); 21 | binary_tree_print(root); 22 | node = avl_insert(&root, 12); 23 | printf("\nInserted: %d\n", node->n); 24 | binary_tree_print(root); 25 | node = avl_insert(&root, 46); 26 | printf("\nInserted: %d\n", node->n); 27 | binary_tree_print(root); 28 | node = avl_insert(&root, 128); 29 | printf("\nInserted: %d\n", node->n); 30 | binary_tree_print(root); 31 | node = avl_insert(&root, 256); 32 | printf("\nInserted: %d\n", node->n); 33 | binary_tree_print(root); 34 | node = avl_insert(&root, 512); 35 | printf("\nInserted: %d\n", node->n); 36 | binary_tree_print(root); 37 | node = avl_insert(&root, 50); 38 | printf("\nInserted: %d\n", node->n); 39 | binary_tree_print(root); 40 | return (0); 41 | } 42 | -------------------------------------------------------------------------------- /122-array_to_avl.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * array_to_avl - a function that builds an AVL tree from an array. 5 | * @array: is a pointer to the first element of the array to be converted. 6 | * @size: is the number of element in the array. 7 | * Return: A pointer to the root node of the created AVL, 8 | * or NULL upon failure. 9 | */ 10 | 11 | avl_t *array_to_avl(int *array, size_t size) 12 | { 13 | avl_t *tree = NULL; 14 | size_t i, j; 15 | 16 | if (array == NULL) 17 | return (NULL); 18 | 19 | for (i = 0; i < size; i++) 20 | { 21 | for (j = 0; j < i; j++) 22 | { 23 | if (array[j] == array[i]) 24 | break; 25 | } 26 | if (j == i) 27 | { 28 | if (avl_insert(&tree, array[i]) == NULL) 29 | return (NULL); 30 | } 31 | } 32 | 33 | return (tree); 34 | } 35 | -------------------------------------------------------------------------------- /122-avl_array: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/122-avl_array -------------------------------------------------------------------------------- /122-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "binary_trees.h" 3 | 4 | /** 5 | * main - Entry point 6 | * 7 | * Return: 0 on success, error code on failure 8 | */ 9 | int main(void) 10 | { 11 | avl_t *tree; 12 | int array[] = { 13 | 79, 47, 68, 87, 84, 91, 21, 32, 34, 2, 14 | 20, 22, 98, 1, 62, 95 15 | }; 16 | size_t n = sizeof(array) / sizeof(array[0]); 17 | 18 | tree = array_to_avl(array, n); 19 | if (!tree) 20 | return (1); 21 | binary_tree_print(tree); 22 | return (0); 23 | } 24 | -------------------------------------------------------------------------------- /123-avl_remove.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * bal - A function that Measures balance factor of a AVL. 5 | * @tree: is a tree to go through. 6 | * Return: balanced factor 7 | */ 8 | 9 | void bal(avl_t **tree) 10 | { 11 | int b_val; 12 | 13 | if (tree == NULL || *tree == NULL) 14 | return; 15 | if ((*tree)->left == NULL && (*tree)->right == NULL) 16 | return; 17 | bal(&(*tree)->left); 18 | bal(&(*tree)->right); 19 | b_val = binary_tree_balance((const binary_tree_t *)*tree); 20 | if (b_val > 1) 21 | *tree = binary_tree_rotate_right((binary_tree_t *)*tree); 22 | else if (b_val < -1) 23 | *tree = binary_tree_rotate_left((binary_tree_t *)*tree); 24 | } 25 | 26 | /** 27 | * successor - A function that get the next successor 28 | * i mean the min node in the right subtree. 29 | * @node: Is a tree to check. 30 | * Return: the min value of this tree 31 | */ 32 | 33 | int successor(bst_t *node) 34 | { 35 | int left = 0; 36 | 37 | if (node == NULL) 38 | { 39 | return (0); 40 | } 41 | else 42 | { 43 | left = successor(node->left); 44 | if (left == 0) 45 | { 46 | return (node->n); 47 | } 48 | return (left); 49 | } 50 | 51 | } 52 | 53 | /** 54 | *remove_type - A function that removes a node depending of its children. 55 | *@root: is a node to remove. 56 | *Return: 0 if it has no children or other value if it has. 57 | */ 58 | 59 | int remove_type(bst_t *root) 60 | { 61 | int new_value = 0; 62 | 63 | if (!root->left && !root->right) 64 | { 65 | if (root->parent->right == root) 66 | root->parent->right = NULL; 67 | else 68 | root->parent->left = NULL; 69 | free(root); 70 | return (0); 71 | } 72 | else if ((!root->left && root->right) || (!root->right && root->left)) 73 | { 74 | if (!root->left) 75 | { 76 | if (root->parent->right == root) 77 | root->parent->right = root->right; 78 | else 79 | root->parent->left = root->right; 80 | root->right->parent = root->parent; 81 | } 82 | if (!root->right) 83 | { 84 | if (root->parent->right == root) 85 | root->parent->right = root->left; 86 | else 87 | root->parent->left = root->left; 88 | root->left->parent = root->parent; 89 | } 90 | free(root); 91 | return (0); 92 | } 93 | else 94 | { 95 | new_value = successor(root->right); 96 | root->n = new_value; 97 | return (new_value); 98 | } 99 | } 100 | 101 | /** 102 | * bst_remove - A function that remove a node from a BST tree. 103 | * @root: is a root of the tree. 104 | * @value: is a node with this value to remove. 105 | * Return: the tree changed 106 | */ 107 | 108 | bst_t *bst_remove(bst_t *root, int value) 109 | { 110 | int type = 0; 111 | 112 | if (root == NULL) 113 | return (NULL); 114 | if (value < root->n) 115 | bst_remove(root->left, value); 116 | else if (value > root->n) 117 | bst_remove(root->right, value); 118 | else if (value == root->n) 119 | { 120 | type = remove_type(root); 121 | if (type != 0) 122 | bst_remove(root->right, type); 123 | } 124 | else 125 | return (NULL); 126 | return (root); 127 | } 128 | 129 | /** 130 | * avl_remove - A function that remove a node from a AVL tree. 131 | * @root: is a root of the tree. 132 | * @value: is a node with this value to remove. 133 | * Return: the tree changed 134 | */ 135 | 136 | avl_t *avl_remove(avl_t *root, int value) 137 | { 138 | avl_t *root_a = (avl_t *) bst_remove((bst_t *) root, value); 139 | 140 | if (root_a == NULL) 141 | return (NULL); 142 | bal(&root_a); 143 | return (root_a); 144 | } 145 | -------------------------------------------------------------------------------- /123-avl_rm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/123-avl_rm -------------------------------------------------------------------------------- /123-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: 0 on success, error code on failure 9 | */ 10 | int main(void) 11 | { 12 | avl_t *tree; 13 | int array[] = { 14 | 79, 47, 68, 87, 84, 91, 21, 32, 34, 2, 15 | 20, 22, 98, 1, 62, 95 16 | }; 17 | size_t n = sizeof(array) / sizeof(array[0]); 18 | 19 | tree = array_to_avl(array, n); 20 | if (!tree) 21 | return (1); 22 | binary_tree_print(tree); 23 | 24 | tree = avl_remove(tree, 47); 25 | printf("Removed 47...\n"); 26 | binary_tree_print(tree); 27 | 28 | tree = avl_remove(tree, 79); 29 | printf("Removed 79...\n"); 30 | binary_tree_print(tree); 31 | 32 | tree = avl_remove(tree, 32); 33 | printf("Removed 32...\n"); 34 | binary_tree_print(tree); 35 | 36 | tree = avl_remove(tree, 34); 37 | printf("Removed 34...\n"); 38 | binary_tree_print(tree); 39 | 40 | tree = avl_remove(tree, 22); 41 | printf("Removed 22...\n"); 42 | binary_tree_print(tree); 43 | binary_tree_delete(tree); 44 | return (0); 45 | } 46 | -------------------------------------------------------------------------------- /125-O: -------------------------------------------------------------------------------- 1 | O(log(n)) 2 | O(log(n)) 3 | O(log(n)) 4 | -------------------------------------------------------------------------------- /13-binary_tree_nodes.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_nodes - Counts nodes with at least 1 child in a binary tree. 5 | * @tree: A pointer to root node of the tree to count the number of nodes. 6 | * Return: If tree is NULL,it must return 0, else return node count. 7 | */ 8 | size_t binary_tree_nodes(const binary_tree_t *tree) 9 | { 10 | size_t nodes = 0; 11 | 12 | if (tree) 13 | { 14 | nodes += (tree->left || tree->right) ? 1 : 0; 15 | nodes += binary_tree_nodes(tree->left); 16 | nodes += binary_tree_nodes(tree->right); 17 | } 18 | return (nodes); 19 | } 20 | -------------------------------------------------------------------------------- /135-O: -------------------------------------------------------------------------------- 1 | O(n) 2 | O(n) 3 | O(n) 4 | -------------------------------------------------------------------------------- /14-binary_tree_balance.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_balance - Measures balance factor of a binary tree. 5 | * @tree: A pointer to root node of the tree to measure the balance factor. 6 | * Return: If tree is NULL, return 0, else return balance factor. 7 | */ 8 | int binary_tree_balance(const binary_tree_t *tree) 9 | { 10 | if (tree) 11 | return (binary_tree_height(tree->left) - binary_tree_height(tree->right)); 12 | 13 | return (0); 14 | } 15 | 16 | /** 17 | * binary_tree_height - Measures the height of a binary tree. 18 | * @tree: A pointer to the root node of the tree to measure the height. 19 | * 20 | * Return: If tree is NULL, your function must return 0, else return height. 21 | */ 22 | size_t binary_tree_height(const binary_tree_t *tree) 23 | { 24 | if (tree) 25 | { 26 | size_t l = 0, r = 0; 27 | 28 | l = tree->left ? 1 + binary_tree_height(tree->left) : 1; 29 | r = tree->right ? 1 + binary_tree_height(tree->right) : 1; 30 | return ((l > r) ? l : r); 31 | } 32 | return (0); 33 | } 34 | -------------------------------------------------------------------------------- /15-binary_tree_is_full.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * is_full_recursive - Checks if a binary tree full recursively. 5 | * @tree: A pointer to root node of the tree to check. 6 | * Return: If tree is not full, 0. 7 | * else, 1. 8 | */ 9 | int is_full_recursive(const binary_tree_t *tree) 10 | { 11 | if (tree != NULL) 12 | { 13 | if ((tree->left != NULL && tree->right == NULL) || 14 | (tree->left == NULL && tree->right != NULL) || 15 | is_full_recursive(tree->left) == 0 || 16 | is_full_recursive(tree->right) == 0) 17 | return (0); 18 | } 19 | return (1); 20 | } 21 | 22 | /** 23 | * binary_tree_is_full - Checks if a binary tree is full. 24 | * @tree: A pointer to the root node of the tree to check. 25 | * 26 | * Return: If tree is NULL or is not full - 0. 27 | * Otherwise - 1. 28 | */ 29 | int binary_tree_is_full(const binary_tree_t *tree) 30 | { 31 | if (tree == NULL) 32 | return (0); 33 | return (is_full_recursive(tree)); 34 | } 35 | -------------------------------------------------------------------------------- /16-binary_tree_is_perfect.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | unsigned char is_leaf(const binary_tree_t *node); 4 | size_t depth(const binary_tree_t *tree); 5 | const binary_tree_t *get_leaf(const binary_tree_t *tree); 6 | int is_perfect_recursive(const binary_tree_t *tree, 7 | size_t leaf_depth, size_t level); 8 | int binary_tree_is_perfect(const binary_tree_t *tree); 9 | 10 | /** 11 | * is_leaf - Checks if node is a leaf of a binary tree. 12 | * @node: A pointer to a node to check. 13 | * Return: If the node is a leaf, 1, else, 0. 14 | */ 15 | unsigned char is_leaf(const binary_tree_t *node) 16 | { 17 | return ((node->left == NULL && node->right == NULL) ? 1 : 0); 18 | } 19 | 20 | /** 21 | * depth - Returns the depth of a given 22 | * node in a binary tree. 23 | * @tree: A pointer to the node to measure the depth of. 24 | * 25 | * Return: The depth of node. 26 | */ 27 | size_t depth(const binary_tree_t *tree) 28 | { 29 | return (tree->parent != NULL ? 1 + depth(tree->parent) : 0); 30 | } 31 | 32 | /** 33 | * get_leaf - Returns a leaf of a binary tree. 34 | * @tree: A pointer to the root node of the tree to find a leaf in. 35 | * 36 | * Return: A pointer to the first encountered leaf. 37 | */ 38 | const binary_tree_t *get_leaf(const binary_tree_t *tree) 39 | { 40 | if (is_leaf(tree) == 1) 41 | return (tree); 42 | return (tree->left ? get_leaf(tree->left) : get_leaf(tree->right)); 43 | } 44 | 45 | /** 46 | * is_perfect_recursive - Checks if a binary tree is perfect recursively. 47 | * @tree: A pointer to the root node of the tree to check. 48 | * @leaf_depth: The depth of one leaf in the binary tree. 49 | * @level: Level of current node. 50 | * 51 | * Return: If the tree is perfect, 1, otherwise 0. 52 | */ 53 | int is_perfect_recursive(const binary_tree_t *tree, 54 | size_t leaf_depth, size_t level) 55 | { 56 | if (is_leaf(tree)) 57 | return (level == leaf_depth ? 1 : 0); 58 | if (tree->left == NULL || tree->right == NULL) 59 | return (0); 60 | return (is_perfect_recursive(tree->left, leaf_depth, level + 1) && 61 | is_perfect_recursive(tree->right, leaf_depth, level + 1)); 62 | } 63 | 64 | /** 65 | * binary_tree_is_perfect - Checks if a binary tree is perfect. 66 | * @tree: A pointer to the root node of the tree to check. 67 | * 68 | * Return: If tree is NULL or not perfect, 0. 69 | * Otherwise, 1. 70 | */ 71 | int binary_tree_is_perfect(const binary_tree_t *tree) 72 | { 73 | if (tree == NULL) 74 | return (0); 75 | return (is_perfect_recursive(tree, depth(get_leaf(tree)), 0)); 76 | } 77 | -------------------------------------------------------------------------------- /17-binary_tree_sibling.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_sibling - Finds the sibling of a 5 | * node in binary tree. 6 | * @node: pointer to the node to find the sibling of. 7 | * Return: If node is NULL or there is no sibling - NULL. 8 | * Otherwise - a pointer to the sibling. 9 | */ 10 | binary_tree_t *binary_tree_sibling(binary_tree_t *node) 11 | { 12 | if (node == NULL || node->parent == NULL) 13 | return (NULL); 14 | if (node->parent->left == node) 15 | return (node->parent->right); 16 | return (node->parent->left); 17 | } 18 | -------------------------------------------------------------------------------- /18-binary_tree_uncle.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_uncle - Finds the uncle of a node 5 | * in binary tree. 6 | * @node: A pointer to a node to find the uncle of. 7 | * Return: If node is NULL or has no uncle, NULL. 8 | * else, a pointer to the uncle node. 9 | */ 10 | binary_tree_t *binary_tree_uncle(binary_tree_t *node) 11 | { 12 | if (node == NULL || 13 | node->parent == NULL || 14 | node->parent->parent == NULL) 15 | return (NULL); 16 | if (node->parent->parent->left == node->parent) 17 | return (node->parent->parent->right); 18 | return (node->parent->parent->left); 19 | } 20 | -------------------------------------------------------------------------------- /2-binary_tree_insert_right.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_insert_right - A function that Insert a node as the right-child 5 | * of another in a binary tree. 6 | * @parent: - is a pointer to the parent node of the node to create. 7 | * @value: - is the value to put in the new node. 8 | * Return: If parent is NULL or an error occurs - NULL. 9 | * Otherwise - a pointer to the new node. 10 | * Description: If parent already has a right-child, the new node must 11 | * take its place, and the old right-child must be set as the 12 | * right-child of the new node. 13 | */ 14 | 15 | binary_tree_t *binary_tree_insert_right(binary_tree_t *parent, int value) 16 | { 17 | binary_tree_t *new; 18 | 19 | if (parent == NULL) 20 | return (NULL); 21 | 22 | new = binary_tree_node(parent, value); 23 | if (new == NULL) 24 | return (NULL); 25 | 26 | if (parent->right != NULL) 27 | { 28 | new->right = parent->right; 29 | parent->right->parent = new; 30 | } 31 | parent->right = new; 32 | 33 | return (new); 34 | } 35 | -------------------------------------------------------------------------------- /2-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: Always 0 (Success) 9 | */ 10 | int main(void) 11 | { 12 | binary_tree_t *root; 13 | 14 | root = binary_tree_node(NULL, 98); 15 | root->left = binary_tree_node(root, 12); 16 | root->right = binary_tree_node(root, 402); 17 | binary_tree_print(root); 18 | printf("\n"); 19 | binary_tree_insert_right(root->left, 54); 20 | binary_tree_insert_right(root, 128); 21 | binary_tree_print(root); 22 | return (0); 23 | } 24 | -------------------------------------------------------------------------------- /2-right: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/2-right -------------------------------------------------------------------------------- /3-binary_tree_delete.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_delete - A function that Deletes a binary tree. 5 | * @tree: is a pointer to the root node of the tree to delete. 6 | */ 7 | 8 | void binary_tree_delete(binary_tree_t *tree) 9 | { 10 | if (tree != NULL) 11 | { 12 | binary_tree_delete(tree->left); 13 | binary_tree_delete(tree->right); 14 | free(tree); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /3-del: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/3-del -------------------------------------------------------------------------------- /3-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: Always 0 (Success) 9 | */ 10 | int main(void) 11 | { 12 | binary_tree_t *root; 13 | 14 | root = binary_tree_node(NULL, 98); 15 | root->left = binary_tree_node(root, 12); 16 | root->right = binary_tree_node(root, 402); 17 | binary_tree_insert_right(root->left, 54); 18 | binary_tree_insert_right(root, 128); 19 | binary_tree_print(root); 20 | binary_tree_delete(root); 21 | return (0); 22 | } 23 | -------------------------------------------------------------------------------- /4-binary_tree_is_leaf.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_is_leaf - Checks if a node is a leaf of a binary tree. 5 | * @node: A pointer to the node to check. 6 | * Return: 1 If node is a leaf, otherwise 0 If node is NULL, return 0. 7 | */ 8 | 9 | int binary_tree_is_leaf(const binary_tree_t *node) 10 | { 11 | if (node == NULL || node->left != NULL || node->right != NULL) 12 | return (0); 13 | 14 | return (1); 15 | } 16 | -------------------------------------------------------------------------------- /4-leaf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/4-leaf -------------------------------------------------------------------------------- /4-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: Always 0 (Success) 9 | */ 10 | int main(void) 11 | { 12 | binary_tree_t *root; 13 | int ret; 14 | 15 | root = binary_tree_node(NULL, 98); 16 | root->left = binary_tree_node(root, 12); 17 | root->right = binary_tree_node(root, 402); 18 | binary_tree_insert_right(root->left, 54); 19 | binary_tree_insert_right(root, 128); 20 | binary_tree_print(root); 21 | 22 | ret = binary_tree_is_leaf(root); 23 | printf("Is %d a leaf: %d\n", root->n, ret); 24 | ret = binary_tree_is_leaf(root->right); 25 | printf("Is %d a leaf: %d\n", root->right->n, ret); 26 | ret = binary_tree_is_leaf(root->right->right); 27 | printf("Is %d a leaf: %d\n", root->right->right->n, ret); 28 | return (0); 29 | } 30 | -------------------------------------------------------------------------------- /5-binary_tree_is_root.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_is_root - A function Checks if a node is a root. 5 | * @node: Is a pointer to the node to check. 6 | * Return: 1 if node is a root, otherwise 0 If node is NULL, return 0. 7 | */ 8 | 9 | int binary_tree_is_root(const binary_tree_t *node) 10 | { 11 | if (node == NULL || node->parent != NULL) 12 | return (0); 13 | 14 | return (1); 15 | } 16 | -------------------------------------------------------------------------------- /5-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: Always 0 (Success) 9 | */ 10 | int main(void) 11 | { 12 | binary_tree_t *root; 13 | int ret; 14 | 15 | root = binary_tree_node(NULL, 98); 16 | root->left = binary_tree_node(root, 12); 17 | root->right = binary_tree_node(root, 402); 18 | binary_tree_insert_right(root->left, 54); 19 | binary_tree_insert_right(root, 128); 20 | binary_tree_print(root); 21 | 22 | ret = binary_tree_is_root(root); 23 | printf("Is %d a root: %d\n", root->n, ret); 24 | ret = binary_tree_is_root(root->right); 25 | printf("Is %d a root: %d\n", root->right->n, ret); 26 | ret = binary_tree_is_root(root->right->right); 27 | printf("Is %d a root: %d\n", root->right->right->n, ret); 28 | return (0); 29 | } 30 | -------------------------------------------------------------------------------- /5-root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/5-root -------------------------------------------------------------------------------- /6-binary_tree_preorder.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_preorder - a function that goes through a binar traversal. 5 | * @tree: is a pointer to the root node of the tree to traverse. 6 | * @func: is a pointer to a function to call for each node. 7 | * The value in the node must be passed as a parameter to this function. 8 | */ 9 | 10 | void binary_tree_preorder(const binary_tree_t *tree, void (*func)(int)) 11 | { 12 | if (tree && func) 13 | { 14 | func(tree->n); 15 | binary_tree_preorder(tree->left, func); 16 | binary_tree_preorder(tree->right, func); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /6-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * print_num - Prints a number 7 | * 8 | * @n: Number to be printed 9 | */ 10 | void print_num(int n) 11 | { 12 | printf("%d\n", n); 13 | } 14 | 15 | /** 16 | * main - Entry point 17 | * 18 | * Return: Always 0 (Success) 19 | */ 20 | int main(void) 21 | { 22 | binary_tree_t *root; 23 | 24 | root = binary_tree_node(NULL, 98); 25 | root->left = binary_tree_node(root, 12); 26 | root->right = binary_tree_node(root, 402); 27 | root->left->left = binary_tree_node(root->left, 6); 28 | root->left->right = binary_tree_node(root->left, 56); 29 | root->right->left = binary_tree_node(root->right, 256); 30 | root->right->right = binary_tree_node(root->right, 512); 31 | 32 | binary_tree_print(root); 33 | binary_tree_preorder(root, &print_num); 34 | return (0); 35 | } 36 | -------------------------------------------------------------------------------- /6-pre: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/6-pre -------------------------------------------------------------------------------- /7-binary_tree_inorder.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_inorder - a function that goes through a binary tree 5 | * using in-order traversal. 6 | * @tree: is a pointer to the root node of the tree to traverse. 7 | * @func: is a pointer to a function to call for each node. 8 | * The value in the node must be passed as 9 | * a parameter to this function. 10 | */ 11 | 12 | void binary_tree_inorder(const binary_tree_t *tree, void (*func)(int)) 13 | { 14 | if (tree && func) 15 | { 16 | binary_tree_inorder(tree->left, func); 17 | func(tree->n); 18 | binary_tree_inorder(tree->right, func); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /7-in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/7-in -------------------------------------------------------------------------------- /7-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * print_num - Prints a number 7 | * 8 | * @n: Number to be printed 9 | */ 10 | void print_num(int n) 11 | { 12 | printf("%d\n", n); 13 | } 14 | 15 | /** 16 | * main - Entry point 17 | * 18 | * Return: Always 0 (Success) 19 | */ 20 | int main(void) 21 | { 22 | binary_tree_t *root; 23 | 24 | root = binary_tree_node(NULL, 98); 25 | root->left = binary_tree_node(root, 12); 26 | root->right = binary_tree_node(root, 402); 27 | root->left->left = binary_tree_node(root->left, 6); 28 | root->left->right = binary_tree_node(root->left, 56); 29 | root->right->left = binary_tree_node(root->right, 256); 30 | root->right->right = binary_tree_node(root->right, 512); 31 | 32 | binary_tree_print(root); 33 | binary_tree_inorder(root, &print_num); 34 | return (0); 35 | } 36 | -------------------------------------------------------------------------------- /8-binary_tree_postorder.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_postorder - a function that goes through a binary tree 5 | * using post-order traversal. 6 | * @tree: is a pointer to the root node of the tree to traverse. 7 | * @func: is a pointer to a function to call for each node. 8 | * The value in the node must be passed as a parameter to this function. 9 | */ 10 | 11 | void binary_tree_postorder(const binary_tree_t *tree, void (*func)(int)) 12 | { 13 | if (tree && func) 14 | { 15 | binary_tree_postorder(tree->left, func); 16 | binary_tree_postorder(tree->right, func); 17 | func(tree->n); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /8-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * print_num - Prints a number 7 | * 8 | * @n: Number to be printed 9 | */ 10 | void print_num(int n) 11 | { 12 | printf("%d\n", n); 13 | } 14 | 15 | /** 16 | * main - Entry point 17 | * 18 | * Return: Always 0 (Success) 19 | */ 20 | int main(void) 21 | { 22 | binary_tree_t *root; 23 | 24 | root = binary_tree_node(NULL, 98); 25 | root->left = binary_tree_node(root, 12); 26 | root->right = binary_tree_node(root, 402); 27 | root->left->left = binary_tree_node(root->left, 6); 28 | root->left->right = binary_tree_node(root->left, 56); 29 | root->right->left = binary_tree_node(root->right, 256); 30 | root->right->right = binary_tree_node(root->right, 512); 31 | 32 | binary_tree_print(root); 33 | binary_tree_postorder(root, &print_num); 34 | return (0); 35 | } 36 | -------------------------------------------------------------------------------- /8-post: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/8-post -------------------------------------------------------------------------------- /9-binary_tree_height.c: -------------------------------------------------------------------------------- 1 | #include "binary_trees.h" 2 | 3 | /** 4 | * binary_tree_height - A function that measures the height of a binary tree. 5 | * @tree: is a pointer to the root node of the tree to measure the height. 6 | * Return: If tree is NULL, your function must return 0, else return height. 7 | */ 8 | 9 | size_t binary_tree_height(const binary_tree_t *tree) 10 | { 11 | if (tree) 12 | { 13 | size_t l = 0, r = 0; 14 | 15 | l = tree->left ? 1 + binary_tree_height(tree->left) : 0; 16 | r = tree->right ? 1 + binary_tree_height(tree->right) : 0; 17 | return ((l > r) ? l : r); 18 | } 19 | return (0); 20 | } 21 | -------------------------------------------------------------------------------- /9-height: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ambesawi/binary_trees/4774d430e0f3e8a680b26852ff2e1b2612137809/9-height -------------------------------------------------------------------------------- /9-main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_trees.h" 4 | 5 | /** 6 | * main - Entry point 7 | * 8 | * Return: Always 0 (Success) 9 | */ 10 | int main(void) 11 | { 12 | binary_tree_t *root; 13 | size_t height; 14 | 15 | root = binary_tree_node(NULL, 98); 16 | root->left = binary_tree_node(root, 12); 17 | root->right = binary_tree_node(root, 402); 18 | binary_tree_insert_right(root->left, 54); 19 | binary_tree_insert_right(root, 128); 20 | binary_tree_print(root); 21 | 22 | height = binary_tree_height(root); 23 | printf("Height from %d: %lu\n", root->n, height); 24 | height = binary_tree_height(root->right); 25 | printf("Height from %d: %lu\n", root->right->n, height); 26 | height = binary_tree_height(root->left->right); 27 | printf("Height from %d: %lu\n", root->left->right->n, height); 28 | return (0); 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C - Binary Trees 2 | 3 | ## Description 4 | 5 | This project delves into the realm of binary trees, exploring concepts such as binary trees, binary search trees, tree traversal methods, and the characteristics of different types of binary trees. The goal is to deepen understanding of data structures and algorithms related to binary trees. 6 | 7 | ## Learning Objectives 8 | 9 | By the end of this project, you should be able to: 10 | 11 | - Explain what a binary tree is. 12 | - Differentiate between a binary tree and a Binary Search Tree (BST). 13 | - Understand the potential gain in terms of time complexity compared to linked lists. 14 | - Define and explain the concepts of depth, height, and size of a binary tree. 15 | - Familiarize yourself with different traversal methods to navigate through a binary tree. 16 | - Describe a complete, full, perfect, and balanced binary tree. 17 | 18 | ## Project Requirements 19 | 20 | - Use allowed editors: vi, vim, emacs. 21 | - All files will be compiled on Ubuntu 20.04 LTS using gcc with the options `-Wall -Werror -Wextra -pedantic -std=gnu89`. 22 | - End all files with a new line. 23 | - A `README.md` file, at the root of the folder of the project, is mandatory. 24 | - Your code should follow the Betty style. It will be checked using `betty-style.pl` and `betty-doc.pl`. 25 | - You are not allowed to use global variables. 26 | - No more than 5 functions per file. 27 | - You are allowed to use the standard library. 28 | - The prototypes of all your functions should be included in your header file called `binary_trees.h`. 29 | - Don’t forget to push your header file. 30 | - All your header files should be include guarded. 31 | 32 | ## Data Structures 33 | 34 | Please use the following data structures and types for binary trees. Include them in your `binary_trees.h` header file: 35 | 36 | ### Basic Binary Tree 37 | ```c 38 | /** 39 | * struct binary_tree_s - Binary tree node 40 | * 41 | * @n: Integer stored in the node 42 | * @parent: Pointer to the parent node 43 | * @left: Pointer to the left child node 44 | * @right: Pointer to the right child node 45 | */ 46 | struct binary_tree_s 47 | { 48 | int n; 49 | struct binary_tree_s *parent; 50 | struct binary_tree_s *left; 51 | struct binary_tree_s *right; 52 | }; 53 | 54 | typedef struct binary_tree_s binary_tree_t; 55 | -------------------------------------------------------------------------------- /binary_tree_print.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "binary_trees.h" 5 | 6 | /* Original code from http://stackoverflow.com/a/13755911/5184480 */ 7 | 8 | /** 9 | * print_t - Stores recursively each level in an array of strings 10 | * 11 | * @tree: Pointer to the node to print 12 | * @offset: Offset to print 13 | * @depth: Depth of the node 14 | * @s: Buffer 15 | * 16 | * Return: length of printed tree after process 17 | */ 18 | static int print_t(const binary_tree_t *tree, int offset, int depth, char **s) 19 | { 20 | char b[6]; 21 | int width, left, right, is_left, i; 22 | 23 | if (!tree) 24 | return (0); 25 | is_left = (tree->parent && tree->parent->left == tree); 26 | width = sprintf(b, "(%03d)", tree->n); 27 | left = print_t(tree->left, offset, depth + 1, s); 28 | right = print_t(tree->right, offset + left + width, depth + 1, s); 29 | for (i = 0; i < width; i++) 30 | s[depth][offset + left + i] = b[i]; 31 | if (depth && is_left) 32 | { 33 | for (i = 0; i < width + right; i++) 34 | s[depth - 1][offset + left + width / 2 + i] = '-'; 35 | s[depth - 1][offset + left + width / 2] = '.'; 36 | } 37 | else if (depth && !is_left) 38 | { 39 | for (i = 0; i < left + width; i++) 40 | s[depth - 1][offset - width / 2 + i] = '-'; 41 | s[depth - 1][offset + left + width / 2] = '.'; 42 | } 43 | return (left + width + right); 44 | } 45 | 46 | /** 47 | * _height - Measures the height of a binary tree 48 | * 49 | * @tree: Pointer to the node to measures the height 50 | * 51 | * Return: The height of the tree starting at @node 52 | */ 53 | static size_t _height(const binary_tree_t *tree) 54 | { 55 | size_t height_l; 56 | size_t height_r; 57 | 58 | height_l = tree->left ? 1 + _height(tree->left) : 0; 59 | height_r = tree->right ? 1 + _height(tree->right) : 0; 60 | return (height_l > height_r ? height_l : height_r); 61 | } 62 | 63 | /** 64 | * binary_tree_print - Prints a binary tree 65 | * 66 | * @tree: Pointer to the root node of the tree to print 67 | */ 68 | void binary_tree_print(const binary_tree_t *tree) 69 | { 70 | char **s; 71 | size_t height, i, j; 72 | 73 | if (!tree) 74 | return; 75 | height = _height(tree); 76 | s = malloc(sizeof(*s) * (height + 1)); 77 | if (!s) 78 | return; 79 | for (i = 0; i < height + 1; i++) 80 | { 81 | s[i] = malloc(sizeof(**s) * 255); 82 | if (!s[i]) 83 | return; 84 | memset(s[i], 32, 255); 85 | } 86 | print_t(tree, 0, 0, s); 87 | for (i = 0; i < height + 1; i++) 88 | { 89 | for (j = 254; j > 1; --j) 90 | { 91 | if (s[i][j] != ' ') 92 | break; 93 | s[i][j] = '\0'; 94 | } 95 | printf("%s\n", s[i]); 96 | free(s[i]); 97 | } 98 | free(s); 99 | } 100 | -------------------------------------------------------------------------------- /binary_trees.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARY_TREES_H 2 | #define BINARY_TREES_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | /* Data structures */ 10 | 11 | /** 12 | * struct binary_tree_s - Binary tree node 13 | * @n: Integer stored in the node 14 | * @parent: Pointer to the parent node 15 | * @left: Pointer to the left child node 16 | * @right: Pointer to the right child node 17 | */ 18 | struct binary_tree_s 19 | { 20 | int n; 21 | struct binary_tree_s *parent; 22 | struct binary_tree_s *left; 23 | struct binary_tree_s *right; 24 | }; 25 | typedef struct binary_tree_s binary_tree_t; 26 | typedef struct binary_tree_s bst_t; 27 | typedef struct binary_tree_s avl_t; 28 | typedef struct binary_tree_s heap_t; 29 | 30 | /** 31 | * struct levelorder_queue_s - Level order traversal queue. 32 | * @node: A node of a binary tree. 33 | * @next: The next node to traverse to in the binary tree. 34 | */ 35 | typedef struct levelorder_queue_s 36 | { 37 | binary_tree_t *node; 38 | struct levelorder_queue_s *next; 39 | } levelorder_queue_t; 40 | 41 | /* Printing helper function */ 42 | void binary_tree_print(const binary_tree_t *); 43 | 44 | /* Task function prototypes */ 45 | binary_tree_t *binary_tree_node(binary_tree_t *parent, int value); 46 | binary_tree_t *binary_tree_insert_left(binary_tree_t *parent, int value); 47 | binary_tree_t *binary_tree_insert_right(binary_tree_t *parent, int value); 48 | void binary_tree_delete(binary_tree_t *tree); 49 | int binary_tree_is_leaf(const binary_tree_t *node); 50 | int binary_tree_is_root(const binary_tree_t *node); 51 | void binary_tree_preorder(const binary_tree_t *tree, void (*func)(int)); 52 | void binary_tree_inorder(const binary_tree_t *tree, void (*func)(int)); 53 | void binary_tree_postorder(const binary_tree_t *tree, void (*func)(int)); 54 | size_t binary_tree_height(const binary_tree_t *tree); 55 | size_t binary_tree_depth(const binary_tree_t *tree); 56 | size_t binary_tree_size(const binary_tree_t *tree); 57 | size_t binary_tree_leaves(const binary_tree_t *tree); 58 | size_t binary_tree_nodes(const binary_tree_t *tree); 59 | int binary_tree_balance(const binary_tree_t *tree); 60 | int binary_tree_is_full(const binary_tree_t *tree); 61 | int binary_tree_is_perfect(const binary_tree_t *tree); 62 | binary_tree_t *binary_tree_sibling(binary_tree_t *node); 63 | binary_tree_t *binary_tree_uncle(binary_tree_t *node); 64 | binary_tree_t *binary_trees_ancestor(const binary_tree_t *first, 65 | const binary_tree_t *second); 66 | void binary_tree_levelorder(const binary_tree_t *tree, void (*func)(int)); 67 | int binary_tree_is_complete(const binary_tree_t *tree); 68 | binary_tree_t *binary_tree_rotate_left(binary_tree_t *tree); 69 | binary_tree_t *binary_tree_rotate_right(binary_tree_t *tree); 70 | int binary_tree_is_bst(const binary_tree_t *tree); 71 | bst_t *bst_insert(bst_t **tree, int value); 72 | bst_t *array_to_bst(int *array, size_t size); 73 | bst_t *bst_search(const bst_t *tree, int value); 74 | bst_t *bst_remove(bst_t *root, int value); 75 | int binary_tree_is_avl(const binary_tree_t *tree); 76 | avl_t *avl_insert(avl_t **tree, int value); 77 | avl_t *array_to_avl(int *array, size_t size); 78 | avl_t *avl_remove(avl_t *root, int value); 79 | avl_t *sorted_array_to_avl(int *array, size_t size); 80 | int binary_tree_is_heap(const binary_tree_t *tree); 81 | heap_t *heap_insert(heap_t **root, int value); 82 | heap_t *array_to_heap(int *array, size_t size); 83 | int heap_extract(heap_t **root); 84 | int *heap_to_sorted_array(heap_t *heap, size_t *size); 85 | 86 | #endif /* BINARY_TREES_H */ 87 | 88 | --------------------------------------------------------------------------------