├── heap ├── README.md ├── deleting-in-a-heap.md ├── inserting-in-a-heap.md └── heapify.md ├── queue ├── README.md ├── queue-using-linked-list.md ├── queue-using-array.md └── double-ended-queue.md ├── avl-tree ├── README.md ├── avl-tree-rotations.md ├── inserting-in-an-avl-tree.md └── deleting-in-an-avl-tree.md ├── binary-search-tree ├── README.md ├── searching-in-a-bst.md ├── deleting-in-a-bst.md └── inserting-in-a-bst.md ├── cirular-linked-list ├── README.md ├── displaying-the-nodes.md ├── inserting-a-node.md └── deleting-a-node.md ├── binary-tree ├── finding-sum-of-all-nodes.md ├── finding-the-height-of-tree.md ├── README.md ├── recursive-tree-traversals.md ├── level-order-traversal.md ├── creating-a-binary-tree-using-queue.md ├── iterative-tree-traversals.md └── counting-nodes-in-a-binary-tree.md ├── stack ├── README.md ├── stack-using-linked-list.md ├── balancing-parenthesis.md ├── stack-using-array.md ├── evaluation-of-postfix-expression.md └── infix-to-postfix.md ├── doubly-linked-list ├── README.md ├── reversing-a-doubly-linked-list.md ├── deleting-a-node.md ├── inserting-a-node.md └── circular-doubly-linked-list.md ├── strings ├── duplicates-in-a-string.md ├── README.md ├── finding-the-length-of-a-string.md ├── permutations-of-a-string.md ├── reversing-a-string.md ├── checking-for-palindrome.md ├── changing-cases-in-a-string.md ├── finding-number-of-vowels-consonants-and-words.md └── checking-if-strings-are-anagrams.md ├── linked-list ├── concatenating-two-lists.md ├── deleting-a-node.md ├── checking-if-list-is-sorted.md ├── detecting-a-loop-in-linked-list.md ├── README.md ├── removing-duplicates-from-a-list.md ├── counting-the-nodes.md ├── sum-of-all-nodes.md ├── finding-the-maximum-element.md ├── displaying-the-nodes.md ├── inserting-a-node-in-sorted-list.md ├── searching-in-a-node.md ├── merge-two-sorted-lists.md ├── finding-the-middle-node.md ├── reversing-a-linked-list.md └── inserting-a-node.md ├── arrays ├── README.md ├── finding-max-and-min-in-single-scan.md ├── reversing-an-array.md ├── getting-a-pair-whose-sum-k.md ├── merging-two-arrays.md ├── finding-missing-elements.md ├── some-more-basic-operations.md ├── binary-search.md ├── operations-in-a-sorted-array.md ├── duplicates-in-an-array.md ├── linear-search.md ├── array-adt.md └── set-operations.md ├── README.md └── SUMMARY.md /heap/README.md: -------------------------------------------------------------------------------- 1 | # Heap 2 | ![Heap Banner](https://i.imgur.com/3SXI2UR.gif) 3 | 4 | ## Table of Contents 5 | * [Inserting in a Heap](heap/inserting-in-a-heap.md) 6 | * [Deleting in a Heap](heap/deleting-in-a-heap.md) 7 | * [Heapify](heap/heapify.md) 8 | -------------------------------------------------------------------------------- /queue/README.md: -------------------------------------------------------------------------------- 1 | # Queue 2 | ![Queue Banner](https://i.imgur.com/UXrHuMB.gif) 3 | 4 | ## Table of Contents 5 | * [Queue using Array](queue/queue-using-array.md) 6 | * [Queue using Linked List](queue/queue-using-linked-list.md) 7 | * [Double Ended Queue](queue/double-ended-queue.md) 8 | -------------------------------------------------------------------------------- /avl-tree/README.md: -------------------------------------------------------------------------------- 1 | # AVL Trees 2 | ![AVL Banner](https://i.imgur.com/o0KHEku.gif) 3 | 4 | ## Table of Contents 5 | * [Inserting in an AVL Tree](avl-tree/inserting-in-an-avl-tree.md) 6 | * [AVL Tree Rotations](avl-tree/avl-tree-rotations.md) 7 | * [Deleting in an AVL Tree](avl-tree/deleting-in-an-avl-tree.md) 8 | -------------------------------------------------------------------------------- /binary-search-tree/README.md: -------------------------------------------------------------------------------- 1 | # Binary Search Trees 2 | ![BST Banner](https://i.imgur.com/JOKcWdD.gif) 3 | 4 | ## Table of Contents 5 | * [Searching in a BST](binary-search-tree/searching-in-a-bst.md) 6 | * [Inserting in a BST](binary-search-tree/inserting-in-a-bst.md) 7 | * [Deleting in a BST](binary-search-tree/deleting-in-a-bst.md) 8 | -------------------------------------------------------------------------------- /cirular-linked-list/README.md: -------------------------------------------------------------------------------- 1 | # Circular Linked Lists 2 | ![CLL Banner](https://i.imgur.com/FKuQo4A.gif) 3 | 4 | ## Table of Contents 5 | * [Displaying the Nodes](circular-linked-list/displaying-the-nodes.md) 6 | * [Inserting a Node](cicrular-linked-list/inserting-a-node.md) 7 | * [Deleting a Node](circular-linked-list/deleting-a-node.md) 8 | -------------------------------------------------------------------------------- /binary-tree/finding-sum-of-all-nodes.md: -------------------------------------------------------------------------------- 1 | # Finding Sum of All Nodes 2 | 3 | ```c 4 | int findSum(struct Node *ptr) { 5 | 6 | int x, y; 7 | 8 | if (ptr) { 9 | x = findHeight(ptr -> left); 10 | y = findHeight(ptr -> right); 11 | return x + y + ptr -> data; 12 | } 13 | return 0; 14 | 15 | } 16 | ``` 17 | 18 | Contributed by Nitin Ranganath 19 | 20 | -------------------------------------------------------------------------------- /stack/README.md: -------------------------------------------------------------------------------- 1 | # Stack 2 | ![Stack Banner](https://i.imgur.com/Dae8CFY.gif) 3 | 4 | ## Table of Contents 5 | * [Stack Using Array](stack/stack-using-array.md) 6 | * [Stack Using Linked List](stack/stack-using-linked-list.md) 7 | * [Balancing Parenthesis](stack/balancing-parenthesis.md) 8 | * [Infix to Postfix](stack/infix-to-postfix.md) 9 | * [Evaluation of Postfix Expression](stack/evaluation-of-postfix-expression.md) 10 | -------------------------------------------------------------------------------- /doubly-linked-list/README.md: -------------------------------------------------------------------------------- 1 | # Doubly Linked Lists 2 | ![DLL Banner](https://i.imgur.com/SDBPvCV.gif) 3 | 4 | ## Table of Contents 5 | * [Inserting a Node](doubly-linked-list/inserting-a-node.md) 6 | * [Deleting a Node](doubly-linked-list/deleting-a-node.md) 7 | * [Reversing a Doubly Linked List](doubly-linked-list/reversing-a-doubly-linked-list.md) 8 | * [Circular Doubly Linked List](doubly-linked-list/circular-doubly-linked-list.md) 9 | -------------------------------------------------------------------------------- /binary-tree/finding-the-height-of-tree.md: -------------------------------------------------------------------------------- 1 | # Finding the Height of Tree 2 | 3 | ```c 4 | int findHeight(struct Node *ptr) { 5 | 6 | int x, y; 7 | 8 | if (ptr) { 9 | x = findHeight(ptr -> left); 10 | y = findHeight(ptr -> right); 11 | if (x > y) { 12 | return x + 1; 13 | } 14 | return y + 1; 15 | } 16 | return 0; 17 | 18 | } 19 | ``` 20 | 21 | Contributed by Nitin Ranganath 22 | 23 | -------------------------------------------------------------------------------- /binary-tree/README.md: -------------------------------------------------------------------------------- 1 | # Binary Trees 2 | ![Binary Tree Banner](https://i.imgur.com/jX3FS0j.gif) 3 | 4 | ## Table of Contents 5 | * [Creating a Binary Tree using Queue](binary-tree/creating-a-binary-tree-using-queue.md) 6 | * [Recursive Tree Traversals](binary-tree/recursive-tree-traversals.md) 7 | * [Iterative Tree Traversals](binary-tree/iterative-tree-traversals.md) 8 | * [Level Order Traversal](binary-tree/level-order-traversal.md) 9 | * [Counting Nodes in a Binary Tree](binary-tree/counting-nodes-in-a-binary-tree.md) 10 | * [Finding the Height of Tree](binary-tree/finding-the-height-of-tree.md) 11 | * [Finding Sum of All Nodes](binary-tree/finding-sum-of-all-nodes.md) 12 | -------------------------------------------------------------------------------- /strings/duplicates-in-a-string.md: -------------------------------------------------------------------------------- 1 | # Duplicates in a String 2 | 3 | ```c 4 | void findDuplicates(char a[]) { 5 | 6 | // Considering all characters to be lowercase 7 | // Range : 97 to 122 => Consider 97 as 0 and 122 as 25 8 | 9 | // Hash array 10 | int h[26] = {0}; 11 | 12 | // Store count of each alphabet in hash array 13 | for (int i = 0; a[i] != '\0'; i++) { 14 | h[a[i] - 97]++; 15 | } 16 | 17 | // Displaying duplicates 18 | for (int i = 0; i < 26; i++) { 19 | if (h[i] > 1) { 20 | printf("Duplicate found : %c\n", i+97); 21 | } 22 | } 23 | 24 | } 25 | ``` 26 | 27 | Contributed by Nitin Ranganath 28 | 29 | -------------------------------------------------------------------------------- /linked-list/concatenating-two-lists.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to concatenate two linked lists. 3 | --- 4 | 5 | # Concatenating Two Lists 6 | 7 | ### Procedure : 8 | 9 | * Take the head pointer of both linked lists as parameters. 10 | * Traverse to the last node of first list. 11 | * Make the next point to the first of second list. 12 | 13 | ```c 14 | void concatenate(struct node *first, *second) ( 15 | 16 | // Traversing to the last node of first list 17 | while (first -> next != NULL) { 18 | first = first -> next; 19 | } 20 | // Setting the next as first node of second list 21 | first -> next = second; 22 | 23 | } 24 | ``` 25 | 26 | Contributed by Nitin Ranganath 27 | 28 | -------------------------------------------------------------------------------- /strings/README.md: -------------------------------------------------------------------------------- 1 | # Strings 2 | ![Strings Banner](https://i.imgur.com/yK8o9pH.gif) 3 | 4 | ## Table of Contents 5 | * [Finding the Length of a String](strings/finding-the-length-of-a-string.md) 6 | * [Changing Cases in a String](strings/changing-cases-in-a-string.md) 7 | * [Finding Number of Vowels, Consonants & Words](strings/finding-number-of-vowels-consonants-and-words.md) 8 | * [Reversing a String](strings/reversing-a-string.md) 9 | * [Checking for Palindrome](strings/checking-for-palindrome.md) 10 | * [Duplicates in a String](strings/duplicates-in-a-string.md) 11 | * [Checking if Strings are Anagrams](strings/checking-if-strings-are-anagrams.md) 12 | * [Permutations of a String](strings/permutations-of-a-string.md) 13 | -------------------------------------------------------------------------------- /strings/finding-the-length-of-a-string.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Implementation for finding the length of a string without library functions. 3 | --- 4 | 5 | # Finding the Length of a String 6 | 7 | ### Procedure : 8 | 9 | * Take character array / pointer as input 10 | * Iterate through the array until null terminator \(\0\) is not encountered. 11 | * Increment length in each iteration. 12 | * Return length 13 | 14 | ```c 15 | int findLength(char *a) { 16 | 17 | // Variable to track length 18 | int len = 0; 19 | 20 | // Iterate till null character is not found 21 | for (int i = 0; a[i] != '\0'; i++) { 22 | len++; 23 | } 24 | 25 | return len; 26 | 27 | } 28 | ``` 29 | 30 | Contributed by Nitin Ranganath 31 | 32 | -------------------------------------------------------------------------------- /doubly-linked-list/reversing-a-doubly-linked-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to reverse a doubly linear linked list. 3 | --- 4 | 5 | # Reversing a Doubly Linked List 6 | 7 | ```c 8 | void reverse(struct node *ptr) { 9 | 10 | // Temporary pointer for swapping 11 | struct node *temp; 12 | 13 | while (ptr != NULL) { 14 | // Swapping the links 15 | temp = ptr -> next; 16 | ptr -> next = ptr -> prev; 17 | ptr -> prev = temp; 18 | // Moving forward 19 | ptr = ptr -> prev; 20 | // Condition to set head node 21 | if (ptr != NULL && ptr -> next == NULL) { 22 | head = ptr; 23 | } 24 | } 25 | 26 | } 27 | ``` 28 | 29 | Contributed by Nitin Ranganath 30 | 31 | -------------------------------------------------------------------------------- /strings/permutations-of-a-string.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Finding all the permutations of a string using backtracking and recursion. 3 | --- 4 | 5 | # Permutations of a String 6 | 7 | ### Backtracking C Function : 8 | 9 | ```c 10 | void permutate(char a[], int l, int r) { 11 | 12 | if (l==r) { 13 | // Print the string when indexes match 14 | printf("%s\n", a); 15 | } else { 16 | for (int i = l; i <= r; i++) { 17 | // Swap to get permutation 18 | swap(&a[l], &a[i]); 19 | // Recursive call 20 | permutate(a, l+1, r); 21 | // Backtrack 22 | swap(&a[l], &a[i]); 23 | } 24 | } 25 | 26 | } 27 | 28 | ``` 29 | 30 | Contributed by Nitin Ranganath 31 | 32 | -------------------------------------------------------------------------------- /arrays/README.md: -------------------------------------------------------------------------------- 1 | # Arrays 2 | ![Array Banner](https://i.imgur.com/2nD18PQ.gif) 3 | 4 | # Table of Contents 5 | * [Array ADT](arrays/array-adt.md) 6 | * [Linear Search](arrays/linear-search.md) 7 | * [Binary Search](arrays/binary-search.md) 8 | * [Some More Basic Operations](arrays/some-more-basic-operations.md) 9 | * [Reversing an Array](arrays/reversing-an-array.md) 10 | * [Operations in a Sorted Array](arrays/operations-in-a-sorted-array.md) 11 | * [Merging Two Arrays](arrays/merging-two-arrays.md) 12 | * [Set Operations](arrays/set-operations.md) 13 | * [Finding Missing Elements](arrays/finding-missing-elements.md) 14 | * [Duplicates in an Array](arrays/duplicates-in-an-array.md) 15 | * [Getting a Pair whose Sum = K](arrays/getting-a-pair-whose-sum-k.md) 16 | * [Finding Max & Min in Single Scan](arrays/finding-max-and-min-in-single-scan.md) 17 | -------------------------------------------------------------------------------- /strings/reversing-a-string.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Implementation of reversing a string without using library function. 3 | --- 4 | 5 | # Reversing a String 6 | 7 | ### Procedure : 8 | 9 | * Calculate the length of string if it isn't given as input. 10 | * Initialise i with 0 and j with length - 1. 11 | * Run a for loop till i < j. 12 | * Swap the i-th and j-th character in each iteration. 13 | 14 | ### C Function : 15 | 16 | ```c 17 | void reverse(char a[], int n) { 18 | 19 | // Initialise i with 0 and j with length - 1 20 | int i = 0, j = n-1; 21 | char temp; 22 | 23 | // Swap characters in each iteration 24 | for (i = 0, j = n-1; i < j; i++, j--) { 25 | temp = a[i]; 26 | a[i] = a[j]; 27 | a[j] = temp; 28 | } 29 | 30 | } 31 | 32 | ``` 33 | 34 | Contributed by Nitin Ranganath 35 | 36 | -------------------------------------------------------------------------------- /strings/checking-for-palindrome.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: An efficient way of checking if a string is a palindrome. 3 | --- 4 | 5 | # Checking for Palindrome 6 | 7 | ### Procedure : 8 | 9 | * Calculate the length of string if it isn't given as input. 10 | * Initialise i with 0 and j with length - 1. 11 | * Run a for loop till i < j. 12 | * Compare the i-th and j-th character in each iteration. 13 | * If it's not the same, return 0 \(false\). 14 | * Else, return 1 \(true\) after the loop is completed. 15 | 16 | ### C Function : 17 | 18 | ```c 19 | int checkPalindrome(char a[], int n) { 20 | 21 | int i = 0, j = n-1; 22 | for (i = 0, j = n-1; i < j; i++, j--) { 23 | if (a[i] != a[j]) { 24 | return 0; 25 | } 26 | } 27 | return 1; 28 | 29 | } 30 | ``` 31 | 32 | Contributed by Nitin Ranganath 33 | 34 | -------------------------------------------------------------------------------- /cirular-linked-list/displaying-the-nodes.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to display all the nodes in a circular linked list. 3 | --- 4 | 5 | # Displaying the Nodes 6 | 7 | ### Iterative Method : 8 | 9 | ```c 10 | void display(struct node *ptr) { 11 | 12 | // Use a do while loop 13 | do { 14 | printf("%d\t", ptr -> data); 15 | ptr = ptr -> next; 16 | } 17 | while (ptr != head); 18 | 19 | } 20 | ``` 21 | 22 | ### Recursive Method : 23 | 24 | ```c 25 | void display(struct node *ptr) { 26 | 27 | // A flag variable to check if head is reached second time 28 | static int flag = 0; 29 | 30 | if (ptr != head || flag = 0) { 31 | printf("%d\t", ptr -> data); 32 | display(ptr -> head); 33 | } 34 | // Make flag 0 again as it is static 35 | flag = 0; 36 | 37 | } 38 | ``` 39 | 40 | Contributed by Nitin Ranganath 41 | 42 | -------------------------------------------------------------------------------- /doubly-linked-list/deleting-a-node.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to delete a node at a given index in a doubly linear linked list. 3 | --- 4 | 5 | # Deleting a Node 6 | 7 | ```c 8 | void delete(struct node *ptr, int pos) { 9 | 10 | // If first node is to be deleted 11 | if (pos == 1) { 12 | head = head -> next; 13 | if (head) { 14 | head -> prev = NULL; 15 | } 16 | free(ptr); 17 | } 18 | 19 | // Deleting any other node 20 | else { 21 | // Reach the node to be deleted 22 | for (int i = 0; i < pos - 1; i++) { 23 | ptr = ptr -> next; 24 | } 25 | // Modify the links 26 | ptr -> prev -> next = ptr -> next; 27 | if (ptr -> next) { 28 | ptr -> next -> prev = ptr -> prev; 29 | } 30 | // Deallocate the memory 31 | free(ptr); 32 | } 33 | 34 | } 35 | ``` 36 | 37 | Contributed by Nitin Ranganath 38 | 39 | -------------------------------------------------------------------------------- /linked-list/deleting-a-node.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to delete a node from any position in a linked list. 3 | --- 4 | 5 | # Deleting a Node 6 | 7 | ### Deleting the Head Node : 8 | 9 | ```c 10 | void deleteFirst(struct node *ptr) { 11 | 12 | first = ptr -> next; 13 | free(ptr); 14 | 15 | } 16 | ``` 17 | 18 | ### Deleting a Node from Any Index : 19 | 20 | ```c 21 | void delete(struct node *ptr, int index) { 22 | 23 | // If node to be deleted is the head node 24 | if (index == 1) { 25 | head = ptr -> next; 26 | free(ptr); 27 | } 28 | 29 | // Deleting other nodes 30 | else { 31 | for (int i = 0; i < index - 2; i++) { 32 | ptr = ptr -> next; 33 | } 34 | // Find the node to be deleted 35 | struct node *toDelete = ptr -> next; 36 | // Replace the link 37 | ptr -> next = toDelete -> next; 38 | // Deallocate the memory 39 | free(toDelete); 40 | } 41 | 42 | } 43 | ``` 44 | 45 | Contributed by Nitin Ranganath 46 | 47 | -------------------------------------------------------------------------------- /binary-tree/recursive-tree-traversals.md: -------------------------------------------------------------------------------- 1 | # Recursive Tree Traversals 2 | 3 | ### Preorder Traversal : 4 | 5 | ```c 6 | void preorderTraversal(struct Node *ptr) { 7 | 8 | if (ptr != NULL) { 9 | printf("%d\t", ptr -> data); 10 | preorderTraversal(ptr -> left); 11 | preorderTraversal(ptr -> right); 12 | } 13 | 14 | } 15 | ``` 16 | 17 | ### Inorder Traversal : 18 | 19 | ```c 20 | void inorderTraversal(struct Node *ptr) { 21 | 22 | if (ptr != NULL) { 23 | inorderTraversal(ptr -> left); 24 | printf("%d\t", ptr -> data); 25 | inorderTraversal(ptr -> right); 26 | } 27 | 28 | } 29 | ``` 30 | 31 | ### Postorder Traversal : 32 | 33 | ```c 34 | void postorderTraversal(struct Node *ptr) { 35 | 36 | if (ptr != NULL) { 37 | postorderTraversal(ptr -> left); 38 | postorderTraversal(ptr -> right); 39 | printf("%d\t", ptr -> data); 40 | } 41 | 42 | } 43 | ``` 44 | 45 | **The time complexity of all 3 traversal methods in O\(n\).** 46 | 47 | Contributed by Nitin Ranganath 48 | 49 | -------------------------------------------------------------------------------- /linked-list/checking-if-list-is-sorted.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to check if a linked list is sorted or not. 3 | --- 4 | 5 | # Checking if List is Sorted 6 | 7 | ### Procedure : 8 | 9 | * Check if only one node is present. If so, return true. 10 | * Else, traverse through the list and check if the data of current node is greater than the data in the next node. If so, return false. 11 | * Return true if while loop is completely executed without returning false. 12 | 13 | ```c 14 | int isSorted(struct node *ptr) { 15 | 16 | // If only one node is present, it is sorted 17 | if (ptr -> next == NULL) { 18 | return 1; 19 | } 20 | 21 | else { 22 | // Check until last node is reached 23 | while (ptr -> next != NULL) { 24 | // If data of previous node is greater 25 | if (ptr -> data > ptr -> next -> data) { 26 | return 0; 27 | } 28 | ptr = ptr -> next; 29 | } 30 | return 1; 31 | } 32 | 33 | } 34 | ``` 35 | 36 | Contributed by Nitin Ranganath 37 | 38 | -------------------------------------------------------------------------------- /binary-tree/level-order-traversal.md: -------------------------------------------------------------------------------- 1 | # Level Order Traversal 2 | 3 | **The below function requires a queue data structure of type pointer to Node to be created and initialised.** 4 | 5 | ```c 6 | void levelOrder(struct Node *ptr) { 7 | 8 | // Queue structure to store pointer 9 | struct Queue q; 10 | 11 | // Print the root node as it is on the topmost level 12 | printf("%d\t", ptr -> data); 13 | // Enqueue root node to the queue 14 | enqueue(&q, ptr); 15 | 16 | while (!isEmpty(q)) { 17 | // Obtain root of subtree 18 | ptr = dequeue(&q); 19 | // Print & enqueue the left child of next level if present 20 | if (ptr -> left) { 21 | printf("%d\t", ptr -> left -> data); 22 | enqueue(&q, ptr -> left); 23 | } 24 | // Print & enqueue the left child of next level if present 25 | if (ptr -> right) { 26 | printf("%d\t", ptr -> right -> data); 27 | enqueue(&q, ptr -> right); 28 | } 29 | } 30 | 31 | } 32 | ``` 33 | 34 | Contributed by Nitin Ranganath 35 | 36 | -------------------------------------------------------------------------------- /strings/changing-cases-in-a-string.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: ASCII values and it's importance in changing cases in a string. 3 | --- 4 | 5 | # Changing Cases in a String 6 | 7 | ### Common ASCII Codes: 8 | 9 | * A = 65 10 | * Z = 90 11 | * a = 97 12 | * z = 122 13 | 14 | ### The Logic: 15 | 16 | To covert from **uppercase to lowercase**, add 32 to the uppercase character. 17 | 18 | To convert from **lowercase to uppercase**, subtract 32 from the lowercase character. 19 | 20 | ### C Function: 21 | 22 | ```c 23 | void toUpper(char A[]) { 24 | 25 | for (int i = 0; A[i] != '\0'; i++) { 26 | A[i] = A[i] - 32; 27 | } 28 | 29 | } 30 | 31 | void toLower(char A[]) { 32 | 33 | for (int i = 0; A[i] != '\0'; i++) { 34 | A[i] = A[i] + 32; 35 | } 36 | 37 | } 38 | 39 | void toggleCase(char A[]) { 40 | 41 | for (int i = 0; A[i] != '\0'; i++) { 42 | if (A[i] >= 'A' && A[i] <= 'Z') { 43 | A[i] = A[i] + 32; 44 | } else if (A[i] >= 'a' && A[i] <= 'z') { 45 | A[i] = A[i] - 32; 46 | } 47 | } 48 | 49 | } 50 | ``` 51 | 52 | Contributed by Nitin Ranganath 53 | 54 | -------------------------------------------------------------------------------- /linked-list/detecting-a-loop-in-linked-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Procedure to check if a given list has a loop using Floyd's Cycle Finding 4 | Algorithm. 5 | --- 6 | 7 | # Detecting a Loop in Linked List 8 | 9 | ### Procedure : 10 | 11 | * Take two pointers : slow and fast 12 | * Move the slow pointer by 1 node each time and fast pointer by 2 nodes each time. 13 | * Perform the above step until either of the pointer become NULL or the next of fast becomes NULL. 14 | * Check if both the pointers are same. If so, the linked list has a loop. Else, it doesn't. 15 | 16 | ```c 17 | int isLoop(struct node *ptr) { 18 | 19 | // Two pointers to check for loop 20 | struct node *slow = ptr; 21 | struct node *fast = ptr; 22 | 23 | while (slow && fast && fast -> next) { 24 | // Move slow by one step 25 | slow = slow -> next; 26 | // Move fast by two steps 27 | fast = fast -> next -> next; 28 | // Check if the pointers are same 29 | if (slow == fast) { 30 | return 1; 31 | } 32 | } 33 | return 0; 34 | 35 | } 36 | ``` 37 | 38 | Contributed by Nitin Ranganath 39 | 40 | -------------------------------------------------------------------------------- /linked-list/README.md: -------------------------------------------------------------------------------- 1 | # Linked Lists 2 | ![LL Banner](https://i.imgur.com/Dt08nJH.gif) 3 | 4 | ## Table of Contents 5 | * [Displaying the Nodes](linked-list/displaying-the-nodes.md) 6 | * [Counting the Nodes](linked-list/counting-the-nodes.md) 7 | * [Sum of all Nodes](linked-list/sum-of-all-nodes.md) 8 | * [Finding the Maximum Element](linked-list/finding-the-maximum-element.md) 9 | * [Searching in a Node](linked-list/searching-in-a-node.md) 10 | * [Inserting a Node](linked-list/inserting-a-node.md) 11 | * [Inserting a Node in Sorted List](linked-list/inserting-a-node-in-sorted-list.md) 12 | * [Deleting a Node](linked-list/deleting-a-node.md) 13 | * [Checking if List is Sorted](linked-list/checking-if-list-is-sorted.md) 14 | * [Removing Duplicates from a List](linked-list/removing-duplicates-from-a-list.md) 15 | * [Reversing a Linked List](linked-list/reversing-a-linked-list.md) 16 | * [Concatenating Two Lists](linked-list/concatenating-two-lists.md) 17 | * [Detecting a Loop in Linked List](linked-list/detecting-a-loop-in-linked-list.md) 18 | * [Merge Two Sorted Lists](linked-list/merge-two-sorted-lists.md) 19 | * [Finding the Middle Node](linked-list/finding-the-middle-node.md) 20 | -------------------------------------------------------------------------------- /linked-list/removing-duplicates-from-a-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to remove duplicate nodes from a linked list. 3 | --- 4 | 5 | # Removing Duplicates from a List 6 | 7 | ### Procedure : 8 | 9 | * Traverse the list until the next node is not NULL. 10 | * If the data of current node and next node is the same, change the next of current node to next of next node and delete the next node. 11 | * Else, move the current node to next of current node. 12 | 13 | ```c 14 | void removeDuplicates(struct node *ptr) { 15 | 16 | while (ptr -> next != NULL) { 17 | 18 | // If data of the two nodes are same 19 | if (ptr -> data == ptr -> next -> data) { 20 | // Pointer for the node to be deleted 21 | struct node *toDelete = ptr -> next; 22 | // Replace the links 23 | ptr -> next = toDelete -> next; 24 | // Deallocate the memory 25 | free(toDelete); 26 | } 27 | 28 | // IMPORTANT : Advance only if no deletion 29 | else { 30 | ptr = ptr -> next; 31 | } 32 | 33 | } 34 | 35 | } 36 | ``` 37 | 38 | Contributed by Nitin Ranganath 39 | 40 | -------------------------------------------------------------------------------- /linked-list/counting-the-nodes.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Iterative and recursive way of counting the number of nodes in a linked list. 3 | --- 4 | 5 | # Counting the Nodes 6 | 7 | ### Iterative Method : 8 | 9 | ```c 10 | int count(struct node *ptr) { 11 | 12 | // A variable to keep track of count 13 | int count = 0; 14 | 15 | // Iterate till ptr becomes NULL 16 | while (ptr != NULL) { 17 | count++; 18 | ptr = ptr -> next; 19 | } 20 | return count; 21 | 22 | } 23 | ``` 24 | 25 | ### Recursive Method : 26 | 27 | ```c 28 | int count(struct node *ptr) { 29 | 30 | // Base condition for termination 31 | if (ptr == NULL) { 32 | return 0; 33 | } 34 | // Recursive call 35 | else { 36 | return count(ptr -> next) + 1; 37 | } 38 | 39 | } 40 | ``` 41 | 42 | ### Time and Space Complexity : 43 | 44 | {% tabs %} 45 | {% tab title="Iterative" %} 46 | Time complexity : **O\(n\)** 47 | Space complexity : **O\(1\)** 48 | {% endtab %} 49 | 50 | {% tab title="Recursive" %} 51 | Time complexity : **O\(n\)** 52 | Space complexity : **O\(n\)** 53 | {% endtab %} 54 | {% endtabs %} 55 | 56 | Contributed by Nitin Ranganath 57 | 58 | -------------------------------------------------------------------------------- /arrays/finding-max-and-min-in-single-scan.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Implementation for finding the maximum and minimum element in an array in a 4 | single scan itself. 5 | --- 6 | 7 | # Finding Max & Min in Single Scan 8 | 9 | ### Procedure : 10 | 11 | * Take array and array size \(n\) as input 12 | * Assign max and min variable to first element initially. 13 | * Iterate from index = 1 to n 14 | * If the element at index 1 is less than min, change min value. 15 | * If not, check if it greater than max. If so, change max value. 16 | 17 | ```c 18 | void findMinMax(int a[], int n) { 19 | 20 | // Assign min and max to first element 21 | int min = a[0]; 22 | int max = a[0]; 23 | 24 | for (int i = 1; i < n; i++) { 25 | // If current element is less than min, update min. 26 | if (a[i] < min) { 27 | min = a[i]; 28 | } 29 | // If current element is greater than max, update max. 30 | else if (a[i] > max) { 31 | max = a[i]; 32 | } 33 | 34 | } 35 | 36 | printf("The maximum element is %d\n", max); 37 | printf("The minimum element is %d\n", min); 38 | 39 | } 40 | ``` 41 | 42 | Contributed by Nitin Ranganath 43 | 44 | -------------------------------------------------------------------------------- /linked-list/sum-of-all-nodes.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Iterative and recursive way of finding the sum of data of all the nodes in a 4 | linked list. 5 | --- 6 | 7 | # Sum of all Nodes 8 | 9 | ### Iterative Method : 10 | 11 | ```c 12 | int sum(struct node *ptr) { 13 | 14 | // A variable to keep track of sum 15 | int sum = 0; 16 | 17 | // Iterate till ptr becomes NULL 18 | while (ptr != NULL) { 19 | sum += ptr -> data; 20 | ptr = ptr -> next; 21 | } 22 | return sum; 23 | 24 | } 25 | ``` 26 | 27 | ### Recursive Method : 28 | 29 | ```c 30 | int sum(struct node *ptr) { 31 | 32 | // Base condition for termination 33 | if (p == NULL) { 34 | return 0; 35 | } 36 | 37 | // Recursive call 38 | else { 39 | return sum(ptr -> next) + p -> data; 40 | } 41 | 42 | } 43 | ``` 44 | 45 | ### Time and Space Complexity : 46 | 47 | {% tabs %} 48 | {% tab title="Iterative" %} 49 | Time complexity : **O\(n\)** 50 | Space complexity : **O\(n\)** 51 | {% endtab %} 52 | 53 | {% tab title="Recursive" %} 54 | Time complexity : **O\(n\)** 55 | Space complexity : **O\(1\)** 56 | {% endtab %} 57 | {% endtabs %} 58 | 59 | Contributed by Nitin Ranganath 60 | 61 | -------------------------------------------------------------------------------- /strings/finding-number-of-vowels-consonants-and-words.md: -------------------------------------------------------------------------------- 1 | # Finding Number of Vowels, Consonants & Words 2 | 3 | * Initialise vowel and consonant count with 0. 4 | * Initialise word count with 1 as there will be a minimum of 1 word in each string. 5 | * Use a for loop to check all characters. 6 | * If it is an uppercase or lowercase vowels, increment vowel count. 7 | * If not, check if the character lies in the uppercase and lowercase alphabet range. If so, increment consonant count. 8 | * If not, check if the character is a space. If so, increment word count. 9 | 10 | ```c 11 | void countAll(char a[]) { 12 | 13 | int vowels=0, consonants=0, words=1; 14 | 15 | for (int i = 0; a[i] != '\0'; i++) { 16 | if (a[i] == 'a' || a[i] == 'e' || a[i] == 'i' || a[i] == 'o' || a[i] == 'u' || a[i] == 'A' || a[i] == 'E' || a[i] == 'I' || a[i] == 'O' || a[i] == 'U') { 17 | vowels++; 18 | } else if ((a[i] >= 'A' && a[i] <= 'Z') || (a[i] >= 'a' && a[i] <= 'z')) { 19 | consonants++; 20 | } else if (a[i] == ' ') { 21 | words++; 22 | } 23 | } 24 | 25 | printf("Vowels: %i\tConsontants: %i\tWords: %i\n", vowels, consonants, words); 26 | 27 | } 28 | ``` 29 | 30 | Contributed by Nitin Ranganath 31 | 32 | -------------------------------------------------------------------------------- /doubly-linked-list/inserting-a-node.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to insert in node in doubly linear linked list. 3 | --- 4 | 5 | # Inserting a Node 6 | 7 | ```c 8 | void insert(struct node *ptr, int data, int pos) { 9 | 10 | // Creating a new node 11 | struct node *newNode; 12 | newNode = (struct node *)malloc(sizeof(struct node)); 13 | newNode -> data = data; 14 | 15 | // If node is to be inserted at first position 16 | if (pos == 1) { 17 | if (head == NULL) { 18 | newNode -> prev = NULL; 19 | newNode -> next = NULL; 20 | head = newNode; 21 | } else { 22 | newNode -> prev = NULL; 23 | newNode -> next = head; 24 | head = newNode; 25 | } 26 | } 27 | 28 | // If node is to be inserted in any other position 29 | else { 30 | for (int i = 0; i < pos - 2; i++) { 31 | ptr = ptr -> next; 32 | } 33 | newNode -> next = ptr -> next; 34 | newNode -> prev = ptr; 35 | // Check if next node is available 36 | if (ptr -> next) { 37 | ptr -> next -> prev = newNode; 38 | } 39 | ptr -> next = newNode; 40 | } 41 | 42 | 43 | ``` 44 | 45 | Contributed by Nitin Ranganath 46 | 47 | -------------------------------------------------------------------------------- /cirular-linked-list/inserting-a-node.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to insert a node at a given index in a circular linked list. 3 | --- 4 | 5 | # Inserting a Node 6 | 7 | ```c 8 | void insert(struct node *ptr, int data, int postition) { 9 | 10 | // Creating a new node and assigning data 11 | struct node *newNode; 12 | newNode = (struct node *)malloc(sizeof(struct node)); 13 | newNode -> data = data; 14 | 15 | // If node is to be inserted before head 16 | if (position == 1) { 17 | // Checking if list is empty 18 | if (head == NULL) { 19 | head = newNode; 20 | head -> next = head; 21 | } 22 | // If a node already exists 23 | else { 24 | // Traverse to end of list 25 | while (ptr -> next != head) { 26 | ptr = ptr -> next; 27 | } 28 | ptr -> next = newNode; 29 | newNode -> next = head; 30 | } 31 | } 32 | 33 | // If node is to be inserted in any other index 34 | else { 35 | for (int i = 0; i < postition - 2; i++) { 36 | ptr = ptr -> next; 37 | } 38 | newNode -> next = ptr -> next; 39 | ptr -> next = newNode; 40 | } 41 | 42 | } 43 | ``` 44 | 45 | Contributed by Nitin Ranganath 46 | 47 | -------------------------------------------------------------------------------- /linked-list/finding-the-maximum-element.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Iterative and recursive way of finding the maximum among all the node's data. 3 | --- 4 | 5 | # Finding the Maximum Element 6 | 7 | ### Iterative Method : 8 | 9 | ```c 10 | int maximum(struct node *ptr) { 11 | 12 | // Variable to keep track of maximum element 13 | // Initialise with INT_MIN 14 | int max = INT_MIN; 15 | 16 | while (ptr != NULL) { 17 | // Change max value is current data is greater 18 | if (ptr -> data > max) { 19 | max = ptr -> data; 20 | } 21 | ptr = ptr -> next; 22 | } 23 | return max; 24 | 25 | } 26 | ``` 27 | 28 | ### Recursive Method : 29 | 30 | ```c 31 | int maximum(struct node *ptr) { 32 | 33 | int max; 34 | 35 | if (ptr == NULL) { 36 | return INT_MIN; 37 | } 38 | max = maximum(p -> next); 39 | return max > p -> data ? max : p -> data; 40 | 41 | } 42 | ``` 43 | 44 | ### Time and Space Complexity : 45 | 46 | {% tabs %} 47 | {% tab title="Iterative" %} 48 | Time complexity : **O\(n\)** 49 | Space complexity : **O\(n\)** 50 | {% endtab %} 51 | 52 | {% tab title="Recursive" %} 53 | Time complexity : **O\(n\)** 54 | Space complexity : **O\(1\)** 55 | {% endtab %} 56 | {% endtabs %} 57 | 58 | Contributed by Nitin Ranganath 59 | 60 | -------------------------------------------------------------------------------- /cirular-linked-list/deleting-a-node.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to remove a node from a given position in a circular linked list. 3 | --- 4 | 5 | # Deleting a Node 6 | 7 | ```c 8 | void delete(struct node *ptr, int position) { 9 | 10 | // If the current head node is to be deleted 11 | if (position == 1) { 12 | while (ptr -> next != head) { 13 | ptr = ptr -> next; 14 | } 15 | if (ptr == head) { 16 | free(head); 17 | head = NULL; 18 | } else { 19 | // Change the link 20 | ptr -> next = head -> next; 21 | // Deallocate the memory 22 | free(head); 23 | // Change head 24 | head = ptr -> next; 25 | } 26 | } 27 | 28 | // If node from any other position is to be deleted 29 | else { 30 | // Traverse to the required node 31 | for (int i = 0; i < position - 2; i++) { 32 | ptr = ptr -> next; 33 | } 34 | // Pointer for the node to be deleted 35 | struct node *toDelete; 36 | toDelete = ptr -> next; 37 | // Change the link 38 | ptr -> next = toDelete -> next; 39 | // Deallocate the memory 40 | free(toDelete); 41 | } 42 | 43 | } 44 | ``` 45 | 46 | Contributed by Nitin Ranganath 47 | 48 | -------------------------------------------------------------------------------- /strings/checking-if-strings-are-anagrams.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Strings which are composed of the same alphabets and their frequency are known 4 | as anagrams of each other. 5 | --- 6 | 7 | # Checking if Strings are Anagrams 8 | 9 | ### Procedure : 10 | 11 | * Take the two strings as input 12 | * Create an hash array of size 26 and initialise it with 0. 13 | * For each character the first string, **increment** the corresponding index in the hash array. 14 | * For each character in the second string, **decrement** the corresponding index in the hash array. 15 | * Loop through the hash array. If any of the element is not 0, return false. Else, return true. 16 | 17 | ### C Function : 18 | 19 | ```c 20 | int checkAnagram(char a[], char b[]) { 21 | 22 | // Create and initialise hash array with 0. 23 | int h[26] = {0}; 24 | 25 | // Increment for first string 26 | for (int i = 0; a[i] != '\0'; i++) { 27 | h[a[i]-97]++; 28 | } 29 | 30 | // Decrement for second string 31 | for (int i = 0; b[i] != '\0'; i++) { 32 | h[b[i]-97]--; 33 | } 34 | 35 | // If any element is not zero, it is not an anagram. 36 | for (int i = 0; i < 26; i++) { 37 | if (h[i] != 0) { 38 | return 0; 39 | } 40 | } 41 | return 1; 42 | 43 | } 44 | ``` 45 | 46 | Contributed by Nitin Ranganath 47 | 48 | -------------------------------------------------------------------------------- /heap/deleting-in-a-heap.md: -------------------------------------------------------------------------------- 1 | # Deleting in a Heap 2 | 3 | ### Procedure : 4 | 5 | * Copy the last element to root i.e index 1. 6 | * Shift the root element to last element of heap. 7 | * Set i as 1 \(root\) and j as 2\*i \(left child of root\). 8 | * Perform the following until j < size - 1. 9 | * Find which of the child is greater. 10 | * Set j to point on that child. 11 | * If the child element \(j\) is greater than parent element \(i\), swap them. 12 | * Set i as j and j as 2\*j after each iteration. 13 | 14 | ```c 15 | int deleteFromHeap(int h[], int size) { 16 | 17 | // Copy last element to root and first element to last place 18 | int lastElement = h[size]; 19 | int firstElement = h[1]; 20 | h[1] = lastElement; 21 | h[size] = firstElement; 22 | 23 | // Keep i at root and j at left child of root initially 24 | int i = 1, j = 2*i; 25 | 26 | while(j < size-1) { 27 | 28 | // Find out if left child is greater or right child 29 | if (h[j+1] > h[j]) 30 | j = j + 1; 31 | 32 | // If child is greater than parent, interchange 33 | if (h[j] > h[i]) { 34 | int temp = h[i]; 35 | h[i] = h[j]; 36 | h[j] = temp; 37 | // Set i to j and j to left child of j 38 | i = j; 39 | j = 2*j; 40 | } else { 41 | break; 42 | } 43 | } 44 | return firstElement; 45 | 46 | } 47 | ``` 48 | 49 | **By calling the same function n times, heap sort can be implemented.** 50 | 51 | -------------------------------------------------------------------------------- /linked-list/displaying-the-nodes.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Iterative and recursive method to print all the nodes in a linked list. 3 | --- 4 | 5 | # Displaying the Nodes 6 | 7 | ### Iterative Method : 8 | 9 | ```c 10 | void display(struct node *ptr) { 11 | 12 | // Checking if list is empty 13 | if (ptr == NULL) { 14 | printf("The list is empty\n"); 15 | } 16 | // Iterate till the end otherwise 17 | else { 18 | while (ptr != NULL) { 19 | printf("%d\t", ptr -> data); 20 | ptr = ptr -> next; 21 | } 22 | } 23 | 24 | } 25 | ``` 26 | 27 | ### Recursive Method : 28 | 29 | ```c 30 | void display(struct node *ptr) { 31 | 32 | if (ptr != NULL) { 33 | printf("%d\t", ptr -> data); 34 | display(ptr -> next); 35 | } 36 | 37 | } 38 | ``` 39 | 40 | ### Recursive & Reversed : 41 | 42 | ```c 43 | void display(struct node *ptr) { 44 | 45 | if (ptr != NULL) { 46 | display(ptr -> next); 47 | printf("%d\t", ptr -> data); 48 | } 49 | 50 | } 51 | ``` 52 | 53 | ### Time and Space Complexity : 54 | 55 | {% tabs %} 56 | {% tab title="Iterative" %} 57 | Time Complexity : **O\(n\) 58 | No extra space** 59 | {% endtab %} 60 | 61 | {% tab title="Recursive" %} 62 | Time complexity : **O\(n\) 63 | Internal stack of size n+1 is used.** 64 | {% endtab %} 65 | {% endtabs %} 66 | 67 | Contributed by Nitin Ranganath 68 | 69 | -------------------------------------------------------------------------------- /arrays/reversing-an-array.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Implementation of 2 of the methods which can be used to reverse an array. 3 | --- 4 | 5 | # Reversing an Array 6 | 7 | ### Reversing Techniques : 8 | 9 | * Reversing using Auxiliary Array 10 | * Reversing by Swapping Elements 11 | 12 | ### Reversing Using Auxiliary Array : 13 | 14 | In this method, we create a new array which stores the values of the input array in reverse order and then overwrites the input array with newly created array. 15 | 16 | ```c 17 | void reverseByCopy(int a[], int n) { 18 | 19 | int i, j, b[n]; // New array to store in reverse order 20 | 21 | // Storing elements in 'b' array in reverse order 22 | for (i = n-1, j = 0; i >= 0; i--, j++) { 23 | b[j] = a[i]; 24 | } 25 | 26 | // Overwriting 'a' array 27 | for(int i = 0; i < n; i++) { 28 | a[i] = b[i]; 29 | } 30 | 31 | } 32 | ``` 33 | 34 | ### Reversing by Swapping Elements : 35 | 36 | In this method, we keep swapping the left side and right side elements of the array until all the elements are swapped. 37 | 38 | ```c 39 | void reverseBySwap(int a[], int n) { 40 | 41 | int i, j; 42 | 43 | // i is set to left end, j is set to right end 44 | for (i = 0, j = n-1; i < j; i++, j--) { 45 | int temp = a[i]; 46 | a[i] = a[j]; 47 | a[j] = temp; 48 | } 49 | 50 | } 51 | ``` 52 | 53 | Contributed by Nitin Ranganath 54 | 55 | -------------------------------------------------------------------------------- /heap/inserting-in-a-heap.md: -------------------------------------------------------------------------------- 1 | # Inserting in a Heap 2 | 3 | ### Some basics : 4 | 5 | * Heap is stored in an array representation. 6 | * Starting index is considered to be 1. Element at index 0 will be 0. 7 | * For an element in **index i**, its left child will be at index **2i** and right child will be at **index 2i + 1**. 8 | * For elements at index > 2, its parent element will be at the floor value of **index /2**. 9 | 10 | ### Inserting in a Max Heap : 11 | 12 | ```c 13 | void insertMaxHeap(int h[], int data, int index) { 14 | 15 | // Check if data is greater than parent 16 | while (index > 1 && data > h[index/2]) { 17 | h[index] = h[index/2]; 18 | index = index/2; 19 | } 20 | h[index] = data; 21 | 22 | } 23 | ``` 24 | 25 | ### Inserting in a Min Heap : 26 | 27 | ```c 28 | void insertMinHeap(int h[], int data, int index) { 29 | 30 | // Check if data is lesser than parent 31 | while (index > 1 && data < h[index/2]) { 32 | h[index] = h[index/2]; 33 | index = index/2; 34 | } 35 | h[index] = data; 36 | 37 | } 38 | ``` 39 | 40 | ### Creating a Heap from Existing Array : 41 | 42 | ```c 43 | void createHeap(int h[], int size) { 44 | 45 | for (int i = 2; i <= size; i++) { 46 | insertMaxHeap(h, h[i], i); 47 | } 48 | 49 | } 50 | 51 | // int h[5] = {0, 34, 12, 56, 4}; 52 | // Heap size is 4. Don't include first index. 53 | // createHeap(h, 4); 54 | ``` 55 | 56 | -------------------------------------------------------------------------------- /arrays/getting-a-pair-whose-sum-k.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Obtaining a pair of elements in the array whose sum = k. 3 | --- 4 | 5 | # Getting a Pair whose Sum = K 6 | 7 | ### For Sorted Arrays: 8 | 9 | ```c 10 | void findPair(int a[], int n, int key) { 11 | 12 | // Set i to starting index and j to last index 13 | int i = 0, j = n-1; 14 | 15 | while (i < j) { 16 | // If pair is found, increment i and decrement j 17 | if (a[i] + a[j] == key) { 18 | printf("Pair : %d and %d\n", a[i], a[j]); 19 | i++; 20 | j--; 21 | } 22 | // If sum is greater than key, decrement j 23 | else if (a[i] + a[j] > key) { 24 | j--; 25 | } 26 | // If sum is smaller than key, increment i 27 | else { 28 | i++; 29 | } 30 | 31 | } 32 | 33 | } 34 | ``` 35 | 36 | ### For Unsorted Arrays: 37 | 38 | ```c 39 | void findPair(int a[], int n, int max, int key) { 40 | 41 | // Create and initialize hash array with 0 42 | int h[max]; 43 | for (int i = 0; i < max; i++) { 44 | h[i] = 0; 45 | } 46 | 47 | for (int i = 0; i < n; i++) { 48 | // Check if the suitable pair is present 49 | if (h[key - a[i]] != 0) { 50 | printf("Pair : %d and %d\n", a[i], key-a[i]); 51 | } 52 | h[a[i]]++; 53 | } 54 | 55 | } 56 | ``` 57 | 58 | Contributed by Nitin Ranganath 59 | 60 | -------------------------------------------------------------------------------- /binary-search-tree/searching-in-a-bst.md: -------------------------------------------------------------------------------- 1 | # Searching in a BST 2 | 3 | ### Procedure : 4 | 5 | * Start from the root node. 6 | * Compare the data in each node with the key. If it matches, return pointer to that node. 7 | * If the key is lesser than the data in the node, move pointer to the left child. 8 | * If the key is greater than the data in the node, move pointer to the right child. 9 | * If pointer becomes null, it means the we have reached the end of the tree and the element was not found. Therefore, return NULL. 10 | 11 | ### Iterative Function : 12 | 13 | ```c 14 | struct Node *BSTsearch(struct Node *ptr, int key) { 15 | 16 | while (ptr != NULL) { 17 | if (key == ptr -> data) { 18 | return ptr; 19 | } else if (key < ptr -> data) { 20 | ptr = ptr -> left; 21 | } else { 22 | ptr = ptr -> right; 23 | } 24 | } 25 | return NULL; 26 | 27 | } 28 | ``` 29 | 30 | ### Recursive Function : 31 | 32 | ```c 33 | struct Node *BSTsearch(struct Node *ptr, int key) { 34 | 35 | if (ptr == NULL) { 36 | return NULL; 37 | } 38 | 39 | if (key == ptr -> data) { 40 | return ptr; 41 | } else if (key < ptr -> data) { 42 | return BSTsearch(ptr -> left, key); 43 | } else { 44 | return BSTsearch(ptr -> right, key); 45 | } 46 | 47 | } 48 | ``` 49 | 50 | **Time Complexity : O\(log n\)** 51 | 52 | Contributed by Nitin Ranganath 53 | 54 | -------------------------------------------------------------------------------- /linked-list/inserting-a-node-in-sorted-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to insert a new node in a sorted linked list. 3 | --- 4 | 5 | # Inserting a Node in Sorted List 6 | 7 | ### Procedure : 8 | 9 | * Create a new node and assign the data to it. 10 | * Check if the head node is NULL. If it is, no nodes are present in the linked list and the new node will be the head. 11 | * Check if the head node's data is greater than the data to be inserted. If so, the new node will become the head node. 12 | * If nodes are already present, reach the proper position by checking if the data of next node in each iteration is less than the data to be inserted. 13 | * Once the position is reached, set the next of new node to be the next of current node. 14 | * Finally, set next of current node to new node. 15 | 16 | ```c 17 | void insert(struct node *ptr, int data) { 18 | 19 | // Creating a node 20 | struct node *newNode; 21 | newNode = (struct node *)malloc(sizeof(struct node)); 22 | newNode -> data = data; 23 | 24 | // If there are no nodes or first node data is greater 25 | if (head == NULL || head -> data > data) { 26 | newNode -> next = head; 27 | head = newNode; 28 | } 29 | 30 | // Inserting at correct position 31 | else { 32 | while (ptr -> next != NULL && ptr -> next -> data < data) { 33 | ptr = ptr -> next; 34 | } 35 | newNode -> next = ptr -> next; 36 | ptr -> next = newNode; 37 | } 38 | 39 | } 40 | ``` 41 | 42 | Contributed by Nitin Ranganath 43 | 44 | -------------------------------------------------------------------------------- /linked-list/searching-in-a-node.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Iterative and recursive implementation of linearly searching for an element in 4 | a linked list. 5 | --- 6 | 7 | # Searching in a Node 8 | 9 | ### Iterative Method : 10 | 11 | ```c 12 | struct node * search(struct node *ptr, int key) { 13 | 14 | while (ptr != NULL) { 15 | if (ptr -> data == key) { 16 | // Return address of node if found 17 | return ptr; 18 | } 19 | ptr = ptr -> next; 20 | } 21 | return NULL; 22 | 23 | } 24 | ``` 25 | 26 | ### Recursive Method : 27 | 28 | ```c 29 | struct node * search(struct node *ptr, int key) { 30 | 31 | // Base condition 32 | if (ptr == NULL) { 33 | return NULL; 34 | } 35 | 36 | // Recursive call 37 | if (ptr -> data == key) { 38 | return ptr; 39 | else { 40 | return search(ptr -> next, key); 41 | } 42 | 43 | } 44 | ``` 45 | 46 | ### Improving Using Move to Head Technique : 47 | 48 | ```c 49 | struct node * search(struct node *ptr, int key) { 50 | 51 | // A pointer which will follow ptr 52 | struct node *prev = NULL; 53 | 54 | while (ptr != NULL) { 55 | if (p -> data == key) { 56 | // Move the found node to the start 57 | prev -> next = ptr -> next; 58 | ptr -> next = head; 59 | head = ptr; 60 | return ptr; 61 | } 62 | prev = ptr; 63 | ptr = ptr -> next; 64 | } 65 | return NULL; 66 | 67 | } 68 | ``` 69 | 70 | Contributed by Nitin Ranganath 71 | 72 | -------------------------------------------------------------------------------- /arrays/merging-two-arrays.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Implementation of Merge Algorithm 3 | --- 4 | 5 | # Merging Two Arrays 6 | 7 | ### Procedure : 8 | 9 | Parameters : 3 arrays \(2 sorted arrays of size n1 and n2 respectively and an empty array of size n1+n2 to merge into\), size of array 1 and size of array 2. 10 | 11 | * Initialise i, j and k with 0. 12 | * i is used to keep track of first array, j is used to keep track of second array and k is used to keep track of merged array. 13 | * Compare the values in first array and second array for each index. 14 | * Assign the lower among those two values to the merged array and increment the index pointers accordingly. 15 | * Transfer remaining elements \(if any\) to the merged array. 16 | 17 | ### Merge function : 18 | 19 | ```c 20 | void merge(int a[], int b[], int c[], int n1, int n2) { 21 | 22 | // Index pointers to keep track of arrays 23 | int i = 0, j = 0, k = 0; 24 | 25 | // While elements are present in both arrays 26 | while (i < n1 && j < n2) { 27 | if (a[i] < b[j]) { 28 | c[k] = a[i]; 29 | i++; 30 | } else { 31 | c[k] = b[j]; 32 | j++; 33 | } 34 | k++; 35 | } 36 | 37 | // Transfer remaining elements from first array (if any) 38 | while (i < n1) { 39 | c[k] = a[i]; 40 | i++; 41 | k++; 42 | } 43 | 44 | // Transfer remaining elements from second array (if any) 45 | while (j < n2) { 46 | c[k] = a[i]; 47 | j++; 48 | k++; 49 | } 50 | 51 | } 52 | ``` 53 | 54 | Contributed by Nitin Ranganath 55 | 56 | -------------------------------------------------------------------------------- /linked-list/merge-two-sorted-lists.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to merge two sorted linked lists. 3 | --- 4 | 5 | # Merge Two Sorted Lists 6 | 7 | ```c 8 | void merge(struct node *first, struct node *second) { 9 | 10 | // A pointer to keep track of last node of merged list 11 | struct node *last; 12 | 13 | // First node of merged list 14 | if (first -> data < second -> data) { 15 | // Set head and tail of merged list 16 | third = last = first; 17 | // Move forward in first list 18 | first = first -> next; 19 | } else { 20 | // Set head and tail of merged list 21 | third = last = second; 22 | // Move forward in second list 23 | second = second -> next; 24 | } 25 | third -> next = NULL; 26 | 27 | // Remaining node of merged list 28 | while (first && second) { 29 | if(first -> data < second -> data) { 30 | // Next node will be first's node 31 | last -> next = first; 32 | // Update the last pointer 33 | last = first; 34 | first = first -> next; 35 | } else { 36 | // Next node will be second's node 37 | last -> next = second; 38 | // Update the last pointer 39 | last = second; 40 | second = second -> next; 41 | } 42 | } 43 | 44 | // Merging remaining elements of first list (if any) 45 | if (first) { 46 | last -> next = first; 47 | } 48 | 49 | // Merging remaining elements of second list (if any) 50 | if (second) { 51 | last -> next = second; 52 | } 53 | 54 | } 55 | ``` 56 | 57 | Contributed by Nitin Ranganath 58 | 59 | -------------------------------------------------------------------------------- /arrays/finding-missing-elements.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Methods to find one or more missing elements in an array. 3 | --- 4 | 5 | # Finding Missing Elements 6 | 7 | ### Single Element Missing : 8 | 9 | ```c 10 | void findMissing(int a[], int n, int start) { 11 | 12 | int difference = start - 0; 13 | 14 | for (int i = 0; i < n; i++) { 15 | if (a[i] - i != difference) { 16 | printf("Missing Element : %d\n", i + difference); 17 | break; 18 | } 19 | } 20 | 21 | } 22 | ``` 23 | 24 | ### Multiple Elements Missing : 25 | 26 | ```c 27 | void findMissing(int a[], int n, int start) { 28 | 29 | int diff = start - 0; 30 | printf("Missing Elements :\n"); 31 | 32 | for (int i = 0; i < n; i++) { 33 | if (a[i] - i != diff) { 34 | while (diff < a[i] - i) { 35 | printf("%d\t", i + diff); 36 | diff++; 37 | } 38 | } 39 | } 40 | 41 | } 42 | ``` 43 | 44 | ### Using Hash Array : 45 | 46 | ```c 47 | void findMissing(int a[], int n, int high) { 48 | 49 | // Creating and initializing hash array with 0 50 | // Size of hash array = maximum element in input array 51 | int h[high]; 52 | for (int i = 0; i < high; i++) { 53 | h[i] = 0; 54 | } 55 | 56 | // Incrementing hash table values as per the numbers in 57 | // original input array 58 | for (int i = 0; i < n; i++) { 59 | h[a[i]]++; 60 | } 61 | 62 | printf("Missing Elements :\n"); 63 | for (int i = low; i <= high; i++) { 64 | if (h[i] == 0) { 65 | printf("%d\t", i); 66 | } 67 | } 68 | 69 | } 70 | ``` 71 | 72 | Contributed by Nitin Ranganath 73 | 74 | -------------------------------------------------------------------------------- /stack/stack-using-linked-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Implementation of a stack using linked list and its functions. 3 | --- 4 | 5 | # Stack Using Linked List 6 | 7 | ### Stack Node Structure : 8 | 9 | ```c 10 | struct Node { 11 | int data; 12 | struct Node *next; 13 | }; 14 | 15 | struct Node *top = NULL; 16 | ``` 17 | 18 | ### Function to Check if Stack is Empty : 19 | 20 | ```c 21 | int isEmpty() { 22 | return top == NULL; 23 | } 24 | ``` 25 | 26 | ### Stack Push Function : 27 | 28 | ```c 29 | void push(int data) { 30 | 31 | // Creating a new stack node 32 | struct Node *newNode; 33 | newNode = (struct Node *)malloc(sizeof(struct Node)); 34 | newNode -> data = data; 35 | 36 | // Set the next to point to current top 37 | newNode -> next = top; 38 | 39 | // Update top 40 | top = newNode; 41 | 42 | } 43 | ``` 44 | 45 | ### Stack Pop Function : 46 | 47 | ```c 48 | int pop() { 49 | 50 | if (isEmpty()) { 51 | printf("Stack underflow !\n"); 52 | return -1; 53 | } 54 | 55 | struct Node *toDelete = top; 56 | int poppedValue = top -> data; 57 | top = top -> next; 58 | 59 | free(toDelete); 60 | return poppedValue; 61 | 62 | } 63 | ``` 64 | 65 | ### Stack Peek Function : 66 | 67 | ```c 68 | int peek() { 69 | return top -> data; 70 | } 71 | ``` 72 | 73 | ### Stack Display Function : 74 | 75 | ```c 76 | void display() { 77 | 78 | if (isEmpty()) { 79 | printf("Stack is empty\n"); 80 | return; 81 | } 82 | 83 | struct Node *ptr = top; 84 | while (ptr != NULL) { 85 | printf("%d\t", ptr -> data); 86 | ptr = ptr -> next; 87 | } 88 | printf("\n"); 89 | 90 | } 91 | ``` 92 | 93 | Contributed by Nitin Ranganath 94 | 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures Manual 2 | 3 | ![DS Header Image](https://i.imgur.com/XxR19gB.png) 4 | 5 | ## Mind Map 6 | ![Mind Map](https://i.imgur.com/5m9tojm.png) 7 | [View in Full Res](https://coggle.it/diagram/Xw3BX0l_UGq4pZSV/t/data-structures-in-c/fda843ad62c446e0df85e164749a6bed2b9f88ada72aa60ecedb2257b75c19d6) 8 | 9 | ## Is this guide good for beginners ? What if I have no experience with DS ? 10 | 11 | Absolutely ! I would go as far as to say that this might the very thing that you might be looking for. I guess I have covered almost all the usual operations that could be performed on each data structure. There's procedure and code comments which tries to explain all the important steps. Give it a try ! 12 | 13 | ## I don't like the way everything is presented. 14 | 15 | To be honest, me neither ! So, here's the [GitBook Version](https://nitinranganath.gitbook.io/data-structures/) which has a better user experience in my opinion. There's no difference in the content. Just the UI. 16 | 17 | ## I want to add or modify something. How do I ? 18 | 19 | Glad to hear that. You can make a pull request with your additions or changes. However, there's just one request. Do try to maintain the same style of file naming and layout of content. Proper credits will be given to each contributor, of course. 20 | 21 | ## I don't see any other languages apart from C. 22 | 23 | There isn't any other as of now. However, feel free to create a new branch for whichever language you want to contribute for. More content to be added soon. 24 | 25 | 26 | Like the initiative ? Give this repo a star or contribute to it. This is more than I can ask for. 27 | 28 | ## Additional Resources 29 | ![Big O Cheatsheet](https://i.imgur.com/hwwGrST.png) 30 | Credits: [Big O Cheatsheet](https://www.bigocheatsheet.com/) 31 | -------------------------------------------------------------------------------- /linked-list/finding-the-middle-node.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to find the middle node of a singly linked list. 3 | --- 4 | 5 | # Finding the Middle Node 6 | 7 | ### First Method : Finding Length & Then Middle Element 8 | 9 | * In the first scan of the linked list, find the length of linked list. 10 | * Find the ceiling value of length/2. 11 | * Traverse to the node having that index. 12 | 13 | ```c 14 | int findMid(struct node *ptr) { 15 | 16 | int len = 0; 17 | // Finding the length of linked list 18 | while (ptr != NULL) { 19 | len++; 20 | ptr = ptr -> next; 21 | } 22 | // Find the middle position 23 | int mid = ceil(len/2); 24 | // Resetting ptr to head 25 | ptr = head; 26 | // Return the middle element 27 | for (int i = 0; i < mid; i++) { 28 | ptr = ptr -> next; 29 | } 30 | return ptr -> data; 31 | 32 | } 33 | ``` 34 | 35 | ### Second Method : Using Two Pointers 36 | 37 | * Take two pointers with initial value as the head address. 38 | * Move pointer 2 two times in each iteration while it is not NULL. 39 | * If pointer 2 is not NULL, move pointer 1 once. 40 | 41 | ```c 42 | int findMid() { 43 | 44 | // Two pointers 45 | struct node *ptr1 = head; 46 | struct node *ptr2 = head; 47 | 48 | // Move until pointer 2 becomes NULL 49 | while (ptr2 != NULL) { 50 | // Move pointer 2 two times 51 | ptr2 = ptr2 -> next; 52 | // Don't move again if already NULL 53 | if (ptr2 != NULL) { 54 | ptr2 = ptr2 -> next; 55 | } 56 | // Move pointer 1 if pointer 2 is not NULL 57 | if (ptr2 != NULL) { 58 | ptr1 = ptr1 -> next; 59 | } 60 | } 61 | return ptr1 -> data; 62 | 63 | } 64 | ``` 65 | 66 | Contributed by Nitin Ranganath 67 | 68 | -------------------------------------------------------------------------------- /queue/queue-using-linked-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Implementation of queue using a linked list. 3 | --- 4 | 5 | # Queue using Linked List 6 | 7 | ### Queue Node Structure : 8 | 9 | ```c 10 | struct Node { 11 | int data; 12 | struct Node *next; 13 | }; 14 | 15 | struct Node *front = NULL; 16 | struct Node *rear = NULL; 17 | ``` 18 | 19 | ### Enqueue Operation : 20 | 21 | ```c 22 | void enqueue(int data) { 23 | 24 | // Creating a new queue node 25 | struct Node *newNode; 26 | newNode = (struct Node *)malloc(sizeof(struct Node)); 27 | newNode -> data = data; 28 | 29 | // If this node is the first node to be inserted 30 | if (front == NULL) { 31 | front = rear = newNode; 32 | } 33 | 34 | // If other nodes are already present 35 | else { 36 | rear -> next = newNode; 37 | rear = newNode; 38 | } 39 | 40 | } 41 | ``` 42 | 43 | ### Dequeue Operation : 44 | 45 | ```c 46 | int dequeue() { 47 | 48 | // If queue is already empty 49 | if (front == NULL) { 50 | printf("Queue underflow\n"); 51 | return -1; 52 | } 53 | 54 | else { 55 | // Pointers for node & data to be deleted 56 | struct Node *toDelete = front; 57 | int deletedData = front -> data; 58 | 59 | front = front -> next; 60 | free(toDelete); 61 | return deletedData; 62 | } 63 | 64 | } 65 | ``` 66 | 67 | ### Display Operation : 68 | 69 | ```c 70 | void display() { 71 | 72 | // If queue is empty 73 | if (front == NULL) { 74 | printf("Queue is empty\n"); 75 | return; 76 | } 77 | 78 | struct Node *ptr = front; 79 | while (ptr != NULL) { 80 | printf("%d\t", ptr -> data); 81 | ptr = ptr -> next; 82 | } 83 | printf("\n"); 84 | 85 | } 86 | ``` 87 | 88 | Contributed by Nitin Ranganath 89 | 90 | -------------------------------------------------------------------------------- /arrays/some-more-basic-operations.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: 'The get, set, min, max, sum and average operations.' 3 | --- 4 | 5 | # Some More Basic Operations 6 | 7 | ### Functions : 8 | 9 | * getElement\(\) 10 | * setElement\(\) 11 | * getMin\(\) 12 | * getMax\(\) 13 | * getSum\(\) 14 | * getAverage\(\) 15 | 16 | #### getElement\(\) function: 17 | 18 | ```c 19 | int getElement(int a[], int n, int index) { 20 | if (index >= 0 && index < n) { 21 | return a[index]; 22 | } else { 23 | return -1; 24 | } 25 | } 26 | ``` 27 | 28 | #### setElement\(\) function: 29 | 30 | ```c 31 | void setElement(int a[], int n, int index, int value) { 32 | if (index >= 0 && index < n) { 33 | a[index] = value; 34 | } else { 35 | printf("Wrong index !"); 36 | } 37 | } 38 | ``` 39 | 40 | #### getMax\(\) function: 41 | 42 | ```c 43 | int getMax(int a[], int n) { 44 | int max = a[0]; 45 | for (int i = 0; i < n; i++) { 46 | if (a[i] > max) { 47 | max = a[i]; 48 | } 49 | } 50 | return max; 51 | } 52 | ``` 53 | 54 | #### getMin\(\) function: 55 | 56 | ```c 57 | int getMin(int a[], int n) { 58 | int min = a[0]; 59 | for (int i = 0; i < n; i++) { 60 | if (a[i] < min) { 61 | min = a[i]; 62 | } 63 | } 64 | return min; 65 | } 66 | ``` 67 | 68 | #### getSum\(\) function: 69 | 70 | ```c 71 | int getSum(int a[], int n) { 72 | int sum = 0; 73 | for (int i = 0; i < n; i++) { 74 | sum = sum + a[i]; 75 | } 76 | return sum; 77 | } 78 | ``` 79 | 80 | #### getAverage\(\) function: 81 | 82 | ```c 83 | float getAverage(int a[], int n) { 84 | int sum = 0; 85 | for (int i = 0; i < n; i++) { 86 | sum = sum + a[i]; 87 | } 88 | float average = sum/n; 89 | return average; 90 | } 91 | ``` 92 | 93 | Contributed by Nitin Ranganath 94 | 95 | -------------------------------------------------------------------------------- /arrays/binary-search.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Implementation of binary search in array using iterative as well as recursive 4 | method. 5 | --- 6 | 7 | # Binary Search 8 | 9 | Binary search is a searching technique which is considered to be better than linear search as the array size keeps getting smaller and smaller in each iteration or recursive call and the index of found element can be found in fewer steps as compared to linear search. 10 | 11 | **Time Complexity = O\(log n\)** 12 | 13 | ### Iterative Method 14 | 15 | ```c 16 | int binarySearch(int a[], int low, int high, int key) { 17 | 18 | while (low <= high) { 19 | 20 | int mid = (low + high)/2; 21 | 22 | if (a[mid] == key) { 23 | return mid; 24 | } else if (a[mid] > key) { 25 | // Key lies in the left sublist 26 | high = mid - 1; 27 | } else { 28 | // Key lies in the right sublist 29 | low = mid + 1; 30 | } 31 | 32 | } 33 | 34 | return -1; 35 | 36 | } 37 | ``` 38 | 39 | ### Recursive Method 40 | 41 | ```c 42 | int binarySearch(int a[], int low, int high, int key) { 43 | 44 | if (low <= high) { 45 | 46 | int mid = (low + high)/2; 47 | 48 | if (a[mid] == key) { 49 | return mid; 50 | } else if (a[mid] > key) { 51 | // Key lies in left sublist 52 | return binarySearch(a, low, mid-1, key); 53 | } else { 54 | // Key lies in right sublist 55 | return binarySearch(a, mid+1, high, key); 56 | } 57 | 58 | } 59 | 60 | return -1; 61 | 62 | } 63 | ``` 64 | 65 | In this case, it is better to use iterative version of binary search as recursion uses internal stack. However, the time complexity remains the same for both the methods. 66 | 67 | Contributed by Nitin Ranganath 68 | 69 | -------------------------------------------------------------------------------- /heap/heapify.md: -------------------------------------------------------------------------------- 1 | # Heapify 2 | 3 | ### Max Heapify : 4 | 5 | ```c 6 | void maxHeapify(int h[], int index, int size) { 7 | 8 | // Set largest as parent and set children 9 | int left = 2 * index; 10 | int right = 2 * index + 1; 11 | int largest = index; 12 | 13 | // If left child is greater, make largest point to it 14 | if (left <= size && h[left] > h[largest]) 15 | largest = left; 16 | 17 | // If right child is greater, make largest point to it 18 | if (right <= size && h[right] > h[largest]) 19 | largest = right; 20 | 21 | // If largest is not parent, swap it with passed index 22 | if (largest != index) { 23 | int temp = h[index]; 24 | h[index] = h[largest]; 25 | h[largest] = temp; 26 | maxHeapify(h, largest, size); 27 | } 28 | return; 29 | 30 | } 31 | ``` 32 | 33 | ### Min Heapify : 34 | 35 | ```c 36 | void minHeapify(int h[], int index, int size) { 37 | 38 | // Set smallest as parent and set children 39 | int left = 2 * index; 40 | int right = 2 * index + 1; 41 | int smallest = index; 42 | 43 | // If left child is smaller, make smallest point to it 44 | if (left <= size && h[left] < h[smallest]) 45 | smallest = left; 46 | 47 | // If right child is smaller, make smallest point to it 48 | if (right <= size && h[right] < h[smallest]) 49 | smallest = right; 50 | 51 | // If smallest is not parent, swap it with passed index 52 | if (smallest != index) { 53 | int temp = h[index]; 54 | h[index] = h[smallest]; 55 | h[smallest] = temp; 56 | minHeapify(h, smallest, size); 57 | } 58 | return; 59 | 60 | } 61 | ``` 62 | 63 | **Note:** To build a max heap or min heap, run the function n/2 times . Like this : 64 | 65 | ```c 66 | for (int i = size/2; i >= 1; i--) { 67 | maxHeapify(heap,i,size); 68 | } 69 | ``` 70 | 71 | -------------------------------------------------------------------------------- /arrays/operations-in-a-sorted-array.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Inserting in a sorted array, checking if an array is sorted and shifting 4 | negative elements to the left of array. 5 | --- 6 | 7 | # Operations in a Sorted Array 8 | 9 | ### Inserting in a Sorted Array : 10 | 11 | To insert a new element in a sorted array, keep shifting the rightmost elements to the right by 1 until the element to be inserted is not greater than the element to be shifted. 12 | 13 | ```c 14 | void insertInSorted(int a[], int n, int x) { 15 | 16 | int i = n-1; // Shift from right 17 | 18 | // Shifting elements to the right 19 | while (i >= 0 && a[i] > x) { 20 | a[i+1] = a[i]; 21 | i--; 22 | } 23 | 24 | // Inserting element in proper position 25 | a[i+1] = x; 26 | 27 | } 28 | ``` 29 | 30 | ### Checking if an Array is Sorted : 31 | 32 | To check if an array is sorted, compare the ith element with \(i+1\)th element and check if ith element is greater than \(i+1\)th element. If it is so, this means that the array is not sorted. 33 | 34 | ```c 35 | int isSorted(int a[], int n) { 36 | 37 | // Iterate till length - 1 38 | for(int i = 0; i < n-1; i++) { 39 | // Case for unsorted array 40 | if (a[i] > a[i+1]) { 41 | return 0; 42 | } 43 | } 44 | return 1; 45 | 46 | } 47 | ``` 48 | 49 | ### Rearranging an Array 50 | 51 | In this operation, all the negative numbers in the array are moved to the left side of the array while all the positive numbers are moved to the right side of the array. 52 | 53 | ```c 54 | void rearrange(int a[], int n) { 55 | 56 | int j = 0; 57 | for (int i = 0; i < n; i++) { 58 | // If negative number => Swap a[i] and a[j] 59 | if (a[i] < 0) { 60 | if (i != j) { 61 | swap(&a[i], &a[j]); 62 | } 63 | j++; 64 | } 65 | } 66 | 67 | } 68 | ``` 69 | 70 | Contributed by Nitin Ranganath 71 | 72 | -------------------------------------------------------------------------------- /avl-tree/avl-tree-rotations.md: -------------------------------------------------------------------------------- 1 | # AVL Tree Rotations 2 | 3 | ### LL Rotation : 4 | 5 | ```c 6 | struct Node *LLRotation(struct Node *ptr) { 7 | 8 | struct Node *ptrL = ptr -> left; 9 | struct Node *ptrLR = ptrL -> right; 10 | 11 | ptrL -> right = ptr; 12 | ptr -> left = ptrLR; 13 | 14 | ptr -> height = nodeHeight(ptr); 15 | ptrL -> height = nodeHeight(ptr -> left); 16 | 17 | if (ptr == root) 18 | root = ptrL; 19 | 20 | return ptrL; 21 | 22 | } 23 | ``` 24 | 25 | ### RR Rotation : 26 | 27 | ```c 28 | struct Node *RRRotation(struct Node *ptr) { 29 | 30 | struct Node *ptrR = ptr -> right; 31 | struct Node *ptrRL = ptrR -> left; 32 | 33 | ptrR -> left = ptr; 34 | ptr -> right = ptrRL; 35 | 36 | ptr -> height = nodeHeight(ptr); 37 | ptrR -> height = nodeHeight(ptr -> right); 38 | 39 | if (ptr == root) 40 | root = ptrR; 41 | 42 | return ptrR; 43 | 44 | } 45 | ``` 46 | 47 | ### LR Rotation : 48 | 49 | ```c 50 | struct Node *LRRotation(struct Node *ptr) { 51 | 52 | struct Node *ptrL = ptr -> left; 53 | struct Node *ptrLR = ptrL -> right; 54 | 55 | ptrL -> right = ptrLR -> left; 56 | ptr -> left = ptrLR -> right; 57 | ptrLR -> left = ptrL; 58 | ptrLR -> right = ptr; 59 | 60 | ptr -> height = nodeHeight(ptr); 61 | ptrL -> height = nodeHeight(ptrL); 62 | ptrLR -> height = nodeHeight(ptrLR); 63 | 64 | if (ptr == root) 65 | root = ptrLR; 66 | 67 | return ptrLR; 68 | 69 | } 70 | ``` 71 | 72 | ### RL Rotation : 73 | 74 | ```c 75 | struct Node *RLRotation(struct Node *ptr) { 76 | 77 | struct Node *ptrR = ptr -> right; 78 | struct Node *ptrRL = ptrR -> left; 79 | 80 | ptrR -> left = ptrRL -> right; 81 | ptr -> right = ptrRL -> left; 82 | ptrRL -> left = ptr; 83 | ptrRL -> right = ptrR; 84 | 85 | ptr -> height = nodeHeight(ptr); 86 | ptrR -> height = nodeHeight(ptrR); 87 | ptrRL -> height = nodeHeight(ptrRL); 88 | 89 | if (ptr == root) 90 | root = ptrRL; 91 | 92 | return ptrRL; 93 | 94 | } 95 | ``` 96 | 97 | Contributed by Nitin Ranganath 98 | 99 | -------------------------------------------------------------------------------- /binary-tree/creating-a-binary-tree-using-queue.md: -------------------------------------------------------------------------------- 1 | # Creating a Binary Tree using Queue 2 | 3 | **Note : The below code assumes that a queue of type pointer to Node is already created and initialised.** 4 | 5 | ```c 6 | struct Node { 7 | int data; 8 | struct Node *left; 9 | struct Node *right; 10 | } 11 | 12 | struct Node *root = NULL; 13 | 14 | void createTree(int noOfNodes) { 15 | 16 | // Pointer to keep track of current node and for new nodes 17 | struct Node *ptr, *newNode; 18 | int data; 19 | 20 | // A queue to store addresses of each node 21 | struct Queue q; 22 | create(&q, noOfNodes); 23 | 24 | // Create the root node and make its child NULL by default 25 | printf("Enter the value of root\n"); 26 | scanf("%d", &data); 27 | root = (struct Node *)malloc(sizeof(struct Node)); 28 | root -> data = data; 29 | root -> left = root -> right = NULL; 30 | // Enqueue the root to queue 31 | 32 | // Repeat until no node is to be inserted further 33 | while (isEmpty(q)) { 34 | 35 | // Get address of current node 36 | ptr = dequque(&q); 37 | 38 | // Inserting left child node 39 | printf("Enter the left child of %d:\n", ptr -> data); 40 | scanf("%d", &data); 41 | if (data != -1) { 42 | newNode = (struct Node *)malloc(sizeof(struct Node)); 43 | newNode -> data = data; 44 | newNode -> left = newNode -> right = NULL; 45 | ptr -> left = newNode; 46 | } 47 | 48 | // Inserting right child node 49 | printf("Enter the right child of %d:\n", ptr -> data); 50 | scanf("%d", &data); 51 | if (data != -1) { 52 | newNode = (struct Node *)malloc(sizeof(struct Node)); 53 | newNode -> data = data; 54 | newNode -> left = newNode -> right = NULL; 55 | ptr -> right = newNode; 56 | } 57 | } 58 | 59 | } 60 | ``` 61 | 62 | Contributed by Nitin Ranganath 63 | 64 | -------------------------------------------------------------------------------- /queue/queue-using-array.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Implementation of queue using arrays and its functions. 3 | --- 4 | 5 | # Queue using Array 6 | 7 | ### Queue Structure : 8 | 9 | ```c 10 | struct Queue { 11 | int size; 12 | int front; 13 | int rear; 14 | int *data; 15 | }; 16 | ``` 17 | 18 | ### Creating a Queue Dynamically : 19 | 20 | ```c 21 | struct Queue *createQueue(int size) { 22 | 23 | // Allocating memory for queue 24 | struct Queue *queue; 25 | queue = (struct Queue *)malloc(sizeof(struct Queue)); 26 | 27 | // Set size, front and rear 28 | queue -> size = size; 29 | queue -> front = -1; 30 | queue -> rear = -1; 31 | 32 | // Allocating memory for array 33 | queue -> data = (int *)malloc(size * sizeof(int)); 34 | 35 | return queue; 36 | 37 | } 38 | ``` 39 | 40 | ### Function to Check if Queue is Empty or Full : 41 | 42 | ```c 43 | int isEmpty(struct Queue *queue) { 44 | return queue -> front == queue -> rear; 45 | } 46 | 47 | int isFull(struct Queue *queuevoid display(struct Queue *queue) { 48 | return queue -> rear == queue -> size - 1; 49 | } 50 | ``` 51 | 52 | ### En-queue Function : 53 | 54 | ```c 55 | void enqueue(struct Queue *queue, int data) { 56 | 57 | if (isFull(queue)) { 58 | printf("Queue overflow !\n"); 59 | return; 60 | } 61 | queue -> rear++; 62 | queue -> data[queue -> rear] = data; 63 | 64 | } 65 | ``` 66 | 67 | ### De-queue Function : 68 | 69 | ```c 70 | int dequeue(struct Queue *queue) { 71 | 72 | if (isEmpty(queue)) { 73 | printf("Queue underflow !\n"); 74 | return -1; 75 | } 76 | queue -> front++; 77 | int deletedValue = queue -> data[queue -> front]; 78 | return deletedValue; 79 | 80 | } 81 | ``` 82 | 83 | ### Display Function : 84 | 85 | ```c 86 | void display(struct Queue *queue) { 87 | 88 | for (int i = queue -> front + 1; i <= queue -> rear; i++) { 89 | printf("%d\t", queue -> data[i]); 90 | } 91 | printf("\n"); 92 | 93 | } 94 | ``` 95 | 96 | Contributed by Nitin Ranganath 97 | 98 | -------------------------------------------------------------------------------- /stack/balancing-parenthesis.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: A program to check if the parenthesis are balanced in an equation. 3 | --- 4 | 5 | # Balancing Parenthesis 6 | 7 | ### Procedure : 8 | 9 | * Iterate through the input equation character by character. 10 | * If an opening bracket is found, push it to stack. 11 | * If a closing bracket is found, pop from the stack and check if the popped bracket and the closing bracket match \(are of the same type\). 12 | * If stack is empty and a closing bracket is found, the parenthesis are not balanced. 13 | * If the stack is empty after iterating through all the characters, the parenthesis are balanced. Else, they are not balanced. 14 | 15 | ### C Function : 16 | 17 | ```c 18 | // Function to check if pair is matching 19 | 20 | int isMatchingPair(char a, char b) { 21 | 22 | if ( (a == '(' && b == ')') || (a == '[' && b == ']') || (a == '{' && b == '}') ) { 23 | return 1; 24 | } 25 | return 0; 26 | 27 | } 28 | 29 | int isBalanced(char *equation) { 30 | 31 | // Creating a stack of max size equal to string length 32 | int len = strlen(equation); 33 | char stack[len]; 34 | int top = -1; 35 | 36 | // Iterating through each character 37 | for (int i = 0; equation[i] != '\0'; i++) { 38 | // Push to stack if opening bracket 39 | if (equation[i] == '(' || equation[i] == '[' || equation[i] == '{') { 40 | top++; 41 | stack[top] = equation[i]; 42 | } 43 | // Pop from stack if closing bracket 44 | else if (equation[i] == ')' || equation[i] == ']' || equation[i] == '}') { 45 | char poppedBracket = stack[top]; 46 | top--; 47 | // If pairs are not matching, return false. 48 | if (!isMatchingPair(poppedBracket, equation[i])) { 49 | return 0; 50 | } 51 | } 52 | } 53 | 54 | // If stack is empty, parenthesis are balanced. 55 | if (top == -1) { 56 | return 1; 57 | } 58 | return 0; 59 | 60 | } 61 | ``` 62 | 63 | Contributed by Nitin Ranganath 64 | 65 | -------------------------------------------------------------------------------- /binary-tree/iterative-tree-traversals.md: -------------------------------------------------------------------------------- 1 | # Iterative Tree Traversals 2 | 3 | **The below functions assume that a stack of type pointer to Node is already created which supports push and pop operations.** 4 | 5 | ### Preorder Traversal : 6 | 7 | ```c 8 | void preorderTraversal(struct Node *ptr) { 9 | 10 | // A stack to keep track of visited nodes 11 | struct Stack s; 12 | 13 | // Iterate until pointer is not NULL or stack is not empty 14 | while (ptr != NULL || !isEmpty(s)) { 15 | if (ptr) { 16 | printf("%d\t", ptr -> data); 17 | // Push current node address to stack 18 | push(&s, p); 19 | ptr = ptr -> left; 20 | } else { 21 | ptr = pop(&s); 22 | ptr = ptr -> right; 23 | } 24 | } 25 | 26 | } 27 | ``` 28 | 29 | ### Inorder Traversal : 30 | 31 | ```c 32 | void inorderTraversal(struct Node *ptr) { 33 | 34 | // A stack to keep track of visited nodes 35 | struct Stack s; 36 | 37 | // Iterate until pointer is not NULL or stack is not empty 38 | while (ptr != NULL || !isEmpty(s)) { 39 | if (ptr) { 40 | // Push current node address to stack 41 | push(&s, p); 42 | ptr = ptr -> left; 43 | } else { 44 | ptr = pop(&s); 45 | printf("%d\t", ptr -> data); 46 | ptr = ptr -> right; 47 | } 48 | } 49 | 50 | } 51 | ``` 52 | 53 | ### Postorder Traversal : 54 | 55 | ```c 56 | void postorderTraversal(struct Node *ptr) { 57 | 58 | // A stack to keep track of visited nodes 59 | struct Stack s; 60 | 61 | // Iterate until pointer is not NULL or stack is not empty 62 | while (ptr != NULL || !isEmpty(s)) { 63 | if (ptr) { 64 | // Push current node address to stack 65 | push(&s, p); 66 | ptr = ptr -> left; 67 | } else { 68 | ptr = pop(&s); 69 | ptr = ptr -> right; 70 | printf("%d\t", ptr -> data); 71 | } 72 | } 73 | 74 | } 75 | 76 | ``` 77 | 78 | Contributed by Nitin Ranganath 79 | 80 | -------------------------------------------------------------------------------- /avl-tree/inserting-in-an-avl-tree.md: -------------------------------------------------------------------------------- 1 | # Inserting in an AVL Tree 2 | 3 | ### Procedure : 4 | 5 | * Use the same method used for inserting in a BST. 6 | * Set the height of new nodes to either 1 or 0. \(1 used in code below\) 7 | * Calculate the height and balance factor of each node. 8 | * If the balance factor is not -1, 0 or 1, the tree is imbalanced. 9 | * Perform required rotation. 10 | 11 | ```c 12 | struct Node *insert(struct Node *ptr, int data) { 13 | 14 | if (ptr == NULL) { 15 | // Create a new node and assign required values 16 | struct Node *newNode; 17 | newNode = (struct Node *)malloc(sizeof(struct Node)); 18 | newNode -> data = data; 19 | newNode -> left = newNode -> right = NULL; 20 | newNode -> height = 1; 21 | return newNode; 22 | } 23 | 24 | if (data < ptr -> data) 25 | ptr -> left = insert(ptr -> left, data); 26 | else if (data > ptr -> data) 27 | ptr -> right = insert(ptr -> right, data); 28 | 29 | // Assign height as the max height of left subtree and right subtree 30 | ptr -> height = nodeHeight(ptr); 31 | 32 | // Check balance factor and perform rotation 33 | if (balanceFactor(ptr) == 2 && balanceFactor(ptr -> left) == 1) 34 | return LLRotation(ptr); 35 | else if (balanceFactor(ptr) == 2 && balanceFactor(ptr -> left) == -1) 36 | return LRRotation(ptr); 37 | else if (balanceFactor(ptr) == -2 && balanceFactor(ptr -> right) == 1) 38 | return RLRotation(ptr); 39 | else if (balanceFactor(ptr) == -2 && balanceFactor(ptr -> right) == -1) 40 | return RRRotation(ptr); 41 | 42 | return ptr; 43 | 44 | } 45 | ``` 46 | 47 | **Utility Functions :** 48 | 49 | ```c 50 | int nodeHeight(struct Node *ptr) { 51 | 52 | int leftHeight, rightHeight; 53 | leftHeight = ptr && ptr -> left ? ptr -> left -> height : 0; 54 | rightHeight = ptr && ptr -> right ? ptr -> right -> height : 0; 55 | return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1; 56 | 57 | } 58 | 59 | int balanceFactor(struct Node *ptr) { 60 | 61 | int leftHeight, rightHeight; 62 | leftHeight = ptr && ptr -> left ? ptr -> left -> height : 0; 63 | rightHeight = ptr && ptr -> right ? ptr -> right -> height : 0; 64 | return leftHeight - rightHeight; 65 | 66 | } 67 | ``` 68 | 69 | Contributed by Nitin Ranganath 70 | 71 | -------------------------------------------------------------------------------- /arrays/duplicates-in-an-array.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to find and count duplicates in an array. 3 | --- 4 | 5 | # Duplicates in an Array 6 | 7 | ### Finding Duplicates in a Sorted Array: 8 | 9 | ```c 10 | void findDuplicates(int a[], int n) { 11 | 12 | int lastDuplicate = 0; 13 | printf("Duplicates in the array :\n"); 14 | 15 | for (int i = 0; i < n; i++) { 16 | // If two or more same elements appear consecutively 17 | if (a[i] == a[i+1] && lastDuplicate != a[i]) { 18 | printf("%d\t", a[i]); 19 | // Keeping track of latest duplicate to avoid 20 | // printing the same duplicate again 21 | lastDuplicate = a[i]; 22 | } 23 | } 24 | printf("\n"); 25 | 26 | } 27 | ``` 28 | 29 | ### Counting Duplicates in a Sorted Array: 30 | 31 | ```c 32 | void countDuplicates(int a[], int n) { 33 | 34 | int j; 35 | printf("Duplicates in the array :\n"); 36 | 37 | for (int i = 0; i < n-1; i++) { 38 | if (a[i] == a[i+1]) { 39 | // Start counting duplicates from i + 1 40 | j = i + 1; 41 | while (a[i] == a[j]) { 42 | // Finding the number of duplicates 43 | j++; 44 | } 45 | printf("%d is appearing %d times\n", a[i], j-i); 46 | // Start looking for duplicates again 47 | i = j - 1; 48 | } 49 | } 50 | 51 | } 52 | ``` 53 | 54 | ### Using Hash Array: 55 | 56 | ```c 57 | void findAndCountDuplicates(int a[], int n, int high) { 58 | 59 | // Creating a hash array and initializing with 0 60 | // Size of hash array = maximum element in input array 61 | int h[high]; 62 | for (int i = 0; i < high; i++) { 63 | h[i] = 0; 64 | } 65 | 66 | // Incrementing hash table values as per the numbers in 67 | // original input array 68 | for (int i = 0; i < n; i++) { 69 | h[a[i]]++; 70 | } 71 | 72 | // If any element in hash table has value > 1, 73 | // it means that the element is repeated 74 | for (int i = 0; i <= high; i++) { 75 | if (h[i] > 1) { 76 | printf("%d appears %d times\n", i, h[i]); 77 | } 78 | } 79 | 80 | } 81 | ``` 82 | 83 | Contributed by Nitin Ranganath 84 | 85 | -------------------------------------------------------------------------------- /arrays/linear-search.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Implementation of linear search and methods to improve it 3 | --- 4 | 5 | # Linear Search 6 | 7 | ### Basic Linear Search 8 | 9 | In linear search, each element of the array is scanned through a for loop and is checked if it same as the element that is to be found i.e key. If found, the index at which the element was found is returned or else, -1 is returned. 10 | 11 | **Time Complexity : O\(n\)** 12 | 13 | ```c 14 | int linearSearch(struct Array arr, int key) { 15 | 16 | for (int i = 0; i < arr.length; i++) { 17 | if (arr.A[i] == key) { 18 | return i; 19 | } 20 | } 21 | return -1; 22 | 23 | } 24 | ``` 25 | 26 | ### Improving Linear Search 27 | 28 | Linear search can be improved by two techniques : 29 | 30 | * Transposition method 31 | * Move to head 32 | 33 | ### Transposition Method 34 | 35 | This method works on the concept that if an element is searched for in an array, chances are that it may be searched for again. Therefore, before returning the index of found element, we swap the element with \(i-1\)th element and return i-1 instead of i. 36 | 37 | ```c 38 | int linearSearch(struct Array *arr, int key) { 39 | 40 | for (int i = 0; i < arr -> length; i++) { 41 | if (arr -> A[i] == key) { 42 | swap(&arr -> A[i], &arr -> A[i-1]); 43 | return i-1; 44 | } 45 | } 46 | return -1; 47 | 48 | } 49 | 50 | void swap(int *x, int *y) { 51 | int temp; 52 | temp = *x; 53 | *x = *y; 54 | *y = temp; 55 | } 56 | ``` 57 | 58 | ### Move to Head 59 | 60 | This method is similar to transposition method except that the found element is swapped with first element i.e 0th index element instead of \(i-1\)th element. This reduces the time complexity on searching the same element to O\(1\). 61 | 62 | ```c 63 | int linearSearch(struct Array *arr, int key) { 64 | 65 | for (int i = 0; i < arr -> length; i++) { 66 | if (arr -> A[i] == key) { 67 | swap(&arr -> A[i], &arr -> A[0]); 68 | return 0; 69 | } 70 | } 71 | return -1; 72 | 73 | } 74 | 75 | void swap(int *x, int *y) { 76 | int temp; 77 | temp = *x; 78 | *x = *y; 79 | *y = temp; 80 | } 81 | ``` 82 | 83 | Contributed by Nitin Ranganath 84 | 85 | -------------------------------------------------------------------------------- /stack/stack-using-array.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Complete implementation of a stack using array and its functions. 3 | --- 4 | 5 | # Stack Using Array 6 | 7 | ### Stack Structure : 8 | 9 | ```c 10 | struct Stack { 11 | int size; 12 | int top; 13 | int *data; 14 | }; 15 | ``` 16 | 17 | ### Creating a Stack Dynamically : 18 | 19 | ```c 20 | struct Stack *createStack(int size) { 21 | 22 | // Allocating memory for stack 23 | struct Stack *stack; 24 | stack = (struct Stack *)malloc(sizeof(struct Stack)); 25 | 26 | // Setting size and top 27 | stack -> size = size; 28 | stack -> top = -1; 29 | 30 | // Allocating memory for data array 31 | stack -> data = (int *)malloc(size * sizeof(int)); 32 | 33 | return stack; 34 | 35 | } 36 | ``` 37 | 38 | ### Function to Check if Stack is Empty or Full : 39 | 40 | ```c 41 | int isFull(struct Stack *stack) { 42 | return stack -> top == stack -> size - 1; 43 | } 44 | 45 | int isEmpty(struct Stack *stack) { 46 | return stack -> top == -1; 47 | } 48 | ``` 49 | 50 | ### Stack Push Function : 51 | 52 | ```c 53 | void push(struct Stack *stack, int data) { 54 | 55 | if (isFull(stack)) { 56 | printf("Stack overflow !\n"); 57 | return; 58 | } else { 59 | stack -> top++; 60 | stack -> data[stack -> top] = data; 61 | } 62 | 63 | } 64 | ``` 65 | 66 | ### Stack Pop Function : 67 | 68 | ```c 69 | int pop(struct Stack *stack) { 70 | 71 | if (isEmpty(stack)) { 72 | printf("Stack underflow !\n"); 73 | return -1; 74 | } else { 75 | int poppedData = stack -> data[stack -> top]; 76 | stack -> top--; 77 | return poppedData; 78 | } 79 | 80 | } 81 | ``` 82 | 83 | ### Stack Peek Function : 84 | 85 | ```c 86 | int peek(struct Stack *stack) { 87 | 88 | if (isEmpty(stack)) { 89 | return -1; 90 | } 91 | return stack -> data[stack -> top]; 92 | 93 | } 94 | ``` 95 | 96 | ### Stack Display Function : 97 | 98 | ```c 99 | void display(struct Stack *stack) { 100 | 101 | if (isEmpty(stack)) { 102 | printf("Stack is empty\n"); 103 | return; 104 | } 105 | 106 | for (int i = stack -> top; i >= 0; i--) { 107 | printf("%d\n", stack -> data[i]); 108 | } 109 | 110 | } 111 | ``` 112 | 113 | Contributed by Nitin Ranganath 114 | 115 | -------------------------------------------------------------------------------- /stack/evaluation-of-postfix-expression.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Procedure to evaluate a postfix expression using stack. 3 | --- 4 | 5 | # Evaluation of Postfix Expression 6 | 7 | ### Procedure : 8 | 9 | * Iterate through each character of the given postfix expression. 10 | * If the character is an operand \(0 to 9\), push it to stack after **properly typecasting into integer value from char value by subtracting 48**. 11 | * If the character is an operator, pop 2 items from the stack. The element to the popped will be num2 and the next element will be num1. 12 | * Evaluate the operation using switch case. 13 | * Push the result of evaluation to stack. 14 | * The result will be at stack top after the whole process. 15 | 16 | ### C Program : 17 | 18 | ```c 19 | int isOperand(char); 20 | 21 | // Main function 22 | int main() { 23 | 24 | char postfix[30]; 25 | int stack[30]; 26 | int num1, num2, res, i, top=-1; 27 | 28 | printf("Enter a postfix expression : \n"); 29 | scanf("%s",postfix); 30 | 31 | // Iterate through each character of postfix expression 32 | for(i=0;postfix[i]!='\0';i++) { 33 | 34 | // If character is an operand, push it to stack 35 | if(isOperand(postfix[i])==1) { 36 | top++; 37 | stack[top] = (int)(postfix[i]-48); 38 | } 39 | 40 | // If character is an operator, pop 2 items from stack and perform operation 41 | else { 42 | 43 | // Popping two items from stack 44 | num2 = stack[top]; 45 | top--; 46 | num1 = stack[top]; 47 | top--; 48 | 49 | // Switch case to choose operation 50 | switch(postfix[i]) { 51 | 52 | case '+' : res = num1+num2; 53 | break; 54 | 55 | case '-' : res = num1-num2; 56 | break; 57 | 58 | case '*' : res = num1*num2; 59 | break; 60 | 61 | case '/' : res= num1/num2; 62 | break; 63 | 64 | } 65 | 66 | // Add result to stack top 67 | top++; 68 | stack[top] = res; 69 | 70 | } 71 | } 72 | 73 | // Getting result 74 | printf("Answer of expression : %d\n",stack[top]); 75 | return 0; 76 | 77 | } 78 | 79 | // isOperand function 80 | int isOperand(char x) { 81 | 82 | if(x>='0' && x<='9') { 83 | return 1; 84 | } 85 | else { 86 | return 0; 87 | } 88 | 89 | } 90 | ``` 91 | 92 | Contributed by Nitin Ranganath 93 | 94 | -------------------------------------------------------------------------------- /linked-list/reversing-a-linked-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Iterative and recursive approaches to reverse a linked list. 3 | --- 4 | 5 | # Reversing a Linked List 6 | 7 | ### Reversing by Changing Node Data & Using an Array : 8 | 9 | * Pass the pointer to head node and an array as parameters. 10 | * Using a while loop, copy the data from each node to the array until the pointer becomes NULL. 11 | * Set the pointer to head and decrement to index i by 1 to reach the last element of array. 12 | * Overwrite the data in each node using a while loop and keep decrementing the index i until pointer becomes NULL. 13 | 14 | ```c 15 | void reverse(struct node *ptr, int a[]) { 16 | 17 | // A variable to keep track of array index 18 | int i = 0; 19 | 20 | // Copy data from linked list to array 21 | while (ptr != NULL) { 22 | a[i] = ptr -> data; 23 | i++; 24 | ptr = ptr -> next; 25 | } 26 | 27 | // Set index to begin reverse procedure 28 | ptr = head; 29 | i--; 30 | 31 | // Copy data from array to linked list in reverse 32 | while (ptr != NULL) { 33 | ptr -> data = a[i]; 34 | i--; 35 | ptr = ptr -> next; 36 | } 37 | 38 | } 39 | ``` 40 | 41 | ### Reversing using Sliding Pointers : 42 | 43 | * Take two additional pointers, prev and next, and initialise them with NULL. 44 | * Copy the next address of each node to the next pointer and then set the next address of node to the prev pointer. 45 | * Make current as next and prev as current in order to move forward. 46 | * Do this procedure until current becomes NULL. 47 | * Set the head node as prev pointer. 48 | 49 | ```c 50 | void reverse(struct node *ptr) { 51 | 52 | // Consider ptr to the pointer to current node 53 | struct node *prev = NULL; 54 | struct node *next = NULL; 55 | 56 | while (ptr != NULL) { 57 | // Store the address of next node 58 | next = ptr -> next; 59 | // Make the next of each node point to its previous 60 | ptr -> next = prev; 61 | // Move forward 62 | prev = ptr; 63 | ptr = next; 64 | } 65 | // Setting the value of head node 66 | head = prev; 67 | } 68 | ``` 69 | 70 | ### Reversing by Recursion : 71 | 72 | ```c 73 | void reverse(struct node *prev, struct node *curr) { 74 | 75 | if (curr != NULL) { 76 | reverse(curr, curr -> next); 77 | curr -> next = prev; 78 | } else { 79 | head = prev; 80 | } 81 | 82 | } 83 | 84 | // Function call : reverse(NULL, head) 85 | ``` 86 | 87 | Contributed by Nitin Ranganath 88 | 89 | -------------------------------------------------------------------------------- /queue/double-ended-queue.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Implementation of double ended queue using linked list 3 | --- 4 | 5 | # Double Ended Queue 6 | 7 | ### Inserting from Front : 8 | 9 | ```c 10 | void frontEnqueue(int data) { 11 | 12 | // Creating a queue node 13 | struct Node *newNode; 14 | newNode = (struct node *)malloc(sizeof(struct Node)); 15 | newNode -> data = data; 16 | 17 | // If this node is the first node to be inserted 18 | if (front == NULL) { 19 | front = rear = newNode; 20 | newNode -> next = NULL; 21 | } 22 | 23 | else { 24 | // Make newNode as front node 25 | newNode -> next = front; 26 | front = newNode; 27 | } 28 | 29 | } 30 | ``` 31 | 32 | ### Inserting from Rear : 33 | 34 | ```c 35 | void rearEnqueue(int data) { 36 | 37 | // Creating a queue node 38 | struct Node *newNode; 39 | newNode = (struct node *)malloc(sizeof(struct Node)); 40 | newNode -> data = data; 41 | newNode -> next = NULL; 42 | 43 | // If this node is the first node to be inserted 44 | if (front == NULL) { 45 | front = rear = newNode; 46 | } 47 | 48 | else { 49 | rear -> next = newNode; 50 | newNode -> next = NULL 51 | rear = newNode; 52 | } 53 | 54 | } 55 | ``` 56 | 57 | ### Deleting from Front : 58 | 59 | ```c 60 | int frontDequeue() { 61 | 62 | // If queue is empty 63 | if (front == NULL) { 64 | printf("Queue is empty\n"); 65 | return -1; 66 | } 67 | 68 | else { 69 | // Pointer for node and data to be deleted 70 | struct node *toDelete = front; 71 | int deletedData = front -> data; 72 | front = front -> next; 73 | free(toDelete); 74 | } 75 | 76 | } 77 | ``` 78 | 79 | ### Deleting from Rear : 80 | 81 | ```c 82 | int rearDequeue() { 83 | 84 | // If queue is empty 85 | if (front == NULL) { 86 | printf("Queue is empty\n"); 87 | return -1; 88 | } 89 | 90 | else { 91 | // Reach rear node 92 | struct node *ptr = front; 93 | while (ptr -> next != rear) { 94 | ptr = ptr -> next; 95 | } 96 | // Delete rear node 97 | struct node *toDelete = rear; 98 | int deletedData = rear -> data; 99 | free(rear); 100 | // Make previous node as rear 101 | rear = ptr; 102 | rear -> next = NULL; 103 | } 104 | 105 | } 106 | ``` 107 | 108 | Contributed by Nitin Ranganath 109 | 110 | -------------------------------------------------------------------------------- /doubly-linked-list/circular-doubly-linked-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Basic operations for a circular doubly linked list. 3 | --- 4 | 5 | # Circular Doubly Linked List 6 | 7 | ### Inserting a Node : 8 | 9 | ```c 10 | void insert(struct node *ptr, int data, int pos) { 11 | 12 | // Creating a node 13 | struct node *newNode; 14 | newNode = (struct node *)malloc(sizeof(struct node)); 15 | newNode -> data = data; 16 | 17 | // If node needs to be inserted at first position 18 | if (pos == 1) { 19 | if (head == NULL) { 20 | // If linked list is empty 21 | head = newNode; 22 | head -> prev = head; 23 | head -> next = head; 24 | } else { 25 | // If other nodes are present 26 | newNode -> prev = head -> prev; 27 | newNode -> next = head; 28 | head -> prev = newNode; 29 | newNode -> prev -> next = newNode; 30 | head = newNode; 31 | } 32 | } 33 | 34 | // If node is to be inserted at any other position 35 | else { 36 | for (int i = 0; i < pos - 2; i++) { 37 | ptr = ptr -> next; 38 | } 39 | // Change the links 40 | newNode -> next = ptr -> next; 41 | newNode -> prev = ptr; 42 | ptr -> next -> prev = newNode; 43 | ptr -> next = newNode; 44 | } 45 | 46 | } 47 | ``` 48 | 49 | ### Deleting a Node : 50 | 51 | ```c 52 | void delete(struct node *ptr, int pos) { 53 | 54 | // If the head node is to be deleted 55 | if (pos == 1) { 56 | head -> prev -> next = head -> next; 57 | head -> next -> prev = head -> prev; 58 | head = head -> next; 59 | free(ptr); 60 | } 61 | 62 | else { 63 | // Traverse to the node to be deleted 64 | for (int i = 0; i < pos - 1; i++) { 65 | ptr = ptr -> next; 66 | } 67 | // Change the links 68 | ptr -> prev -> next = ptr -> next; 69 | ptr -> next -> prev = ptr -> prev; 70 | // Deallocate the memory 71 | free(ptr); 72 | } 73 | 74 | } 75 | ``` 76 | 77 | ### Displaying the Nodes : 78 | 79 | ```c 80 | void display(struct node *ptr) { 81 | 82 | // If linked list is empty 83 | if (ptr == NULL) { 84 | printf("Linked list is empty\n"); 85 | return; 86 | } 87 | 88 | do { 89 | printf("%d\t", ptr -> data); 90 | ptr = ptr -> next; 91 | } 92 | while (ptr != head); 93 | printf("\n"); 94 | 95 | } 96 | ``` 97 | 98 | Contributed by Nitin Ranganath 99 | 100 | -------------------------------------------------------------------------------- /arrays/array-adt.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: 'Implementation of append, insert, delete and display function in an array.' 3 | --- 4 | 5 | # Array ADT 6 | 7 | ### Creating a Structure for Array 8 | 9 | ```c 10 | struct Array { 11 | int A[20]; 12 | int length; 13 | int size; 14 | } 15 | ``` 16 | 17 | The following Array structure has three key elements to it: 18 | 19 | * The actual array 20 | * An integer to store the length of the array \(No. of elements present\) 21 | * An integer to store the size of an the array \(Maximum capacity\) 22 | 23 | ### Appending to the End 24 | 25 | For appending an element to the end of an array, we need to first increment the length of the array and then store the desired value in the last index of array. This can be implemented using the following C code : 26 | 27 | ```c 28 | void append(struct Array *arr, int value) { 29 | 30 | // Check if there is enough space to append 31 | if (arr -> length < arr -> size) { 32 | // Set desired value the last index and increment length 33 | arr -> A[length++] = value; 34 | } 35 | 36 | } 37 | ``` 38 | 39 | ### Inserting at a Specific Index 40 | 41 | To insert an element at a particular index in the array, we must check if there's enough space in the array and then shift all the elements to the right of desired index by 1. This creates a space for the element to be inserted at the desired index. Function for the same : 42 | 43 | ```c 44 | void insert(struct Array *arr, int index, int value) { 45 | 46 | // Check if index is valid 47 | if (index >= 0 && index < arr -> length) { 48 | // Shift elements to the right 49 | for (int i = 0; i > index; i++) { 50 | arr -> A[i] = arr -> A[i-1]; 51 | } 52 | // Set the value at desired index 53 | arr -> A[index] = value; 54 | // Increment the length 55 | arr -> length++; 56 | } 57 | 58 | } 59 | ``` 60 | 61 | ### Deleting from Specific Index 62 | 63 | In this operating, the index of the element which needs to be deleted will be passed along with the array. To perform this operation, all the elements which are present after the index from which an element was deleted should be shifted left by 1 and length of array must be decremented. 64 | 65 | ```c 66 | void delete(struct Array *arr, int index) { 67 | 68 | // Check if index is valid or not 69 | if (index >= 0 && index < arr -> length) { 70 | // Shift elements to the left 71 | for (int i = index; i < arr -> length - 1; i++) { 72 | arr -> A[i] = arr -> A[i+1]; 73 | } 74 | arr -> length--; 75 | } 76 | 77 | } 78 | ``` 79 | 80 | Contributed by Nitin Ranganath 81 | 82 | -------------------------------------------------------------------------------- /binary-search-tree/deleting-in-a-bst.md: -------------------------------------------------------------------------------- 1 | # Deleting in a BST 2 | 3 | ### Procedure : 4 | 5 | * Search recursively for the data to be deleted. 6 | * Call the function on the left subtree if the data to be deleted is less than current node's data. 7 | * Call the function on the right subtree if the data to be deleted is greater than current node's data. 8 | * Once the node is found, check the height of it's left and right subtree. 9 | * If the height of left subtree is greater, find the inorder predecessor and replace the data in node to be deleted with inorder predecessor's data. Now, delete the inorder predecessor as it's a leaf node. 10 | * If the height of right subtree is greater, find the inorder successor and replace the data in node to be deleted with inorder successor's data. Now, delete the inorder successor as it's a leaf node. 11 | * If the node to be deleted is a leaf node, check if it is the root node. If yes, make the root as NULL. Then, free the memory. 12 | 13 | ```c 14 | struct Node *deleteNode(struct Node *ptr, int key) { 15 | 16 | if (ptr == NULL) 17 | return NULL; 18 | 19 | // If the node is a leaf node 20 | if (ptr -> left == NULL && ptr -> right == NULL) { 21 | // If it's the root node, make root NULL after deletion 22 | if (ptr == root) 23 | root = NULL; 24 | // Free the memory 25 | free(ptr); 26 | return NULL; 27 | } 28 | 29 | // If value to be deleted is lesser, go to left subtree 30 | if (key < ptr -> data) 31 | ptr -> left = deleteNode(ptr -> left, key); 32 | 33 | // If value to be deleted is greater, go to right subtree 34 | else if (key > ptr -> data) 35 | ptr -> right = deleteNode(ptr -> right, key); 36 | 37 | // Deleting the node once it's found 38 | else { 39 | // Delete from the subtree which has greater height 40 | if (height(ptr -> left) > height(ptr -> right)) { 41 | 42 | // Find the inorder predecessor for left subtree 43 | struct Node *inPre = inorderPredecessor(ptr -> left); 44 | ptr -> data = inPre -> data; 45 | ptr -> left = deleteNode(ptr -> left, inPre -> data); 46 | 47 | } else { 48 | 49 | // Find the inorder successor for right subtree 50 | struct Node *inSuc = inorderSuccessor(ptr -> right); 51 | ptr -> data = inSuc -> data; 52 | ptr -> right = deleteNode(ptr -> right, inSuc -> data); 53 | 54 | } 55 | } 56 | 57 | return ptr; 58 | 59 | } 60 | ``` 61 | 62 | **Utility Functions :** 63 | 64 | ```c 65 | int height(struct Node *ptr) { 66 | 67 | int x, y; 68 | 69 | if (ptr == NULL) 70 | return 0; 71 | 72 | x = height(ptr -> left); 73 | y = height(ptr -> right); 74 | 75 | return x > y ? x + 1 : y + 1; 76 | 77 | } 78 | 79 | struct Node *inorderPredecessor(struct Node *ptr) { 80 | 81 | // Find rightmost child of left subtree 82 | while (ptr && ptr -> right) 83 | ptr = ptr -> right; 84 | return ptr; 85 | 86 | } 87 | 88 | struct Node *inorderSuccessor(struct Node *ptr) { 89 | 90 | // Find leftmost child of right subtree 91 | while (ptr && ptr -> left) 92 | ptr = ptr -> left; 93 | return ptr; 94 | 95 | } 96 | ``` 97 | 98 | Contributed by Nitin Ranganath 99 | 100 | -------------------------------------------------------------------------------- /binary-search-tree/inserting-in-a-bst.md: -------------------------------------------------------------------------------- 1 | # Inserting in a BST 2 | 3 | ### Iterative Insert \(Using Tail Pointer\) : 4 | 5 | ```c 6 | void insert(struct Node *ptr, int data) { 7 | 8 | // New node to be added 9 | struct Node *newNode = (struct Node *)malloc(sizeof(struct Node)); 10 | newNode -> data = data; 11 | newNode -> left = newNode -> right = NULL; 12 | 13 | // Tail pointer 14 | struct Node *parent = NULL; 15 | 16 | // If BST is empty, make new node as root node 17 | if (ptr == NULL) { 18 | root = newNode; 19 | return; 20 | } 21 | 22 | while (ptr != NULL) { 23 | 24 | // Move tail pointer to current node 25 | parent = ptr; 26 | 27 | // Move current node to the next node 28 | if (ptr -> data == data) { 29 | // If the same data node is already present, free new node 30 | free(newNode); 31 | return; 32 | } 33 | 34 | else if (data < ptr -> data) 35 | ptr = ptr -> left; 36 | else 37 | ptr = ptr -> right; 38 | } 39 | 40 | if (data < parent -> data) 41 | parent -> left = newNode; 42 | else 43 | parent -> right = newNode; 44 | 45 | } 46 | ``` 47 | 48 | ### Iterative Insert \(Without Using Tail Pointer\) : 49 | 50 | ```c 51 | void insert(struct Node *ptr, int data) { 52 | 53 | // Creating a new node for new element 54 | struct Node *newNode = (struct Node *)malloc(sizeof(struct Node)); 55 | newNode -> data = data; 56 | newNode -> left = newNode -> right = NULL; 57 | 58 | // If the BST is empty, make the new node as root 59 | if (ptr == NULL) { 60 | root = newNode; 61 | return; 62 | } 63 | 64 | while (ptr != NULL) { 65 | 66 | // If the element is already present in BST 67 | if (ptr -> data == data) 68 | return; 69 | 70 | else if (data < ptr -> data) { 71 | // If the left child is NULL, make new node as left child 72 | // Otherwise, go to the left child 73 | if (ptr -> left == NULL) 74 | ptr -> left = newNode; 75 | else 76 | ptr = ptr -> left; 77 | } 78 | 79 | else { 80 | // If the right child is NULL, make new node as right child 81 | // Otherwise, go to the right child 82 | if (ptr -> right == NULL) 83 | ptr -> right = newNode; 84 | else 85 | ptr = ptr -> right; 86 | } 87 | 88 | } 89 | 90 | } 91 | ``` 92 | 93 | ### Recursive Insert : 94 | 95 | ```c 96 | struct Node *insert(struct Node *ptr, int data) { 97 | 98 | // Create and return a new node when NULL 99 | if (ptr == NULL) { 100 | struct Node *newNode; 101 | newNode = (struct Node *)malloc(sizeof(struct Node)); 102 | newNode -> left = newNode -> right = NULL; 103 | return newNode; 104 | } 105 | 106 | // Insert at appropriate position 107 | if (data < ptr -> data) 108 | ptr -> left = insert(ptr -> left, key); 109 | else if (data > ptr -> data) 110 | ptr -> right = insert(ptr -> right, key); 111 | return ptr; 112 | 113 | } 114 | 115 | // Call like this: 116 | // root = insert(root, 10); <- Assign to root when calling first time 117 | // insert(root, 20); 118 | // insert(root, 30); 119 | ``` 120 | 121 | Contributed by Nitin Ranganath 122 | 123 | -------------------------------------------------------------------------------- /linked-list/inserting-a-node.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Procedure to insert a new node in the beginning, end or at a specific position 4 | in the linked list. 5 | --- 6 | 7 | # Inserting a Node 8 | 9 | ### Insert at Beginning : 10 | 11 | ```c 12 | void insertAtBeginning(struct node *ptr, int data) { 13 | 14 | // Creating a new node 15 | struct node *newNode; 16 | newNode = (struct node *)malloc(sizeof(struct node)); 17 | newNode -> data = data; 18 | 19 | // Make the new node as first node 20 | newNode -> next = head; 21 | head = newNode; 22 | 23 | } 24 | ``` 25 | 26 | ### Insert at N-th Position : 27 | 28 | ```c 29 | void insertAtNthPos(struct node *ptr, int pos, int data) { 30 | 31 | // If position is invalid 32 | if (pos < 0 || pos > count(head)) { 33 | printf("Inavlid position\n"); 34 | return; 35 | } 36 | 37 | else { 38 | 39 | // Creating a new node 40 | struct node *newNode; 41 | newNode = (struct node *)malloc(sizeof(struct node)); 42 | newNode -> data = data; 43 | 44 | // For valid position, traverse to the position 45 | for (int i = 0; i < pos - 2; i++) { 46 | ptr = ptr -> next; 47 | } 48 | 49 | // Setting up links 50 | newNode -> next = ptr -> next; 51 | ptr -> next = newNode; 52 | } 53 | 54 | } 55 | ``` 56 | 57 | {% hint style="info" %} 58 | Indexing for the linked list is considered to start from 1 in the above code where the index of the first node is 1. 59 | 60 | If index is considered to start from 0, change condition to **pos - 1** instead of **pos - 2** in the for loop. 61 | {% endhint %} 62 | 63 | ### Insert at End in O\(1\) Time : 64 | 65 | ```c 66 | void insertAtEnd(struct node *ptr, int data) { 67 | 68 | // Creating a new node 69 | struct node *newNode; 70 | newNode = (struct node *)malloc(sizeof(struct node)); 71 | newNode -> data = data; 72 | newNode -> next = NULL; 73 | 74 | // If there are no nodes present 75 | if (head == NULL) { 76 | first = newNode; 77 | last = newNode; 78 | } 79 | 80 | // If some nodes are already present 81 | else { 82 | last -> next = newNode; 83 | last = newNode; 84 | } 85 | 86 | } 87 | ``` 88 | 89 | {% hint style="info" %} 90 | In the above function, an **additional pointer named last** is taken which will always point to the last node of the linked list. Through this, we can insert a new node to the end of list in constant time. 91 | {% endhint %} 92 | 93 | ### Insert at End in O\(n\) Time : 94 | 95 | ```c 96 | void insertAtEnd(struct node *ptr, int data) { 97 | 98 | // Creating a new node 99 | struct node *newNode; 100 | newNode = (struct node *)malloc(sizeof(struct node)); 101 | newNode -> data = data; 102 | newNode -> next = NULL; 103 | 104 | // Traverse to last node 105 | while (ptr -> next != NULL) { 106 | ptr = ptr -> next; 107 | } 108 | ptr -> next = newNode; 109 | 110 | } 111 | ``` 112 | 113 | Contributed by Nitin Ranganath 114 | 115 | -------------------------------------------------------------------------------- /stack/infix-to-postfix.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Program to convert an infix expression to a postfix expression. 3 | --- 4 | 5 | # Infix to Postfix 6 | 7 | ### C Program : 8 | 9 | ```c 10 | int priority(char); 11 | int isOperand(char); 12 | 13 | // Main function 14 | int main() { 15 | 16 | // Required variables 17 | char infix[30], postfix[30], stack[30]; 18 | int i; 19 | int j = -1; // Used for postfix array 20 | int top = -1; // Used for stack 21 | 22 | // Scanning the expression 23 | printf("Enter the infix expression : \n"); 24 | scanf("%s", infix); 25 | 26 | // Scanning each character one by one 27 | for (i = 0; infix[i] != '\0'; i++) { 28 | 29 | // If character is an operand, add to postfix expression 30 | if (isOperand(infix[i]) == 1) { 31 | j++; 32 | postfix[j] = infix[i]; 33 | } 34 | 35 | // If character is an operator 36 | 37 | // If stack is empty 38 | else if (top == -1) { 39 | top++; 40 | stack[top] = infix[i]; 41 | } 42 | 43 | // If closing bracket is encountered, pop from stack until opening bracket is at stack top 44 | else if (infix[i] == ')') { 45 | while (stack[top] != '(') { 46 | j++; 47 | postfix[j] = stack[top]; 48 | top--; 49 | } 50 | top--; 51 | } 52 | 53 | // If scanned operator has higher priority than stack top operator, push it to stack 54 | else if (priority(infix[i]) > priority(stack[top])) { 55 | top++; 56 | stack[top] = infix[i]; 57 | } 58 | 59 | // If scanned operator has lower priority than stack top operator, pop from stack until stack top has lower priority 60 | else if (priority(stack[top]) >= priority(infix[i])) { 61 | while (priority(stack[top]) >= priority(infix[i]) && top != -1 && stack[top] != '(') { 62 | j++; 63 | postfix[j] = stack[top]; 64 | top--; 65 | } 66 | top++; 67 | stack[top] = infix[i]; 68 | } 69 | } 70 | 71 | // Pop all remaning operators from stack until stack is empty 72 | while (top != -1) { 73 | j++; 74 | postfix[j] = stack[top]; 75 | top--; 76 | } 77 | 78 | // Set postfix[j+1] as \0 79 | postfix[j + 1] = '\0'; 80 | 81 | // Output the postfix expression 82 | puts(postfix); 83 | return 0; 84 | 85 | } 86 | 87 | // Priority function 88 | int priority(char x) { 89 | 90 | if (x == '*' || x == '/') { 91 | return 3; 92 | } 93 | else if (x == '+' || x == '-') { 94 | return 2; 95 | } 96 | else if (x == '(' || x == ')') { 97 | return 1; 98 | } 99 | else { 100 | return 0; 101 | } 102 | 103 | } 104 | 105 | // isOperand function 106 | int isOperand(char x) { 107 | 108 | if ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || (x >= 0 && x <= 9)) { 109 | return 1; 110 | } 111 | else { 112 | return 0; 113 | } 114 | 115 | } 116 | ``` 117 | 118 | Contributed by Nitin Ranganath 119 | 120 | -------------------------------------------------------------------------------- /arrays/set-operations.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Implementation of set operations like union, intersection, difference and set 4 | membership. 5 | --- 6 | 7 | # Set Operations 8 | 9 | ### Union Operation : 10 | 11 | To get the union of two arrays, apply merge procedure such that if an element is present in both arrays, **copy it to the merged array once and increment both i and j**. 12 | 13 | ```c 14 | void unionOfArray(int a[], int b[], int c[], int n1, int n2) { 15 | 16 | // Index pointers 17 | int i = 0, j = 0, k= 0; 18 | 19 | while (i < n1 && j < n2) { 20 | // If elements are same, copy once and increment all 21 | if (a[i] == b[j]) { 22 | c[k] = a[i]; 23 | i++; 24 | j++; 25 | } else if (a[i] < b[j]) { 26 | c[k] = a[i]; 27 | i++; 28 | } else { 29 | c[k] = b[j]; 30 | j++; 31 | } 32 | k++; 33 | } 34 | 35 | // Copy remaining elements from first array 36 | while (i < n1) { 37 | c[k] = a[i]; 38 | i++; 39 | k++; 40 | } 41 | 42 | // Copy remaining elements from second array 43 | while (j < n2) { 44 | c[k] = b[j]; 45 | j++; 46 | k++; 47 | } 48 | 49 | } 50 | ``` 51 | 52 | ### Intersection Operation : 53 | 54 | In intersection operation, apply merge procedure in such a manner that the **elements are copied only if they are the same or else, their index pointers should just be incremented**. Leftover elements will not be considered. 55 | 56 | ```c 57 | void intersection(int a[], int b[], int c[], int n1, int n2) { 58 | 59 | int i = 0, j = 0, k= 0; 60 | 61 | while (i < n1 && j < n2) { 62 | // Increment all index pointers if element is same 63 | if (a[i] == b[j]) { 64 | c[k] = a[i]; 65 | i++; 66 | j++; 67 | k++; 68 | } else if (a[i] < b[j]) { 69 | i++; 70 | } else { 71 | j++; 72 | } 73 | } 74 | 75 | } 76 | ``` 77 | 78 | ### Difference Operation : 79 | 80 | The difference operation or A-B operation will also follow the merge procedure but in such a manner that **elements will only be copied from the first array and that too only if it is not present in the second array.** 81 | 82 | ```c 83 | void difference(int a[], int b[], int c[], int n1, int n2) { 84 | 85 | int i = 0, j = 0, k= 0; 86 | 87 | while (i < n1 && j < n2) { 88 | // If elements are same, just increment i and j 89 | if (a[i] == b[j]) { 90 | i++; 91 | j++; 92 | } else if (a[i] < b[j]) { 93 | // If element is not same and present in first array, 94 | // copy it and increment i and k. 95 | c[k] = a[i]; 96 | i++; 97 | k++; 98 | } else { 99 | // If element is in second array, just increment j. 100 | j++; 101 | } 102 | } 103 | 104 | // Copy remaining elements from first array 105 | while (i < n1) { 106 | c[k] = a[i]; 107 | i++; 108 | k++; 109 | } 110 | 111 | } 112 | ``` 113 | 114 | ### Set Membership : 115 | 116 | For set membership operation, just implement binary search or linear search. 117 | 118 | Contributed by Nitin Ranganath 119 | 120 | -------------------------------------------------------------------------------- /binary-tree/counting-nodes-in-a-binary-tree.md: -------------------------------------------------------------------------------- 1 | # Counting Nodes in a Binary Tree 2 | 3 | ### Count All Nodes in Binary Tree : 4 | 5 | ```c 6 | int countAllNodes(struct Node *ptr) { 7 | 8 | // Variables to obtain nodes is left and right subtree 9 | int leftNodes, rightNodes; 10 | 11 | if (ptr) { 12 | leftNodes = countAllNodes(ptr -> left); 13 | rightNodes = countAllNodes(ptr -> right); 14 | return leftNodes + rightNodes + 1; 15 | } 16 | return 0; 17 | 18 | } 19 | ``` 20 | 21 | ### Count Nodes Having Both Children \(Degree 2\) : 22 | 23 | ```c 24 | int countTwoChildren(struct Node *ptr) { 25 | 26 | // Variables to obtain nodes is left and right subtree 27 | int leftNodes, rightNodes; 28 | 29 | if (ptr) { 30 | leftNodes = countTwoChildren(ptr -> left); 31 | rightNodes = countTwoChildren(ptr -> right); 32 | // Check if both children are present 33 | if (ptr -> left && ptr -> right) { 34 | return leftNodes + rightNodes + 1; 35 | } else { 36 | return leftNodes + rightNodes; 37 | } 38 | } 39 | return 0; 40 | 41 | } 42 | ``` 43 | 44 | ### Count Nodes Having One or More Children \(Degree 1 or 2\) : 45 | 46 | ```c 47 | int countOneOrMore(struct Node *ptr) { 48 | 49 | // Variables to obtain nodes is left and right subtree 50 | int leftNodes, rightNodes; 51 | 52 | if (ptr) { 53 | leftNodes = countOneOrMore(ptr -> left); 54 | rightNodes = countOneOrMore(ptr -> right); 55 | // Check if atleast one child is present 56 | if (ptr -> left || ptr -> right) { 57 | return leftNodes + rightNodes + 1; 58 | } else { 59 | return leftNodes + rightNodes; 60 | } 61 | } 62 | return 0; 63 | 64 | } 65 | ``` 66 | 67 | ### Count Nodes Having Exactly One Child \(Degree 1\) : 68 | 69 | ```c 70 | int countOneChild(struct Node *ptr) { 71 | 72 | // Variables to obtain nodes is left and right subtree 73 | int leftNodes, rightNodes; 74 | 75 | if (ptr) { 76 | leftNodes = countOneChild(ptr -> left); 77 | rightNodes = countOneChild(ptr -> right); 78 | // Perform XOR operation to check if only child is present 79 | if (ptr -> left ^ ptr -> right) { 80 | return leftNodes + rightNodes + 1; 81 | } else { 82 | return leftNodes + rightNodes; 83 | } 84 | } 85 | return 0; 86 | 87 | } 88 | ``` 89 | 90 | ### Count Leaf Nodes \(Degree 0\) : 91 | 92 | ```c 93 | int countLeafNodes(struct Node *ptr) { 94 | 95 | // Variables to obtain nodes is left and right subtree 96 | int leftNodes, rightNodes; 97 | 98 | if (ptr) { 99 | leftNodes = countLeafNodes(ptr -> left); 100 | rightNodes = countLeafNodes(ptr -> right); 101 | // Check if both children are NULL 102 | if (!(ptr -> left) && !(ptr -> right)) { 103 | return leftNodes + rightNodes + 1; 104 | } else { 105 | return leftNodes + rightNodes; 106 | } 107 | } 108 | return 0; 109 | 110 | } 111 | ``` 112 | 113 | ### Alternative Way of Counting \(Without Variables\) : 114 | 115 | ```c 116 | int count(struct Node *ptr) { 117 | 118 | if (ptr == NULL) { 119 | return 0; 120 | } 121 | return count(ptr -> left) + count(ptr -> right) + 1; 122 | 123 | } 124 | ``` 125 | 126 | Following the same style for all the other conditions. 127 | 128 | Contributed by Nitin Ranganath 129 | 130 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Data Structures Manual](README.md) 4 | 5 | ## Arrays 6 | 7 | * [Array ADT](arrays/array-adt.md) 8 | * [Linear Search](arrays/linear-search.md) 9 | * [Binary Search](arrays/binary-search.md) 10 | * [Some More Basic Operations](arrays/some-more-basic-operations.md) 11 | * [Reversing an Array](arrays/reversing-an-array.md) 12 | * [Operations in a Sorted Array](arrays/operations-in-a-sorted-array.md) 13 | * [Merging Two Arrays](arrays/merging-two-arrays.md) 14 | * [Set Operations](arrays/set-operations.md) 15 | * [Finding Missing Elements](arrays/finding-missing-elements.md) 16 | * [Duplicates in an Array](arrays/duplicates-in-an-array.md) 17 | * [Getting a Pair whose Sum = K](arrays/getting-a-pair-whose-sum-k.md) 18 | * [Finding Max & Min in Single Scan](arrays/finding-max-and-min-in-single-scan.md) 19 | 20 | ## Strings 21 | 22 | * [Finding the Length of a String](strings/finding-the-length-of-a-string.md) 23 | * [Changing Cases in a String](strings/changing-cases-in-a-string.md) 24 | * [Finding Number of Vowels, Consonants & Words](strings/finding-number-of-vowels-consonants-and-words.md) 25 | * [Reversing a String](strings/reversing-a-string.md) 26 | * [Checking for Palindrome](strings/checking-for-palindrome.md) 27 | * [Duplicates in a String](strings/duplicates-in-a-string.md) 28 | * [Checking if Strings are Anagrams](strings/checking-if-strings-are-anagrams.md) 29 | * [Permutations of a String](strings/permutations-of-a-string.md) 30 | 31 | ## Singly Linked List 32 | 33 | * [Displaying the Nodes](linked-list/displaying-the-nodes.md) 34 | * [Counting the Nodes](linked-list/counting-the-nodes.md) 35 | * [Sum of all Nodes](linked-list/sum-of-all-nodes.md) 36 | * [Finding the Maximum Element](linked-list/finding-the-maximum-element.md) 37 | * [Searching in a Node](linked-list/searching-in-a-node.md) 38 | * [Inserting a Node](linked-list/inserting-a-node.md) 39 | * [Inserting a Node in Sorted List](linked-list/inserting-a-node-in-sorted-list.md) 40 | * [Deleting a Node](linked-list/deleting-a-node.md) 41 | * [Checking if List is Sorted](linked-list/checking-if-list-is-sorted.md) 42 | * [Removing Duplicates from a List](linked-list/removing-duplicates-from-a-list.md) 43 | * [Reversing a Linked List](linked-list/reversing-a-linked-list.md) 44 | * [Concatenating Two Lists](linked-list/concatenating-two-lists.md) 45 | * [Detecting a Loop in Linked List](linked-list/detecting-a-loop-in-linked-list.md) 46 | * [Merge Two Sorted Lists](linked-list/merge-two-sorted-lists.md) 47 | * [Finding the Middle Node](linked-list/finding-the-middle-node.md) 48 | 49 | ## Cirular Linked List 50 | 51 | * [Displaying the Nodes](cirular-linked-list/displaying-the-nodes.md) 52 | * [Inserting a Node](cirular-linked-list/inserting-a-node.md) 53 | * [Deleting a Node](cirular-linked-list/deleting-a-node.md) 54 | 55 | ## Doubly Linked List 56 | 57 | * [Inserting a Node](doubly-linked-list/inserting-a-node.md) 58 | * [Deleting a Node](doubly-linked-list/deleting-a-node.md) 59 | * [Reversing a Doubly Linked List](doubly-linked-list/reversing-a-doubly-linked-list.md) 60 | * [Circular Doubly Linked List](doubly-linked-list/circular-doubly-linked-list.md) 61 | 62 | ## Stack 63 | 64 | * [Stack Using Array](stack/stack-using-array.md) 65 | * [Stack Using Linked List](stack/stack-using-linked-list.md) 66 | * [Balancing Parenthesis](stack/balancing-parenthesis.md) 67 | * [Infix to Postfix](stack/infix-to-postfix.md) 68 | * [Evaluation of Postfix Expression](stack/evaluation-of-postfix-expression.md) 69 | 70 | ## Queue 71 | 72 | * [Queue using Array](queue/queue-using-array.md) 73 | * [Queue using Linked List](queue/queue-using-linked-list.md) 74 | * [Double Ended Queue](queue/double-ended-queue.md) 75 | 76 | ## Binary Tree 77 | 78 | * [Creating a Binary Tree using Queue](binary-tree/creating-a-binary-tree-using-queue.md) 79 | * [Recursive Tree Traversals](binary-tree/recursive-tree-traversals.md) 80 | * [Iterative Tree Traversals](binary-tree/iterative-tree-traversals.md) 81 | * [Level Order Traversal](binary-tree/level-order-traversal.md) 82 | * [Counting Nodes in a Binary Tree](binary-tree/counting-nodes-in-a-binary-tree.md) 83 | * [Finding the Height of Tree](binary-tree/finding-the-height-of-tree.md) 84 | * [Finding Sum of All Nodes](binary-tree/finding-sum-of-all-nodes.md) 85 | 86 | ## Binary Search Tree 87 | 88 | * [Searching in a BST](binary-search-tree/searching-in-a-bst.md) 89 | * [Inserting in a BST](binary-search-tree/inserting-in-a-bst.md) 90 | * [Deleting in a BST](binary-search-tree/deleting-in-a-bst.md) 91 | 92 | ## AVL Tree 93 | 94 | * [Inserting in an AVL Tree](avl-tree/inserting-in-an-avl-tree.md) 95 | * [AVL Tree Rotations](avl-tree/avl-tree-rotations.md) 96 | * [Deleting in an AVL Tree](avl-tree/deleting-in-an-avl-tree.md) 97 | 98 | ## Heap 99 | 100 | * [Inserting in a Heap](heap/inserting-in-a-heap.md) 101 | * [Deleting in a Heap](heap/deleting-in-a-heap.md) 102 | * [Heapify](heap/heapify.md) 103 | 104 | -------------------------------------------------------------------------------- /avl-tree/deleting-in-an-avl-tree.md: -------------------------------------------------------------------------------- 1 | # Deleting in an AVL Tree 2 | 3 | ### Procedure : 4 | 5 | * Perform the same steps as deleting in a binary search tree. 6 | * After that, assign new height to the node. 7 | * Check the balance factor of the node. 8 | * According to the balance of the node and it's left/right child, perform rotation in order to balance the balance the tree 9 | 10 | ```c 11 | struct Node *deleteNode(struct Node *ptr , int key) { 12 | 13 | // If there's no node to be deleted 14 | if (ptr == NULL) 15 | return NULL; 16 | 17 | // If the node is a leaf node 18 | if (ptr -> left == NULL && ptr -> right == NULL) { 19 | // If it's the root node, make root NULL after deletion 20 | if (ptr == root) 21 | root = NULL; 22 | // Free the memory 23 | free(ptr); 24 | return NULL; 25 | } 26 | 27 | // If value to be deleted is lesser, go to left subtree 28 | if (key < ptr -> data) 29 | ptr -> left = deleteNode(ptr -> left, key); 30 | 31 | // If value to be deleted is greater, go to right subtree 32 | else if (key > ptr -> data) 33 | ptr -> right = deleteNode(ptr -> right, key); 34 | 35 | // Deleting the node once it's found 36 | else { 37 | // Delete from the subtree which has greater height 38 | if (nodeHeight(ptr -> left) > nodeHeight(ptr -> right)) { 39 | 40 | // Find the inorder predecessor for left subtree 41 | struct Node *inPre = inorderPredecessor(ptr -> left); 42 | ptr -> data = inPre -> data; 43 | ptr -> left = deleteNode(ptr -> left, inPre -> data); 44 | 45 | } else { 46 | 47 | // Find the inorder successor for right subtree 48 | struct Node *inSuc = inorderSuccessor(ptr -> right); 49 | ptr -> data = inSuc -> data; 50 | ptr -> right = deleteNode(ptr -> right, inSuc -> data); 51 | 52 | } 53 | } 54 | 55 | // Set new height 56 | ptr->height = nodeHeight(ptr); 57 | 58 | // Rotate as per balance factor 59 | if(balanceFactor(ptr) == 2 && balanceFactor(ptr -> left) == 1) 60 | return LLRotation(ptr); //L 1 Rotation 61 | else if(balanceFactor(ptr) == 2 && balanceFactor(ptr -> left)==-1) 62 | return LRRotation(ptr); //L -1 Rotation 63 | else if(balanceFactor(ptr) == 2 && balanceFactor(ptr -> left) == 0) 64 | return LLRotation(ptr); //L 0 Rotation 65 | else if(balanceFactor(ptr) == 2 && balanceFactor(ptr -> right) == 1) 66 | return RRRotation(ptr); //R 1 Rotation 67 | else if(balanceFactor(ptr) == 2 && balanceFactor(ptr -> right) == -1) 68 | return RLRotation(ptr); //R-1 Rotation 69 | else if(balanceFactor(ptr) == 2 && balanceFactor(ptr -> right) == 0) 70 | return RRRotation(ptr); //R 0 Rotation 71 | 72 | return ptr; 73 | 74 | } 75 | ``` 76 | 77 | **Utility Functions :** 78 | 79 | ```c 80 | // Node height function 81 | int nodeHeight(struct Node *ptr) { 82 | 83 | int leftHeight, rightHeight; 84 | leftHeight = ptr && ptr -> left ? ptr -> left -> height : 0; 85 | rightHeight = ptr && ptr -> right ? ptr -> right -> height : 0; 86 | return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1; 87 | 88 | } 89 | 90 | // Balance factor function 91 | int balanceFactor(struct Node *ptr) { 92 | 93 | int leftHeight, rightHeight; 94 | leftHeight = ptr && ptr -> left ? ptr -> left -> height : 0; 95 | rightHeight = ptr && ptr -> right ? ptr -> right -> height : 0; 96 | return leftHeight - rightHeight; 97 | 98 | } 99 | 100 | // LL Rotation 101 | struct Node *LLRotation(struct Node *ptr) { 102 | 103 | struct Node *ptrL = ptr -> left; 104 | struct Node *ptrLR = ptrL -> right; 105 | 106 | ptrL -> right = ptr; 107 | ptr -> left = ptrLR; 108 | 109 | ptr -> height = nodeHeight(ptr); 110 | ptrL -> height = nodeHeight(ptr -> left); 111 | 112 | if (ptr == root) 113 | root = ptrL; 114 | 115 | return ptrL; 116 | 117 | } 118 | 119 | // LR Rotation 120 | struct Node *LRRotation(struct Node *ptr) { 121 | 122 | struct Node *ptrL = ptr -> left; 123 | struct Node *ptrLR = ptrL -> right; 124 | 125 | ptrL -> right = ptrLR -> left; 126 | ptr -> left = ptrLR -> right; 127 | ptrLR -> left = ptrL; 128 | ptrLR -> right = ptr; 129 | 130 | ptr -> height = nodeHeight(ptr); 131 | ptrL -> height = nodeHeight(ptrL); 132 | ptrLR -> height = nodeHeight(ptrLR); 133 | 134 | if (ptr == root) 135 | root = ptrLR; 136 | 137 | return ptrLR; 138 | 139 | } 140 | 141 | // RR Rotation 142 | struct Node *RRRotation(struct Node *ptr) { 143 | 144 | struct Node *ptrR = ptr -> right; 145 | struct Node *ptrRL = ptrR -> left; 146 | 147 | ptrR -> left = ptr; 148 | ptr -> right = ptrRL; 149 | 150 | ptr -> height = nodeHeight(ptr); 151 | ptrR -> height = nodeHeight(ptr -> right); 152 | 153 | if (ptr == root) 154 | root = ptrR; 155 | 156 | return ptrR; 157 | 158 | } 159 | 160 | // RL Rotation 161 | struct Node *RLRotation(struct Node *ptr) { 162 | 163 | struct Node *ptrR = ptr -> right; 164 | struct Node *ptrRL = ptrR -> left; 165 | 166 | ptrR -> left = ptrRL -> right; 167 | ptr -> right = ptrRL -> left; 168 | ptrRL -> left = ptr; 169 | ptrRL -> right = ptrR; 170 | 171 | ptr -> height = nodeHeight(ptr); 172 | ptrR -> height = nodeHeight(ptrR); 173 | ptrRL -> height = nodeHeight(ptrRL); 174 | 175 | if (ptr == root) 176 | root = ptrRL; 177 | 178 | return ptrRL; 179 | 180 | } 181 | ``` 182 | 183 | Contributed by Nitin Ranganath 184 | 185 | --------------------------------------------------------------------------------