├── README.md ├── LICENSE └── minHeap.c /README.md: -------------------------------------------------------------------------------- 1 | Min Heap 2 | ======== 3 | 4 | Min Heap is a data structure that is used extensively in various operations like sorting, job scheduling and various other operations. A binary min heap is a min heap, with each node having atmost two children. Various operations like insertion, deletion and traversal are possible on a min heap, and their C code is provided in this repository. 5 | 6 | To learn more about min heap, have a look at: [A Study In Min Heap](http://robin-thomas.github.io/min-heap/) 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Robin Thomas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /minHeap.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | File: minHeap.c 4 | Desc: Program showing various operations on a binary min heap 5 | Author: Robin Thomas 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define LCHILD(x) 2 * x + 1 13 | #define RCHILD(x) 2 * x + 2 14 | #define PARENT(x) (x - 1) / 2 15 | 16 | typedef struct node { 17 | int data ; 18 | } node ; 19 | 20 | typedef struct minHeap { 21 | int size ; 22 | node *elem ; 23 | } minHeap ; 24 | 25 | 26 | /* 27 | Function to initialize the min heap with size = 0 28 | */ 29 | minHeap initMinHeap(int size) { 30 | minHeap hp ; 31 | hp.size = 0 ; 32 | return hp ; 33 | } 34 | 35 | 36 | /* 37 | Function to swap data within two nodes of the min heap using pointers 38 | */ 39 | void swap(node *n1, node *n2) { 40 | node temp = *n1 ; 41 | *n1 = *n2 ; 42 | *n2 = temp ; 43 | } 44 | 45 | 46 | /* 47 | Heapify function is used to make sure that the heap property is never violated 48 | In case of deletion of a node, or creating a min heap from an array, heap property 49 | may be violated. In such cases, heapify function can be called to make sure that 50 | heap property is never violated 51 | */ 52 | void heapify(minHeap *hp, int i) { 53 | int smallest = (LCHILD(i) < hp->size && hp->elem[LCHILD(i)].data < hp->elem[i].data) ? LCHILD(i) : i ; 54 | if(RCHILD(i) < hp->size && hp->elem[RCHILD(i)].data < hp->elem[smallest].data) { 55 | smallest = RCHILD(i) ; 56 | } 57 | if(smallest != i) { 58 | swap(&(hp->elem[i]), &(hp->elem[smallest])) ; 59 | heapify(hp, smallest) ; 60 | } 61 | } 62 | 63 | 64 | /* 65 | Build a Min Heap given an array of numbers 66 | Instead of using insertNode() function n times for total complexity of O(nlogn), 67 | we can use the buildMinHeap() function to build the heap in O(n) time 68 | */ 69 | void buildMinHeap(minHeap *hp, int *arr, int size) { 70 | int i ; 71 | 72 | // Insertion into the heap without violating the shape property 73 | for(i = 0; i < size; i++) { 74 | if(hp->size) { 75 | hp->elem = realloc(hp->elem, (hp->size + 1) * sizeof(node)) ; 76 | } else { 77 | hp->elem = malloc(sizeof(node)) ; 78 | } 79 | node nd ; 80 | nd.data = arr[i] ; 81 | hp->elem[(hp->size)++] = nd ; 82 | } 83 | 84 | // Making sure that heap property is also satisfied 85 | for(i = (hp->size - 1) / 2; i >= 0; i--) { 86 | heapify(hp, i) ; 87 | } 88 | } 89 | 90 | 91 | /* 92 | Function to insert a node into the min heap, by allocating space for that node in the 93 | heap and also making sure that the heap property and shape propety are never violated. 94 | */ 95 | void insertNode(minHeap *hp, int data) { 96 | if(hp->size) { 97 | hp->elem = realloc(hp->elem, (hp->size + 1) * sizeof(node)) ; 98 | } else { 99 | hp->elem = malloc(sizeof(node)) ; 100 | } 101 | 102 | node nd ; 103 | nd.data = data ; 104 | 105 | int i = (hp->size)++ ; 106 | while(i && nd.data < hp->elem[PARENT(i)].data) { 107 | hp->elem[i] = hp->elem[PARENT(i)] ; 108 | i = PARENT(i) ; 109 | } 110 | hp->elem[i] = nd ; 111 | } 112 | 113 | 114 | /* 115 | Function to delete a node from the min heap 116 | It shall remove the root node, and place the last node in its place 117 | and then call heapify function to make sure that the heap property 118 | is never violated 119 | */ 120 | void deleteNode(minHeap *hp) { 121 | if(hp->size) { 122 | printf("Deleting node %d\n\n", hp->elem[0].data) ; 123 | hp->elem[0] = hp->elem[--(hp->size)] ; 124 | hp->elem = realloc(hp->elem, hp->size * sizeof(node)) ; 125 | heapify(hp, 0) ; 126 | } else { 127 | printf("\nMin Heap is empty!\n") ; 128 | free(hp->elem) ; 129 | } 130 | } 131 | 132 | 133 | /* 134 | Function to get maximum node from a min heap 135 | The maximum node shall always be one of the leaf nodes. So we shall recursively 136 | move through both left and right child, until we find their maximum nodes, and 137 | compare which is larger. It shall be done recursively until we get the maximum 138 | node 139 | */ 140 | int getMaxNode(minHeap *hp, int i) { 141 | if(LCHILD(i) >= hp->size) { 142 | return hp->elem[i].data ; 143 | } 144 | 145 | int l = getMaxNode(hp, LCHILD(i)) ; 146 | int r = getMaxNode(hp, RCHILD(i)) ; 147 | 148 | if(l >= r) { 149 | return l ; 150 | } else { 151 | return r ; 152 | } 153 | } 154 | 155 | 156 | /* 157 | Function to clear the memory allocated for the min heap 158 | */ 159 | void deleteMinHeap(minHeap *hp) { 160 | free(hp->elem) ; 161 | } 162 | 163 | 164 | /* 165 | Function to display all the nodes in the min heap by doing a inorder traversal 166 | */ 167 | void inorderTraversal(minHeap *hp, int i) { 168 | if(LCHILD(i) < hp->size) { 169 | inorderTraversal(hp, LCHILD(i)) ; 170 | } 171 | printf("%d ", hp->elem[i].data) ; 172 | if(RCHILD(i) < hp->size) { 173 | inorderTraversal(hp, RCHILD(i)) ; 174 | } 175 | } 176 | 177 | 178 | /* 179 | Function to display all the nodes in the min heap by doing a preorder traversal 180 | */ 181 | void preorderTraversal(minHeap *hp, int i) { 182 | if(LCHILD(i) < hp->size) { 183 | preorderTraversal(hp, LCHILD(i)) ; 184 | } 185 | if(RCHILD(i) < hp->size) { 186 | preorderTraversal(hp, RCHILD(i)) ; 187 | } 188 | printf("%d ", hp->elem[i].data) ; 189 | } 190 | 191 | 192 | /* 193 | Function to display all the nodes in the min heap by doing a post order traversal 194 | */ 195 | void postorderTraversal(minHeap *hp, int i) { 196 | printf("%d ", hp->elem[i].data) ; 197 | if(LCHILD(i) < hp->size) { 198 | postorderTraversal(hp, LCHILD(i)) ; 199 | } 200 | if(RCHILD(i) < hp->size) { 201 | postorderTraversal(hp, RCHILD(i)) ; 202 | } 203 | } 204 | 205 | 206 | /* 207 | Function to display all the nodes in the min heap by doing a level order traversal 208 | */ 209 | void levelorderTraversal(minHeap *hp) { 210 | int i ; 211 | for(i = 0; i < hp->size; i++) { 212 | printf("%d ", hp->elem[i].data) ; 213 | } 214 | } 215 | --------------------------------------------------------------------------------