├── .gitignore ├── DataStructuresList.pdf ├── Graphs └── DirectedWeightedGraphAdjListRepresentation.c ├── HashTables └── HashTableWithChaining.c ├── LinkedLists ├── DoublyLinkedList.cpp └── SinglyLinkedList.cpp ├── Queues ├── PriorityQueue │ └── PriorityQueueWithLinkedList.c └── QueueUsingArray.c ├── README.md ├── Stacks └── StackUsingDynamicArray.c └── Trees ├── BinarySearchTree ├── BSTInsertDeleteNode.c └── BinarySeachTreeInorderTraversal.c └── Heaps ├── HeapSortMaxHeap.c ├── HeapSortMinHeap.c ├── MaxHeap.c ├── MinHeap.c └── PriorityQueues └── PriorityQueueBinaryHeap.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.o 3 | *.out 4 | -------------------------------------------------------------------------------- /DataStructuresList.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlokikPathak/data-structures/dd308645fa80674edc3b3f1ce91508036fcf6a82/DataStructuresList.pdf -------------------------------------------------------------------------------- /Graphs/DirectedWeightedGraphAdjListRepresentation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Structure for storing Graph 6 | struct Graph{ 7 | 8 | int vertexNum; 9 | int** edges; 10 | 11 | }; 12 | 13 | 14 | // Constructs a graph with V vertices and E edges 15 | void createGraph( struct Graph* G, int V) { 16 | 17 | int i,j; 18 | G->vertexNum = V; 19 | 20 | // Creating V num of Integer Pointers(Array of Integer Pointers) and assign it G->edges 21 | G->edges = (int**) malloc(V * sizeof(int*)); 22 | 23 | for( i=0; iedges[i] Pointers 26 | G->edges[i] = (int*) malloc(V*sizeof(int)); 27 | 28 | for( j=0; jedges[i][j] = INT_MAX; 30 | } 31 | 32 | // Intialize Weight to Edge pointing to itself 33 | G->edges[i][i] = 0; 34 | } 35 | } 36 | 37 | // Adds the given edge to the graph 38 | void addEdge( struct Graph* G, int src, int dst, int weight) { 39 | 40 | G->edges[src][dst] = weight; 41 | } 42 | 43 | // Prints graph in Adjcacency list format 44 | void printGraph( struct Graph* G, int V) { 45 | 46 | printf("The Directed { Weighted } Graph Adjacency List Representation: "); 47 | int i,j; 48 | for( i=0; iedges[i][j] != INT_MAX && G->edges[i][j] != 0 ) { 55 | printf(" -> "); 56 | // Edge Weight is printed inside {} 57 | printf("%d {%d}", j, G->edges[i][j]); 58 | } 59 | } 60 | 61 | } 62 | } 63 | 64 | 65 | 66 | 67 | int main() { 68 | 69 | int V, E, gsrc,i; 70 | 71 | int src, dst, weight; 72 | 73 | struct Graph G; 74 | 75 | printf("Enter no. of vertices\n"); 76 | scanf("%d",&V); 77 | 78 | printf("Enter no. of Edges\n"); 79 | scanf("%d",&E); 80 | 81 | createGraph(&G, V); 82 | 83 | for( i=0; i 2 | #include 3 | using namespace std; 4 | 5 | /** 6 | * Purpose: Define the Node structute of Doubly Linked List 7 | * Parameter: Head pointer 8 | * @returns: new Head pointer 9 | * Complexity: O(1) 10 | */ 11 | typedef struct Node{ 12 | int info; 13 | struct Node *next, *prev; 14 | }Node; 15 | 16 | 17 | /** 18 | * Purpose: Forward traversal in the doubly linked list 19 | * Parameter: Head pointer 20 | * @returns: void 21 | * Complexity: O(N) 22 | */ 23 | void forwardTraversal(struct Node *head){ 24 | cout<<"\nForward traversal in Doubly List: \n"; 25 | while(head->next!=NULL){ 26 | cout<info<<" -> "; 27 | head=head->next; 28 | // cout<<"\nEnd..!\n"; 29 | } 30 | cout<info<prev!=NULL){//Loop continues until it reaches to start node 42 | cout<info<<" -> "; 43 | tail = tail->prev; 44 | } 45 | cout<info<>val; 59 | 60 | struct Node *newN=NULL; 61 | newN = (struct Node*)malloc(sizeof(struct Node));//dynamic mem allocated 62 | newN->info= val; 63 | 64 | newN->prev = NULL; //its new Head so null 65 | newN->next = head; //points to second node which is head now; 66 | head->prev = newN; //head prev points to newN and becomes second node 67 | 68 | return newN;//returns the new Head Node 69 | 70 | 71 | } 72 | 73 | 74 | /** 75 | * Purpose: Insert a new Node at the end using Head pointer(if tail pointer is not there) 76 | * Parameter: Head pointer 77 | * @returns: new Tail pointer 78 | * Complexity: O(N) 79 | */ 80 | struct Node* insertEndHead(struct Node*head){ 81 | 82 | 83 | while(head->next != NULL){//loops run it reaches the Tail Node 84 | head=head->next;// 85 | } 86 | 87 | struct Node* newTail=NULL; 88 | newTail = (struct Node*)malloc(sizeof(struct Node)); 89 | 90 | 91 | head->next= newTail; 92 | newTail->prev = head; 93 | newTail->next = NULL; 94 | 95 | cout<<"\nEnter the node which will be inserted at End:\n"; 96 | cin>>newTail->info; 97 | return newTail; 98 | 99 | } 100 | 101 | 102 | /** 103 | * Purpose: Insert a new Node at the end using Tail Pointer 104 | * Parameter: Head pointer 105 | * @returns: new Tail pointer 106 | * Complexity: O(1) 107 | */ 108 | struct Node* insertEndTail(struct Node *tail){ 109 | struct Node* newTail=NULL; 110 | newTail = (struct Node*)malloc(sizeof(struct Node)); 111 | 112 | cout<<"Enter the New Node inserted at End\n"; 113 | cin>>newTail->info; 114 | 115 | newTail->next=NULL; 116 | tail->next = newTail; 117 | newTail->prev= tail; 118 | 119 | return newTail; 120 | 121 | } 122 | 123 | /** 124 | * Purpose: Insert a new Node after a specific Node 125 | * Parameter: Head pointer 126 | * @returns: void(since there must be node after which new node will be inserted, it never be the first node) 127 | * Complexity: O(N) 128 | */ 129 | void insertAfter(struct Node *head){ 130 | int node_at,val; 131 | cout<<"Enter the Node after which you want to insert\n"; 132 | cin>>node_at; 133 | cout<<"Enter the Node need to be Inserted.!\n"; 134 | cin>>val; 135 | while(head->info != node_at){ 136 | head= head->next; 137 | } 138 | 139 | struct Node *newNode=NULL; 140 | newNode = (struct Node*)malloc(sizeof(struct Node)); 141 | newNode->info=val; 142 | 143 | newNode->next = head->next; 144 | (head->next)->prev = newNode; //next node prev is linked to newNode 145 | head->next=newNode; 146 | 147 | newNode->prev = head; 148 | 149 | } 150 | 151 | 152 | 153 | /** 154 | * Purpose: Deletes front node 155 | * Parameter: Head pointer 156 | * @returns: new Head pointer 157 | * Complexity: O(1) 158 | */ 159 | struct Node* deleteFront(struct Node* head){ 160 | struct Node *newHead= NULL; 161 | 162 | newHead = head->next; 163 | newHead->prev = NULL; 164 | (head->next) = NULL; //head becomes null reference 165 | free(head); 166 | return newHead; 167 | } 168 | 169 | 170 | /** 171 | * Purpose: Deletes end node using Tail pointer 172 | * Parameter: Tail pointer 173 | * @returns: new Tail pointer 174 | * Complexity: O(1) 175 | */ 176 | struct Node* deleteEnd(struct Node *tail){ 177 | 178 | struct Node *newTail = NULL; 179 | // newTail = (struct Node*)malloc(sizeof(struct Node)); 180 | 181 | newTail = tail->prev; 182 | newTail->next = NULL; 183 | tail->prev = NULL; 184 | free(tail); 185 | return newTail; 186 | } 187 | 188 | /** 189 | * Purpose: Deletes node after a specific node 190 | * Parameter: Head pointer 191 | * @returns: new Head pointer 192 | * Complexity: O(1) 193 | */ 194 | struct Node* deleteAfter(struct Node *head){ 195 | int val; 196 | cout<<"Enter the node which you want to delete\n"; 197 | cin>>val; 198 | 199 | while(head->info != val){ 200 | head= head->next; 201 | } 202 | struct Node *newHead= NULL; 203 | newHead = head->prev; 204 | newHead->next = head->next; 205 | (head->next)->prev = newHead; 206 | 207 | //making null reference 208 | head->next = NULL; head->prev= NULL; 209 | free(head); 210 | return newHead; 211 | 212 | /*(head->prev)->next = head->next; 213 | (head->next)->prev = head->prev; 214 | head->next = NULL; head->prev=NULL; 215 | free(head); 216 | */ 217 | 218 | } 219 | 220 | 221 | int main(){ 222 | struct Node *head=NULL;// 1st node of DLL 223 | struct Node *tail=NULL;// last node of DLL 224 | 225 | //dynamic mem allocation 226 | head =(struct Node*)malloc(sizeof(struct Node)); 227 | tail = (struct Node*)malloc(sizeof(struct Node)); 228 | 229 | int firstNode,secondNode; 230 | cout<<"Enter 1st Node of DLL"<>firstNode; 232 | 233 | cout<<"Enter 2nd Node of DLL"<>secondNode; 235 | 236 | head->info = firstNode; 237 | head->prev = NULL; //start node prev is NULL 238 | head->next = tail; 239 | 240 | 241 | tail->info= secondNode; 242 | tail->prev = head; 243 | tail->next = NULL; 244 | 245 | forwardTraversal(head); 246 | backwardTraversal(tail); 247 | 248 | 249 | int choice; 250 | while(choice!=8){ 251 | cout<<"\nEnter your choice:\n1: Insert Front\n2: Insert at End using Head O(N)\n3: Insert at End using Tail O(1)\n4: Insert After Node:\n5: Delete Front Node using Head O(1)\n6: Delete End Node using Tail O(1)\n7: Delete Particular Node\n8: Exit..!!!\n9: Reverse Traversal:\n"; 252 | cin>>choice; 253 | switch(choice){ 254 | case 1: head=insertBegin(head); 255 | break; 256 | case 2: tail=insertEndHead(head); 257 | break; 258 | case 3: tail=insertEndTail(tail); 259 | break; 260 | case 4: insertAfter(head); 261 | break; 262 | case 5: head=deleteFront(head); 263 | break; 264 | case 6: tail =deleteEnd(tail); 265 | break; 266 | case 7: head=deleteAfter(head); 267 | break; 268 | case 8: break; 269 | case 9: backwardTraversal(tail); 270 | 271 | } 272 | 273 | forwardTraversal(head); 274 | 275 | }//end of while 276 | 277 | } 278 | -------------------------------------------------------------------------------- /LinkedLists/SinglyLinkedList.cpp: -------------------------------------------------------------------------------- 1 | 2 | //############# SINGLY LINKED LIST with ALL Operations ############### 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | typedef struct Node{ 9 | int info; 10 | struct Node *next; 11 | }Node; 12 | 13 | /** 14 | * Purpose: Traverse through linkedlist. 15 | * Complexity: O(N) 16 | * @return: void 17 | */ 18 | void printList(struct Node *head){ 19 | 20 | if(head!= NULL){ 21 | while(head->next !=NULL){ 22 | cout<info<<" -> "; 23 | head = head->next; 24 | } 25 | cout<info;//for last node 26 | } 27 | else{ 28 | cout<<"Empty List..!"<>newN->info; 44 | 45 | newN->next = head; 46 | head = newN; 47 | 48 | // Freeing the newN Node 49 | // free(newN); 50 | 51 | //return the head as the Head Node 52 | return head; 53 | 54 | } 55 | 56 | 57 | /** 58 | * Purpose: Insert Node at end. 59 | * Complexity: O(N) 60 | * @return: void 61 | */ 62 | void insertEnd( struct Node* head){ 63 | 64 | while(head->next!=NULL){ 65 | head = head->next; 66 | } 67 | struct Node* newN= NULL; 68 | newN = (struct Node*)malloc(sizeof(struct Node)); 69 | cout<<"Enter the node need to Inserted at END..!\n"; 70 | cin>>newN->info; 71 | 72 | newN->next = head->next; //now it becomes end Node 73 | head->next = newN; // finally head->points to newN 74 | 75 | } 76 | 77 | /** 78 | * Purpose: Insert node after specific Node. 79 | * Complexity: O(N) 80 | * @return: Head pointer 81 | */ 82 | void insertAfter(struct Node* head){ 83 | cout<<"Enter the Node the after which you want to insert\n"; 84 | int nodeAt; cin>>nodeAt; 85 | 86 | while( head->info != nodeAt){ 87 | head = head->next; 88 | }//loops ends when head becomes the 89 | 90 | struct Node *newN= NULL; 91 | newN = (struct Node*)malloc(sizeof(struct Node)); //dynamic mem allocation 92 | cout<<"Enter the Node needs to be inserted\n"; 93 | cin>>newN->info; 94 | 95 | newN->next = head->next; 96 | head->next = newN; 97 | } 98 | 99 | /** 100 | * Purpose: Deletes fron Node. 101 | * Complexity: O(1) 102 | * @return: Head pointer 103 | */ 104 | struct Node* deleteFront(struct Node *head){ 105 | struct Node*newN; 106 | newN = head; 107 | head=head->next; //head is pointing to next node 108 | free(newN); 109 | return head; 110 | 111 | } 112 | 113 | /** 114 | * Purpose: Deletes Node at the End. 115 | * Complexity: O(N) 116 | * @return: Head pointer 117 | */ 118 | struct Node* deleteEnd(struct Node *head){ 119 | 120 | 121 | struct Node *endPrev=head; 122 | struct Node *startConst = head; //it always points to head Node 123 | //if only one element is there 124 | if(head->next == NULL){ 125 | head=deleteFront(head); 126 | return head; 127 | } 128 | 129 | else{ 130 | while(head->next!=NULL){ 131 | endPrev = head; //keep track of second last node 132 | head = head->next; 133 | } 134 | endPrev->next= NULL; //tail(head) becomes null referenced 135 | free(head); 136 | return startConst; 137 | } 138 | } 139 | 140 | /** 141 | * Purpose: Deletes Node after a specific Node. 142 | * Complexity: O(N) 143 | * @return: Head pointer 144 | */ 145 | void deleteAfter(struct Node*head){ 146 | cout<<"Enter the Node the after which you want to Delete\n"; 147 | int nodeAt; cin>>nodeAt; 148 | 149 | while(head->info!=nodeAt){ 150 | head= head->next; 151 | } 152 | struct Node*oldNptr=NULL; 153 | oldNptr = head->next;//pointer refers to Node need to be deleted 154 | head->next = oldNptr->next; //heads points the Node after the DeleteNode(oldNptr) 155 | oldNptr=NULL; //deleted node is null referenced 156 | free(oldNptr); //deallocates the memory 157 | 158 | } 159 | 160 | /** 161 | * Purpose: Deletes specific Node. 162 | * Complexity: O(N) 163 | * @return: Head pointer 164 | */ 165 | struct Node* deleteNode( struct Node*head){ 166 | cout<<"Enter the Node which you want to Delete\n"; 167 | int nodeAt; cin>>nodeAt; 168 | 169 | struct Node *ptrN= head; //node to keep track of prev of deleted node 170 | struct Node *newHead = head; //always points to head Node 171 | 172 | //if the node is head Node itself 173 | if(head->info == nodeAt){ 174 | head = deleteFront(head); 175 | return head; 176 | } 177 | else{//if it is not the start Node 178 | while(head->info!=nodeAt){ 179 | ptrN = head; //points to Node prev to deleted node 180 | head=head->next; 181 | }//stops when head becomes deleted node 182 | 183 | ptrN->next = head->next; //ptrN points to Node which need to be deleted 184 | head = NULL; //node need to deleted becomes Null Referenced 185 | free(head); 186 | } 187 | return newHead; 188 | 189 | } 190 | 191 | 192 | int main(){ 193 | 194 | struct Node *head; 195 | head=NULL; 196 | 197 | int choice; 198 | 199 | while(choice!=8){ 200 | cout<<"\nEnter Your Choice\n1: Insert Begin\n2: Insert End\n3: Insert After\n4: Delete Front\n5: Delete End\n6: Delete After\n7: Delete Particular Node\n8: EXIT"<>choice; 202 | switch(choice){ 203 | case 1: head=insertBegin(head); 204 | break; 205 | case 2: insertEnd(head); 206 | break; 207 | case 3: insertAfter(head); 208 | break; 209 | case 4: head=deleteFront(head); 210 | break; 211 | case 5: head = deleteEnd(head); 212 | break; 213 | 214 | case 6: deleteAfter(head); 215 | break; 216 | case 7: head=deleteNode(head); 217 | break; 218 | case 8: break; //EXIT 219 | default: break; 220 | } 221 | printList(head); 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /Queues/PriorityQueue/PriorityQueueWithLinkedList.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Priority Queue Implementation using Linked List 3 | 4 | * Time Complexity Analysis 5 | * Enque Operation amortized time O(N) 6 | * Deque Operation amortized time O(1) 7 | * Peek(Getting the Highest Priority Element) amortized time O(1) 8 | 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | 15 | /** 16 | * Node -> Stores information of each element of Queue 17 | * data -> stores element value 18 | * priority -> stores element's priority 19 | * next -> stores the next element 20 | **/ 21 | typedef struct Node { 22 | 23 | int data; // Stores Node value 24 | 25 | int priority; // Higher Value indicates highest priority 26 | 27 | struct Node* next; 28 | 29 | } Node; 30 | 31 | 32 | /** 33 | * Creates a new Node 34 | */ 35 | Node* newNode(int d, int p){ 36 | 37 | Node* temp = (Node*)malloc(sizeof(Node)); 38 | 39 | temp->data = d; 40 | temp->priority = p; 41 | 42 | temp->next = NULL; 43 | 44 | 45 | } 46 | 47 | /** 48 | * Peek -> returs the value at Head(Having highest Priority) 49 | * Time Complexity: O(1) 50 | */ 51 | int peek( Node** head){ 52 | 53 | return (*head)->data; 54 | } 55 | 56 | 57 | /** 58 | * Deque(Pop) -> removes the element having highest priority from Queue 59 | * Removes Head element 60 | * Time Complexity: O(1) 61 | */ 62 | void pop( Node** head){ 63 | 64 | Node* temp = *head; // storing the current head into temp 65 | 66 | (*head) = (*head)->next; // storing the next node info to Head 67 | 68 | free(temp); // free up Temp node 69 | } 70 | 71 | 72 | /** 73 | * Push -> Insert a new node in the queue at a position according to its priority 74 | * 75 | * Time Complexity: O(N) 76 | */ 77 | void push(Node** head, int d, int p){ 78 | 79 | Node* start = (*head); // stores head node info to start 80 | 81 | // Create a new node 82 | Node* temp = newNode(d, p); 83 | 84 | 85 | // If the Head Node as lower priority than NewNode 86 | if( (*head)->priority < p ){ 87 | 88 | // Insert new node as Head 89 | temp->next = (*head); 90 | 91 | //Making new node as head 92 | (*head) = temp; 93 | 94 | }else{ 95 | 96 | /** 97 | * Travesing through list and Finding position to insert new Node 98 | * If same priority Node is present then fisrt come first serve phenomena will be followed (i.e start->next->priority >= p ) 99 | */ 100 | while( start->next != NULL && start->next->priority >= p ){ 101 | 102 | // Store the Node after which new Node will be inserted 103 | start = start->next; 104 | 105 | } 106 | 107 | /** 108 | * Inserting a New Node 109 | * A. Either at the End Of Queue 110 | * B. or at the Required Position 111 | */ 112 | temp->next = start->next; 113 | start->next = temp; 114 | 115 | 116 | } 117 | 118 | } 119 | 120 | 121 | /** 122 | * Function to check wheather the node is empty or not 123 | */ 124 | int isEmpty( Node** head){ 125 | 126 | return (*head) == NULL; 127 | } 128 | 129 | 130 | /** 131 | * Printing the Priority Queue 132 | */ 133 | 134 | int printQueue(Node* head){ 135 | 136 | if( head == NULL ){ 137 | printf("Queue is empty\n"); 138 | exit(0); 139 | } 140 | 141 | while( head->next != NULL){ 142 | 143 | printf("(%d,%d)-> ",head->data,head->priority ); 144 | 145 | head = head->next; 146 | } 147 | 148 | printf("(%d,%d)\n",head->data,head->priority ); 149 | 150 | 151 | } 152 | 153 | 154 | 155 | int main(){ 156 | 157 | int choice, nodeData, nodePriority; //Stores no of element 158 | 159 | Node* priorityQueue = newNode(4,2); // Initialzing Priority Queue with a Node(data->4, priority->2) 160 | 161 | printf("Priority Queue Implementation using Linked List\n"); 162 | 163 | 164 | while(1){ 165 | 166 | 167 | printf("\nEnter your choice\n"); 168 | printf("1. Insert a new Node\n2. Delete a Node\n3. Peek the highest priority(Head) Node\n4. Print complete Priority Queue with Priority\n5. Exit\n"); 169 | scanf("%d",&choice); 170 | 171 | 172 | 173 | switch(choice){ 174 | 175 | case 1: printf("Insert a new Node in Queue\n"); 176 | printf("Enter Node data: "); 177 | scanf("%d", &nodeData); 178 | printf("\nEnter Node priority: "); 179 | scanf("%d", &nodePriority); 180 | 181 | push(&priorityQueue, nodeData, nodePriority); 182 | break; 183 | 184 | case 2: printf("Deleting a Node(highest priority(head))\n"); 185 | 186 | pop(&priorityQueue); 187 | break; 188 | 189 | case 3: printf("Highest Priority Node: data:%d",peek(&priorityQueue)); 190 | break; 191 | 192 | case 4: printf("The Priority Queue:\n"); 193 | 194 | printQueue(priorityQueue); 195 | break; 196 | 197 | case 5: exit(0); 198 | 199 | default: break; 200 | 201 | } 202 | 203 | 204 | 205 | } 206 | 207 | } 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /Queues/QueueUsingArray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Queue{ 6 | int front, rear, size; 7 | unsigned int capacity; //Stores the capacity of Queue 8 | int *array; 9 | }; 10 | // Function to create Queue of a specific capacity 11 | // Initialize the size of Queue as 0 12 | struct Queue* createQueue(unsigned int capacity){ 13 | struct Queue* queue = (struct Queue*) malloc(sizeof(struct Queue)); 14 | queue->capacity = capacity; 15 | queue->front = 0; 16 | queue->size = 0; 17 | queue->rear = capacity-1; //refer enqueue function 18 | // Create Integer array of size 'capacity' 19 | queue->array =(int*) malloc((queue->capacity)*sizeof(int)); 20 | return queue; 21 | } 22 | // Queue is full when size becomes equal to capacity 23 | // Overflow 24 | int isFull(struct Queue* queue) { 25 | return (queue->size == queue->capacity); 26 | } 27 | // Queue is empty when size is 0 28 | // Underflow 29 | int isEmpty(struct Queue* queue) { 30 | return (queue->size == 0); 31 | } 32 | 33 | //Function to add item in Queue 34 | //It alters rear and size 35 | void enqueue(struct Queue* queue, int item) { 36 | if(isFull(queue)) 37 | return; 38 | // Circular Indexing Technique 39 | // After rear becomes last index(epmty Queue) it will point to first Index of Arrsy 40 | queue->rear = (queue->rear+1)%queue->capacity; 41 | queue->array[queue->rear] = item; 42 | queue->size++; 43 | } 44 | 45 | // Function to remove item from queue 46 | // It removes item from queue 47 | void dequeue(struct Queue* queue) { 48 | if(isEmpty(queue)) 49 | return; 50 | 51 | int item = queue->array[queue->front]; 52 | // Circular indexing technique , 53 | // After last index queue->front will be point to Null Index i.e index before 0th Index(empty queue) 54 | queue->front = (queue->front+1)%queue->capacity; 55 | queue->size--; 56 | } 57 | 58 | //Function to get front item of queue 59 | int getFront(struct Queue* queue) { 60 | // Checking underflow condition 61 | if(isEmpty(queue)) { 62 | printf("\nQueue is empty\n"); 63 | return INT_MIN; 64 | } 65 | return queue->array[queue->front]; 66 | } 67 | 68 | // Function to get rear item of queue 69 | int getRear(struct Queue* queue) { 70 | if(isEmpty(queue)) 71 | return INT_MIN; 72 | return queue->array[queue->rear]; 73 | } 74 | 75 | int main(){ 76 | 77 | struct Queue* queue = createQueue(1000); 78 | enqueue(queue, 10); 79 | enqueue(queue, 345); 80 | enqueue(queue, 675); 81 | printf("\nQueue size: %d\n", queue->size); 82 | printf("%d front of Queue", getFront(queue)); 83 | dequeue(queue); 84 | printf("\n%d rear of Queue", getRear(queue)); 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures/C 2 | Implementation of Data Structures in C. 3 | 4 | ### Contents 5 | #### [Graphs](https://github.com/AlokikPathak/data-structures/tree/master/Graphs) 6 | * [DirectedWeightedGraphAdjListRepresentation.c](https://github.com/AlokikPathak/data-structures/blob/master/Graphs/DirectedWeightedGraphAdjListRepresentation.c) 7 | #### [LinkedLists](https://github.com/AlokikPathak/data-structures/tree/master/LinkedLists) 8 | * [DoublyLinkedList.cpp](https://github.com/AlokikPathak/data-structures/blob/master/LinkedLists/DoublyLinkedList.cpp) 9 | * [SinglyLinkedList.cpp](https://github.com/AlokikPathak/data-structures/blob/master/LinkedLists/SinglyLinkedList.cpp) 10 | #### [Queues](https://github.com/AlokikPathak/data-structures/tree/master/Queues) 11 | * [PriorityQueue](https://github.com/AlokikPathak/data-structures/tree/master/Queues/PriorityQueue) 12 | * [PriorityQueueWithLinkedList.c](https://github.com/AlokikPathak/data-structures/blob/master/Queues/PriorityQueue/PriorityQueueWithLinkedList.c) 13 | * [QueueUsingArray.c](https://github.com/AlokikPathak/data-structures/blob/master/Queues/QueueUsingArray.c) 14 | #### [Stack](https://github.com/AlokikPathak/data-structures/tree/master/Stacks) 15 | * [StackUsingDynamicArray.c](https://github.com/AlokikPathak/data-structures/blob/master/Stacks/StackUsingDynamicArray.c) 16 | #### [Trees](https://github.com/AlokikPathak/data-structures/tree/master/Trees) 17 | * [BinarySearchTree](https://github.com/AlokikPathak/data-structures/tree/master/Trees/BinarySearchTree) 18 | * [BSTInsertDeleteNode.c](https://github.com/AlokikPathak/data-structures/blob/master/Trees/BinarySearchTree/BSTInsertDeleteNode.c) 19 | * [BinarySearchTreeInorderTraversal.c](https://github.com/AlokikPathak/data-structures/blob/master/Trees/BinarySearchTree/BinarySeachTreeInorderTraversal.c) 20 | * [Heaps](https://github.com/AlokikPathak/data-structures/tree/master/Trees/Heaps) 21 | * [PriorityQueues](https://github.com/AlokikPathak/data-structures/tree/master/Trees/Heaps/PriorityQueues) 22 | * [PriorityQueueBinaryHeap.c](https://github.com/AlokikPathak/data-structures/blob/master/Trees/Heaps/PriorityQueues/PriorityQueueBinaryHeap.c) 23 | * [HeapSortMaxHeap.c](https://github.com/AlokikPathak/data-structures/blob/master/Trees/Heaps/HeapSortMaxHeap.c) 24 | * [HeapSortMinHeap.c](https://github.com/AlokikPathak/data-structures/blob/master/Trees/Heaps/HeapSortMinHeap.c) 25 | * [MaxHeap.c](https://github.com/AlokikPathak/data-structures/blob/master/Trees/Heaps/MaxHeap.c) 26 | * [MinHeap.c](https://github.com/AlokikPathak/data-structures/blob/master/Trees/Heaps/MinHeap.c) 27 | #### [HashTables](https://github.com/AlokikPathak/data-structures/tree/master/HashTables) 28 | * [HashTableWithChaining.c](https://github.com/AlokikPathak/data-structures/blob/master/HashTables/HashTableWithChaining.c) 29 | 30 | 31 | -------------------------------------------------------------------------------- /Stacks/StackUsingDynamicArray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /** 6 | * Date modified: 28/12/2019 7 | * Stack(Last-In-First-Out) 8 | * @member int front: stores index of 1st element of Stack 9 | * @member int rear: stores index of last element of Stack 10 | * @member int size: stores number of elements present in Stack 11 | * @member unsigned int capacity: maximum no. of elements stack can have 12 | * @member int* array: store pointer to array of elements 13 | */ 14 | struct Stack{ 15 | int top, size; 16 | unsigned int capacity; 17 | int* array; 18 | }; 19 | 20 | /** 21 | * Name: createStack() 22 | * Purpose: creates a Stack of given capacity 23 | * @param unsigned int capacity 24 | * @return struct Stack* 25 | */ 26 | struct Stack* createStack(unsigned int capacity) { 27 | struct Stack *stack = (struct Stack*) malloc(sizeof(struct Stack)); 28 | // Allocating a array of given capacity and stack->array points to it 29 | stack->array = (int*) malloc(capacity * sizeof(int)); 30 | // Initialization 31 | stack->capacity = capacity; 32 | stack->top = -1;//Stack-Underflow 33 | stack->size = 0; 34 | return stack; 35 | } 36 | 37 | /** 38 | * Name: isEmpty() 39 | * Purpose: Check whether Stack is empty or not,If False, returns 0, else any number 40 | * @param struct Stack* stack 41 | * @return int 42 | */ 43 | int isEmpty(struct Stack* stack) { 44 | return (stack->size == 0); 45 | } 46 | 47 | /** 48 | * Name: isFull() 49 | * Purpose: Check whether Stack is Full or not, If False, returns 0, else any number 50 | * @param struct Stack* stack 51 | * @return int 52 | */ 53 | int isFull(struct Stack* stack) { 54 | return (stack->size == stack->capacity); 55 | } 56 | 57 | /** 58 | * Name: pop() 59 | * Purpose: Pop out the top item(last item) from Stack 60 | * @param struct Stack* 61 | * @return void 62 | */ 63 | void pop(struct Stack* stack) { 64 | if(isEmpty(stack)){ 65 | printf("\nStack underflow"); 66 | return; 67 | } 68 | stack->top--; 69 | stack->size--; 70 | } 71 | 72 | /** 73 | * Name: push() 74 | * Purpose: Push item to Stack if it in not full 75 | * @param struck Stack* 76 | * @param int item 77 | * @return void 78 | */ 79 | void push(struct Stack* stack, int item) { 80 | if(isFull(stack)) { 81 | printf("\nStack Overflow"); 82 | return; 83 | } 84 | stack->top = (stack->top+1)%stack->capacity; 85 | stack->array[stack->top] = item; 86 | stack->size++; 87 | } 88 | 89 | /** 90 | * Name: getTop() 91 | * Purpose: Return the Top Item, if Stack is not empty, else INT_MIN 92 | * @param struct Stack* stack 93 | * @return int 94 | */ 95 | int getTop(struct Stack* stack) { 96 | if(isEmpty(stack)){ 97 | printf("\nStack is empty"); 98 | return INT_MIN; 99 | } 100 | return (stack->array[stack->top]); 101 | } 102 | 103 | int main() { 104 | unsigned int capacity, choice; 105 | int item; 106 | printf("Enter the capacity of Stack\n"); 107 | scanf("%d", &capacity); 108 | struct Stack* stack = createStack(capacity); 109 | 110 | while(1){ 111 | printf("\nEnter your choice?\n1. Show Top\n2. Pop \n3. Push \n4. Size of Stack \n5. Capacity of Stack\n6. Exit\n"); 112 | scanf("%d", &choice); 113 | switch(choice) { 114 | case 1: printf("\nTop of Stack is: %d", getTop(stack)); 115 | break; 116 | case 2: pop(stack); 117 | break; 118 | case 3: printf("\nEnter item to be pushed in Stack: "); 119 | scanf("%d", &item); 120 | push(stack, item); 121 | break; 122 | case 4: printf("\nSize of Stack is: %d", stack->size); 123 | break; 124 | case 5: printf("\nCapacity of Stack is: %d", stack->capacity); 125 | break; 126 | case 6: exit(0); 127 | default: break; 128 | } 129 | } 130 | 131 | free(stack); 132 | return 0; 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /Trees/BinarySearchTree/BSTInsertDeleteNode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // BST node structure 5 | struct node{ 6 | int key; 7 | struct node *left, *right; 8 | }; 9 | 10 | // Create a new Node in BST 11 | struct node* newNode( int item) { 12 | 13 | struct node *temp = (struct node*) malloc( sizeof(struct node) ); 14 | 15 | temp->key = item; 16 | 17 | temp->left = temp->right = NULL; 18 | 19 | return temp; 20 | } 21 | 22 | 23 | // Utility function to insert new node in given BST with given key value 24 | struct node* insert( struct node* node, int key) { 25 | 26 | /* If tree empty, create and returns root node*/ 27 | if( node == NULL){ 28 | 29 | return newNode(key); 30 | 31 | } 32 | /* if new key is smaller than root node key */ 33 | else if( key < node->key){ 34 | node->left = insert( node->left, key ); 35 | } 36 | /* if new key is greater that root node key */ 37 | else if( key > node->key ) { 38 | node->right = insert( node->right, key ); 39 | } 40 | 41 | /* returns (unchanged) node pointer(root node)*/ 42 | return node; 43 | } 44 | 45 | 46 | /* 47 | * Depth First Search: In-order Traversal (left->root->right) 48 | */ 49 | void inorderTraverse( struct node *root) { 50 | 51 | if( root != NULL ) { 52 | 53 | inorderTraverse( root->left ); 54 | printf("%d\n", root->key ); 55 | inorderTraverse( root->right ); 56 | 57 | } 58 | } 59 | 60 | void preorderTraverse( struct node *root) { 61 | 62 | if( root != NULL) { 63 | 64 | printf( "%d\n", root->key); 65 | preorderTraverse( root->left ); 66 | preorderTraverse( root->right ); 67 | } 68 | } 69 | 70 | void postorderTraverse( struct node *root ) { 71 | 72 | if( root != NULL) { 73 | 74 | postorderTraverse( root->left ); 75 | postorderTraverse( root->right ); 76 | printf("%d\n", root->key); 77 | } 78 | } 79 | 80 | /** 81 | * "In-order successor" needed for deletion of Node if it has both children 82 | * Left-most leaf node of Right-subtreee of the Node to be deleted is In-order successor 83 | * minValueNode finds the In-order successor of that node 84 | * @return struct Node* i.e in-order successor 85 | */ 86 | struct node* minValueNode( struct node* root) { 87 | 88 | // Base Case: If the node doesn't have left-child i.e. the node is In-order successor( or minValueNode of the tree) 89 | if ( root->left == NULL) { 90 | return root; 91 | 92 | }else { 93 | // always traversing through left child 94 | return minValueNode( root->left ); 95 | } 96 | 97 | } 98 | 99 | /** 100 | * Deletes the Node with specific Key value 101 | * 3 Cases are there 102 | * 1. If the delete Node has only Left Child 103 | * 2. If the delete Node has only Right Child 104 | * 3. If the Delete Node has both Children 105 | * @return struct Node* new root of BST 106 | */ 107 | struct node* deleteNodeBST( struct node* root, int key ) { 108 | 109 | 110 | // Traversing and finding the Node need to be deleted 111 | 112 | // Base case 113 | if(root == NULL) { 114 | return root; 115 | } 116 | 117 | /** 118 | * If Key is less than the Root's key then the Node needed to be deleted 119 | * lies in the left sub-tree 120 | */ 121 | if( key < root->key ) { 122 | root->left = deleteNodeBST( root->left, key); 123 | } 124 | 125 | /** 126 | * If Key is greater than the Root's key then the Node needed to be deleted 127 | * lies in the right sub-tree 128 | */ 129 | else if( key > root->key ) { 130 | root->right = deleteNodeBST( root->right, key ); 131 | } 132 | /** 133 | * If Key is equal to the Node needed to be deleted key 134 | * We've the reached to Node in BST which needed to be deleted 135 | */ 136 | else { 137 | 138 | 139 | /** 140 | * 3 Cases are there 141 | * 1. If the delete Node has only Left Child 142 | * 2. If the delete Node has only Right Child 143 | * 3. If the Delete Node has both Children 144 | */ 145 | 146 | 147 | // Case 1: If the Delete Node has only Left child or no child 148 | if( root->right == NULL ) { 149 | 150 | // assign the root->left to new temp node 151 | struct node *temp = root->left; 152 | // clear old root node 153 | free( root ); 154 | 155 | // returning the new root node 156 | return temp; 157 | } 158 | // Case 2: if Delete Node has only right child or no child 159 | else if( root->left == NULL ) { 160 | 161 | // assign the root->right to new temp node 162 | struct node *temp = root->right; 163 | // clear old root node 164 | free( root ); 165 | 166 | // returning the new root node 167 | return temp; 168 | } 169 | // Case 3: if Delete Node has both child 170 | // So Delete Node is replaced by its in-order successor 171 | // in-order successor is left-most node(smallest) in right-subtree of Delete Node 172 | else { 173 | 174 | // Passing the root node of the Right sub-tree of Delete Node to get in-order successor 175 | struct node *temp = minValueNode( root->right ); 176 | 177 | // Copy the content of in-order successor to Delete Node 178 | root->key = temp->key; 179 | 180 | // Delete the in-order successor 181 | // Further Optimise by Tracking the Parent of Successor 182 | root->right = deleteNodeBST( root->right, temp->key); 183 | 184 | } 185 | } 186 | return root; 187 | }//end of function 188 | 189 | 190 | int main(){ 191 | 192 | struct node *root = NULL; 193 | 194 | /** 195 | 50 196 | / \ 197 | 30 70 198 | / \ / \ 199 | 20 40 60 80 200 | */ 201 | 202 | //1st Node 203 | root = insert(root, 50); 204 | 205 | root = insert(root, 30); 206 | root = insert(root, 20); 207 | root = insert(root, 40); 208 | root = insert(root, 70); 209 | root = insert(root, 60); 210 | root = insert(root, 80); 211 | 212 | // Print DFS: inorder traverse 213 | printf("In-order(sorted) Traversal:\n"); 214 | inorderTraverse( root ); 215 | 216 | printf("Pre-order traversal:\n"); 217 | preorderTraverse( root ); 218 | 219 | printf("Post-order traversal:\n"); 220 | postorderTraverse( root ); 221 | 222 | root = deleteNodeBST(root, 50); 223 | printf("In-order(sorted) Traversal after delete node '50':\n"); 224 | inorderTraverse( root ); 225 | /** 226 | After Deleting Root Node "50" 227 | 60 228 | / \ 229 | 30 70 230 | / \ \ 231 | 20 40 80 232 | */ 233 | 234 | root = deleteNodeBST(root, 80); 235 | printf("In-order(sorted) Traversal after delete node '80':\n"); 236 | inorderTraverse( root ); 237 | /** 238 | After Deleting Root Node "80" 239 | 60 240 | / \ 241 | 30 70 242 | / \ 243 | 20 40 244 | */ 245 | 246 | root = insert(root, 98); 247 | printf("In-order(sorted) Traversal after inserting node '98':\n"); 248 | inorderTraverse( root ); 249 | /** 250 | After Inserting Root Node "98" 251 | 60 252 | / \ 253 | 30 70 254 | / \ \ 255 | 20 40 98 256 | */ 257 | 258 | root = insert(root, 35); 259 | printf("In-order(sorted) Traversal after inserting node '35':\n"); 260 | inorderTraverse( root ); 261 | /** 262 | After Inserting Root Node "98" 263 | 60 264 | / \ 265 | 30 70 266 | / \ \ 267 | 20 40 98 268 | / 269 | 35 270 | */ 271 | 272 | root = deleteNodeBST(root, 40); 273 | printf("In-order(sorted) Traversal after delete node '40':\n"); 274 | inorderTraverse( root ); 275 | /** 276 | After Deleting Root Node "40" 277 | 60 278 | / \ 279 | 30 70 280 | / \ \ 281 | 20 35 98 282 | 283 | */ 284 | 285 | root = deleteNodeBST(root, 70); 286 | printf("In-order(sorted) Traversal after delete node '70':\n"); 287 | inorderTraverse( root ); 288 | /** 289 | After Deleting Root Node "70" 290 | 60 291 | / \ 292 | 30 98 293 | / \ 294 | 20 35 295 | 296 | */ 297 | 298 | return 0; 299 | 300 | } 301 | 302 | -------------------------------------------------------------------------------- /Trees/BinarySearchTree/BinarySeachTreeInorderTraversal.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // BST node structure 5 | struct node{ 6 | int key; 7 | struct node *left, *right; 8 | }; 9 | 10 | // Create a new Node in BST 11 | struct node* newNode( int item) { 12 | 13 | struct node *temp = (struct node*) malloc( sizeof(struct node) ); 14 | 15 | temp->key = item; 16 | 17 | temp->left = temp->right = NULL; 18 | 19 | return temp; 20 | } 21 | 22 | 23 | // Utility function to insert new node in given BST with given key value 24 | struct node* insert( struct node* node, int key) { 25 | 26 | /* If tree empty, create and returns root node*/ 27 | if( node == NULL){ 28 | 29 | return newNode(key); 30 | 31 | } 32 | /* if new key is smaller than root node key */ 33 | else if( key < node->key){ 34 | node->left = insert( node->left, key ); 35 | } 36 | /* if new key is greater that root node key */ 37 | else if( key > node->key ) { 38 | node->right = insert( node->right, key ); 39 | } 40 | 41 | /* returns (unchanged) node pointer(root node)*/ 42 | return node; 43 | } 44 | 45 | 46 | /* 47 | * Depth First Search: In-order Traversal (left->root->right) 48 | */ 49 | void inorderTraverse( struct node *root) { 50 | 51 | if( root != NULL ) { 52 | 53 | inorderTraverse( root->left ); 54 | printf("%d\n", root->key ); 55 | inorderTraverse( root->right ); 56 | 57 | } 58 | } 59 | 60 | void preorderTraverse( struct node *root) { 61 | 62 | if( root != NULL) { 63 | 64 | printf( "%d\n", root->key); 65 | preorderTraverse( root->left ); 66 | preorderTraverse( root->right ); 67 | } 68 | } 69 | 70 | void postorderTraverse( struct node *root ) { 71 | 72 | if( root != NULL) { 73 | 74 | postorderTraverse( root->left ); 75 | postorderTraverse( root->right ); 76 | printf("%d\n", root->key); 77 | } 78 | } 79 | 80 | 81 | int main(){ 82 | 83 | struct node *root = NULL; 84 | 85 | //1st Node 86 | root = insert(root, 50); 87 | 88 | root = insert(root, 30); 89 | root = insert(root, 20); 90 | root = insert(root, 40); 91 | root = insert(root, 70); 92 | root = insert(root, 60); 93 | root = insert(root, 80); 94 | 95 | // Print DFS: inorder traverse 96 | printf("In-order(sorted) Traversal:\n"); 97 | inorderTraverse( root ); 98 | 99 | printf("Pre-order traversal:\n"); 100 | preorderTraverse( root ); 101 | 102 | printf("Post-order traversal:\n"); 103 | postorderTraverse( root ); 104 | 105 | return 0; 106 | 107 | } 108 | 109 | -------------------------------------------------------------------------------- /Trees/Heaps/HeapSortMaxHeap.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * Name: swapTwoNum() 5 | * Purpose: Swaps two numbers 6 | * @param: int* a 7 | * @param: int* b 8 | * @return: void 9 | * @complexity: O(1) i.e constant time 10 | */ 11 | void swapTwoNum(int *a, int *b) 12 | { 13 | *a = (*a + *b) - (*b = *a); 14 | } 15 | 16 | /** 17 | * Name: takeArrayInput() 18 | * Purpose: takes input of given array 19 | * @param: int* arr, pointer to array 20 | * @param: unsigned int size, size of array 21 | * @return: void 22 | * @complexity: O(N) i.e. linear 23 | */ 24 | void takeArrayInput(int *arr, int size) 25 | { 26 | unsigned int i; 27 | printf("Enter %d elements of array\n", size); 28 | for (i = 0; i < size; i++) 29 | scanf("%d", &arr[i]); 30 | } 31 | 32 | /** 33 | * Name: takeArrayInput() 34 | * Purpose: takes input of given array 35 | * @param: int* arr, pointer to array 36 | * @param: unsigned int size, size of array 37 | * @return: void 38 | * @complexity: O(N) i.e. linear 39 | */ 40 | void printArray(int arr[], int size) 41 | { 42 | unsigned int i; 43 | for (i = 0; i < size; i++) 44 | printf("%d ", arr[i]); 45 | } 46 | 47 | /** 48 | * Name: maxHeapify() 49 | * Purpose: Max-heapify the given root of sub-tree as array 50 | * @param: int* arr, pointer to heap array 51 | * @param: unsigned int size, stores size of heap array 52 | * @param: unsigned int nodeIndex, contains index of root node of sub-tree needed to be max-heap 53 | * @return: void 54 | * @complexity: O(logN) i.e. logrithimic time 55 | */ 56 | void maxHeapify(int *arr, int size, int nodeIndex) 57 | { 58 | 59 | int left = (2 * nodeIndex) + 1; // left child Node index( since array is from 0 so +1) 60 | int right = (2 * nodeIndex) + 2; // right child Node index 61 | int largest = nodeIndex; // initialize as root node 62 | 63 | if (left < size && arr[left] > arr[largest]) 64 | largest = left; 65 | if (right < size && arr[right] > arr[largest]) 66 | largest = right; 67 | 68 | // largest in not root Node index(i.e. modified) 69 | if (largest != nodeIndex) 70 | { 71 | // swapping Root Node with child having largest value & build Max Heap Sub-tree 72 | swapTwoNum(&arr[nodeIndex], &arr[largest]); 73 | // recursively MaxHeapify the new subtree formed after swap 74 | maxHeapify(arr, size, largest); 75 | } 76 | } 77 | 78 | /** 79 | * Name: buildMaxHeap() 80 | * Purpose: Build Max heap out of an array visualized as Heap 81 | * @param: int arr[] 82 | * @param: int n, size of array 83 | * @return: void 84 | * @complexity : O(N) (max_heapify complexity: O(logN) and total n/2 steps so O(N) is linear time) 85 | * If array is visualized as nearly Complete Binary Tree, all the elements after n/2 to n are leaves 86 | * In heaps, the leaves are automatically a Max Heap, since they don't have child 87 | * 88 | */ 89 | void buildMaxHeap(int *arr, int n) 90 | { 91 | int i; 92 | for (i = (n / 2) - 1; i >= 0; i--) 93 | maxHeapify(arr, n, i); 94 | } 95 | 96 | /** 97 | * Name: heapSortMaxHeap() 98 | * Purpose: Build Max Heap out of given array visualized as heap, and then sorting the Max Heap 99 | * @param: int* arr, pointer to array 100 | * @param: int n, size of array 101 | * @return: void 102 | * @complexity: O(NlogN), since BuilMaxHeap() takes O(N) and traversing through Binary Tree takes logarithimic time 103 | */ 104 | void heapSortMaxHeap(int *arr, int n) 105 | { 106 | int i; 107 | // Making Max Heap using the heap 108 | buildMaxHeap(arr, n); 109 | printf("\nMax Heap: "); 110 | printArray(arr, n); 111 | 112 | // Performing Heap Sort on Max heap 113 | // heap sort using man-heap 114 | // exchange last node with root, man-heapify the changed heap 115 | // doing this for all nodes from last to first( sorting using bottom-to-top(leaves to root) way in heap) 116 | for (i = n - 1; i >= 0; i--) 117 | { 118 | // Move current root to end(i.e i, everytime getting reduced by 1) 119 | swapTwoNum(&arr[0], &arr[i]); 120 | // Remove the last node, and call Max Heapify on reduced heap of size "i" 121 | maxHeapify(arr, i, 0); 122 | } 123 | } 124 | 125 | /** 126 | * Name: main() 127 | * Pupose: Starts execution of program 128 | * @return: int 129 | * ex. n = 10, arr[n]= {14, 16, 10, 9, 7, 8, 3, 2, 4, 1} 130 | * Max_Heap: {16, 14, 10, 9, 7, 8, 3, 2, 4, 1} 131 | * Sorted: {1, 2, 3, 4, 7, 8, 9, 10, 14, 16 } 132 | */ 133 | int main() 134 | { 135 | unsigned int n; 136 | printf("Enter Size of Array\n"); 137 | scanf("%d", &n); 138 | int arr[n]; 139 | takeArrayInput(arr, n); 140 | heapSortMaxHeap(arr, n); 141 | printf("Sorted array: \n"); 142 | printArray(arr, n); 143 | 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /Trees/Heaps/HeapSortMinHeap.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * Name: swapTwoNum() 5 | * Purpose: Swaps two numbers 6 | * @param: int* a 7 | * @param: int* b 8 | * @return: void 9 | * @complexity: O(1) i.e constant time 10 | */ 11 | void swapTwoNum(int *a, int *b) 12 | { 13 | *a = (*a + *b) - (*b = *a); 14 | } 15 | 16 | /** 17 | * Name: takeArrayInput() 18 | * Purpose: takes input of given array 19 | * @param: int* arr, pointer to array 20 | * @param: unsigned int size, size of array 21 | * @return: void 22 | * @complexity: O(N) i.e. linear 23 | */ 24 | void takeArrayInput(int *arr, int size) 25 | { 26 | unsigned int i; 27 | printf("Enter %d elements of array\n", size); 28 | for (i = 0; i < size; i++) 29 | scanf("%d", &arr[i]); 30 | } 31 | 32 | /** 33 | * Name: takeArrayInput() 34 | * Purpose: takes input of given array 35 | * @param: int* arr, pointer to array 36 | * @param: unsigned int size, size of array 37 | * @return: void 38 | * @complexity: O(N) i.e. linear 39 | */ 40 | void printArray(int arr[], int size) 41 | { 42 | unsigned int i; 43 | for (i = 0; i < size; i++) 44 | printf("%d ", arr[i]); 45 | } 46 | 47 | /** 48 | * Name: minHeapify() 49 | * Purpose: Min-heapify the given root of sub-tree as array 50 | * @param: int* arr, pointer to heap array 51 | * @param: unsigned int size, stores size of heap array 52 | * @param: unsigned int nodeIndex, contains index of root node of sub-tree needed to be mix-heap 53 | * @return: void 54 | * @complexity: O(logN) i.e. logrithimic time 55 | */ 56 | void minHeapify(int *arr, int size, int nodeIndex) 57 | { 58 | 59 | int left = (2 * nodeIndex) + 1; // left child Node index( since array is from 0 so +1) 60 | int right = (2 * nodeIndex) + 2; // right child Node index 61 | int smallest = nodeIndex; // initialize as root node 62 | 63 | if (left < size && arr[left] < arr[smallest]) 64 | smallest = left; 65 | if (right < size && arr[right] < arr[smallest]) 66 | smallest = right; 67 | 68 | // largest in not root Node index(i.e. modified) 69 | if (smallest != nodeIndex) 70 | { 71 | // swapping Root Node with child having smallest(min) value & build Min Heap Sub-tree 72 | swapTwoNum(&arr[nodeIndex], &arr[smallest]); 73 | // recursively MinHeapify the new subtree formed after swap 74 | minHeapify(arr, size, smallest); 75 | } 76 | } 77 | 78 | /** 79 | * Name: buildMinHeap() 80 | * Purpose: Build Min heap out of an array visualized as Heap 81 | * @param: int arr[] 82 | * @param: int n, size of array 83 | * @return: void 84 | * @complexity : O(N) (min_heapify complexity: O(logN) and total n/2 steps so N constant) 85 | * If array is visualized as nearly Complete Binary Tree, all the elements after n/2 to n are leaves 86 | * In heaps, the leaves are automatically a Min Heap, since they don't have child 87 | * 88 | */ 89 | void buildMinHeap(int *arr, int n) 90 | { 91 | int i; 92 | for (i = (n / 2) - 1; i >= 0; i--) 93 | minHeapify(arr, n, i); 94 | } 95 | 96 | void heapSortMinHeap(int* arr, int size) { 97 | int i; 98 | // build min-heap 99 | buildMinHeap(arr, size); 100 | 101 | // heap sort using min-heap 102 | // exchange last node with root, min-heapify the changed heap 103 | // doing this for all nodes from last to first( sorting using bottom-to-top(leaves to root) way in heap) 104 | for( i=size-1; i>=0; i--) { 105 | // swap last node with root 106 | swapTwoNum(&arr[i], &arr[0]); 107 | // min-heapify the new heap after swap, reducing size by 1 each time(i is reduced each time) 108 | minHeapify(arr, i, 0); 109 | } 110 | } 111 | 112 | /** 113 | * Name: main() 114 | * Pupose: Starts execution of program 115 | * @return: int 116 | * ex. n = 6, arr[n]= {18, 17, 9, 2, 6, -10} 117 | * Min_Heap: {18, 17, 9, 2, 6, -10} 118 | */ 119 | int main() 120 | { 121 | unsigned int n; 122 | printf("Enter Size of Array\n"); 123 | scanf("%d", &n); 124 | int arr[n]; 125 | takeArrayInput(arr, n); 126 | heapSortMinHeap(arr, n); 127 | printf("Sorted Heap(using heap i.e. descending order): \n"); 128 | printArray(arr, n); 129 | 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /Trees/Heaps/MaxHeap.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * Name: swapTwoNum() 5 | * Purpose: Swaps two numbers 6 | * @param: int* a 7 | * @param: int* b 8 | * @return: void 9 | * @complexity: O(1) i.e constant time 10 | */ 11 | void swapTwoNum(int *a, int *b) 12 | { 13 | *a = (*a + *b) - (*b = *a); 14 | } 15 | 16 | /** 17 | * Name: takeArrayInput() 18 | * Purpose: takes input of given array 19 | * @param: int* arr, pointer to array 20 | * @param: unsigned int size, size of array 21 | * @return: void 22 | * @complexity: O(N) i.e. linear 23 | */ 24 | void takeArrayInput(int *arr, int size) 25 | { 26 | unsigned int i; 27 | printf("Enter %d elements of array\n", size); 28 | for (i = 0; i < size; i++) 29 | scanf("%d", &arr[i]); 30 | } 31 | 32 | /** 33 | * Name: takeArrayInput() 34 | * Purpose: takes input of given array 35 | * @param: int* arr, pointer to array 36 | * @param: unsigned int size, size of array 37 | * @return: void 38 | * @complexity: O(N) i.e. linear 39 | */ 40 | void printArray(int arr[], int size) 41 | { 42 | unsigned int i; 43 | for (i = 0; i < size; i++) 44 | printf("%d ", arr[i]); 45 | } 46 | 47 | /** 48 | * Name: maxHeapify() 49 | * Purpose: Max-heapify the given root of sub-tree as array 50 | * @param: int* arr, pointer to heap array 51 | * @param: unsigned int size, stores size of heap array 52 | * @param: unsigned int nodeIndex, contains index of root node of sub-tree needed to be max-heap 53 | * @return: void 54 | * @complexity: O(logN) i.e. logrithimic time 55 | */ 56 | void maxHeapify(int *arr, int size, int nodeIndex) 57 | { 58 | 59 | int left = (2 * nodeIndex) + 1; // left child Node index( since array is from 0 so +1) 60 | int right = (2 * nodeIndex) + 2; // right child Node index 61 | int largest = nodeIndex; // initialize as root node 62 | 63 | if (left < size && arr[left] > arr[largest]) 64 | largest = left; 65 | if (right < size && arr[right] > arr[largest]) 66 | largest = right; 67 | 68 | // largest in not root Node index(i.e. modified) 69 | if (largest != nodeIndex) 70 | { 71 | // swapping Root Node with child having largest value & build Max Heap Sub-tree 72 | swapTwoNum(&arr[nodeIndex], &arr[largest]); 73 | // recursively MaxHeapify the new subtree formed after swap 74 | maxHeapify(arr, size, largest); 75 | } 76 | } 77 | 78 | /** 79 | * Name: buildMaxHeap() 80 | * Purpose: Build Max heap out of an array visualized as Heap 81 | * @param: int arr[] 82 | * @param: int n, size of array 83 | * @return: void 84 | * @complexity : O(N) (max_heapify complexity: O(logN) and total n/2 steps so N linear) 85 | * If array is visualized as nearly Complete Binary Tree, all the elements after n/2 to n are leaves 86 | * In heaps, the leaves are automatically a Max Heap, since they don't have child 87 | * 88 | */ 89 | void buildMaxHeap(int *arr, int n) 90 | { 91 | int i; 92 | for (i = (n / 2) - 1; i >= 0; i--) 93 | maxHeapify(arr, n, i); 94 | } 95 | 96 | /** 97 | * Name: main() 98 | * Pupose: Starts execution of program 99 | * @return: int 100 | * ex. n = 10, arr[n]= {14, 16, 10, 9, 7, 8, 3, 2, 4, 1} 101 | * Max_Heap: {16, 14, 10, 9, 7, 8, 3, 2, 4, 1} 102 | */ 103 | int main() 104 | { 105 | unsigned int n; 106 | printf("Enter Size of Array\n"); 107 | scanf("%d", &n); 108 | int arr[n]; 109 | takeArrayInput(arr, n); 110 | buildMaxHeap(arr, n); 111 | printf("Max Heap: \n"); 112 | printArray(arr, n); 113 | 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /Trees/Heaps/MinHeap.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * Name: swapTwoNum() 5 | * Purpose: Swaps two numbers 6 | * @param: int* a 7 | * @param: int* b 8 | * @return: void 9 | * @complexity: O(1) i.e constant time 10 | */ 11 | void swapTwoNum(int *a, int *b) 12 | { 13 | *a = (*a + *b) - (*b = *a); 14 | } 15 | 16 | /** 17 | * Name: takeArrayInput() 18 | * Purpose: takes input of given array 19 | * @param: int* arr, pointer to array 20 | * @param: unsigned int size, size of array 21 | * @return: void 22 | * @complexity: O(N) i.e. linear 23 | */ 24 | void takeArrayInput(int *arr, int size) 25 | { 26 | unsigned int i; 27 | printf("Enter %d elements of array\n", size); 28 | for (i = 0; i < size; i++) 29 | scanf("%d", &arr[i]); 30 | } 31 | 32 | /** 33 | * Name: takeArrayInput() 34 | * Purpose: takes input of given array 35 | * @param: int* arr, pointer to array 36 | * @param: unsigned int size, size of array 37 | * @return: void 38 | * @complexity: O(N) i.e. linear 39 | */ 40 | void printArray(int arr[], int size) 41 | { 42 | unsigned int i; 43 | for (i = 0; i < size; i++) 44 | printf("%d ", arr[i]); 45 | } 46 | 47 | /** 48 | * Name: minHeapify() 49 | * Purpose: Min-heapify the given root of sub-tree as array 50 | * @param: int* arr, pointer to heap array 51 | * @param: unsigned int size, stores size of heap array 52 | * @param: unsigned int nodeIndex, contains index of root node of sub-tree needed to be mix-heap 53 | * @return: void 54 | * @complexity: O(logN) i.e. logrithimic time 55 | */ 56 | void minHeapify(int *arr, int size, int nodeIndex) 57 | { 58 | 59 | int left = (2 * nodeIndex) + 1; // left child Node index( since array is from 0 so +1) 60 | int right = (2 * nodeIndex) + 2; // right child Node index 61 | int smallest = nodeIndex; // initialize as root node 62 | 63 | if (left < size && arr[left] < arr[smallest]) 64 | smallest = left; 65 | if (right < size && arr[right] < arr[smallest]) 66 | smallest = right; 67 | 68 | // largest in not root Node index(i.e. modified) 69 | if (smallest != nodeIndex) 70 | { 71 | // swapping Root Node with child having smallest(min) value & build Min Heap Sub-tree 72 | swapTwoNum(&arr[nodeIndex], &arr[smallest]); 73 | // recursively MinHeapify the new subtree formed after swap 74 | minHeapify(arr, size, smallest); 75 | } 76 | } 77 | 78 | /** 79 | * Name: buildMinHeap() 80 | * Purpose: Build Min heap out of an array visualized as Heap 81 | * @param: int arr[] 82 | * @param: int n, size of array 83 | * @return: void 84 | * @complexity : O(N) (min_heapify complexity: O(logN) and total n/2 steps so N constant) 85 | * If array is visualized as nearly Complete Binary Tree, all the elements after n/2 to n are leaves 86 | * In heaps, the leaves are automatically a Min Heap, since they don't have child 87 | * 88 | */ 89 | void buildMinHeap(int *arr, int n) 90 | { 91 | int i; 92 | for (i = (n / 2) - 1; i >= 0; i--) 93 | minHeapify(arr, n, i); 94 | } 95 | 96 | /** 97 | * Name: main() 98 | * Pupose: Starts execution of program 99 | * @return: int 100 | * ex. n = 6, arr[n]= {18, 17, 9, 2, 6, -10} 101 | * Min_Heap: {18, 17, 9, 2, 6, -10} 102 | */ 103 | int main() 104 | { 105 | unsigned int n; 106 | printf("Enter Size of Array\n"); 107 | scanf("%d", &n); 108 | int arr[n]; 109 | takeArrayInput(arr, n); 110 | buildMinHeap(arr, n); 111 | printf("Min Heap: \n"); 112 | printArray(arr, n); 113 | 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /Trees/Heaps/PriorityQueues/PriorityQueueBinaryHeap.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * Heaps are mainly used in build efficient Priority Queues which are used in 5 | * Prims Minimum Spanning Trees, Dijikistra's and all scheduling algorithms in OS 6 | */ --------------------------------------------------------------------------------