├── .gitignore ├── Algorithms ├── BackTracking │ ├── Find Longest Possible Route in a Matrix.cpp │ ├── N-Queen.cpp │ ├── Permutations of a given string.cpp │ ├── SELECTION PROBLEMS │ │ ├── combinations.cpp │ │ ├── next_permuation.cpp │ │ ├── permutations.cpp │ │ └── subsets.cpp │ ├── binary strings that can be formed from given wildcard pattern.cpp │ ├── determine-pattern-matches-string-not.cpp │ ├── find-combinations-of-elements-satisfies-given-constraints.cpp │ ├── find-shortest-path-in-maze.cpp │ ├── find-ways-calculate-target-elements-array.cpp │ ├── generate-list-of-possible-words-from-a-character-matrix.cpp │ ├── hamiltonian_paths.cpp │ ├── k-partition-problem-print-all-subsets.cpp │ ├── kcolor_graph.cpp │ └── knight.cpp ├── Bit Manipulation │ └── 1.cpp ├── Dynamic Programming │ ├── 0-1Knapsack(DP).cpp │ ├── EditDistance(DP).cpp │ ├── LongestIncSubsequence(DP).cpp │ ├── LongestPallindromicSubstring(DP).cpp │ ├── matrix_chain_multiplication.cpp │ └── rod_cutting(DP).cpp ├── GRAPHS │ ├── All_pair_shortest_path │ │ └── floyd_warshall.cpp │ ├── Bipartite graph │ │ └── code.cpp │ ├── Bridges │ │ ├── bridge.bin │ │ └── bridge.cpp │ ├── Cycle Detection │ │ ├── Directed Graph │ │ │ └── dfs.cpp │ │ └── Undirected Graph │ │ │ ├── dfs.cpp │ │ │ └── dsu.cpp │ ├── DSU │ │ └── dsu.cpp │ ├── Euler Path and Cycle │ │ └── a.cpp │ ├── Hamiltonian Path and cycle │ │ └── a.cpp │ ├── Longest Path in a DAG │ │ └── main.cpp │ ├── Minimum Spanning Tree │ │ ├── my_kruskal.cpp │ │ └── prims_CN.cpp │ ├── Single_source_Shortest_distance │ │ ├── bellman_ford.cpp │ │ ├── dijkstra.cpp │ │ └── dijsktra practice.cpp │ ├── Topological Sort │ │ ├── dfs.cpp │ │ └── kahn.cpp │ ├── Traversals │ │ ├── BFS │ │ │ ├── ITERATIVE.CPP │ │ │ └── RECURSIVE.CPP │ │ └── DFS │ │ │ ├── iterative.cpp │ │ │ └── recursive.cpp │ └── arr_dept_time_dfs.cpp ├── Others │ └── Stable_Matching.cpp ├── Search │ ├── Linear search.cpp │ ├── binarySearch.cp │ └── ternarySearch.cpp ├── Sorting │ ├── CountingSort.cpp │ ├── HeapSort.cpp │ ├── RadixSort.cpp │ ├── analysis.md │ ├── bubbleSort.cpp │ ├── insertionSort.cpp │ ├── mergeSort.cpp │ ├── quickSort.cpp │ └── selectionSort.cpp ├── String Matching │ ├── Z-algo.cpp │ └── kmp.cpp └── TREES │ ├── BST │ ├── inorder_pred.cpp │ └── inorder_suc.cpp │ ├── LCA │ ├── Naive_1.cpp │ ├── Naive_2.cpp │ ├── RMQ.cpp │ ├── nary_naive.cpp │ ├── sparse_matrix_nary.cpp │ ├── sqrt_decom_optimized.cpp │ ├── sqrt_decomposition_naive.cpp │ └── using_parent_pointer.cpp │ └── Traversals │ ├── Iterative │ ├── inorder.cpp │ ├── postorder.cpp │ ├── postorder_using_1_stacks.cpp │ └── preorder.cpp │ ├── bottmo view.cpp │ ├── top view.cpp │ └── vertical order traversal.cpp ├── CONTRIBUTING.md ├── DOCUMENTATION.md ├── DS implementations ├── FENWICK TREES │ └── index.cpp ├── GRAPHS │ ├── Impl_USING STL │ │ ├── directed_weighted_graph.cpp │ │ └── un_directed_graph.cpp │ └── Impl_WITHOUT STL │ │ ├── directed_graph.cpp │ │ ├── directed_graph.exe │ │ └── weighted_directed_graph.cpp ├── HASHMAPS │ ├── INDEX2.CPP │ ├── basic.cpp │ ├── chaining.cpp │ ├── open_addressing.cpp │ └── theory.md ├── Linked List │ ├── Double_linked_list │ │ └── doublelinkedlist.cpp │ ├── circular_linked_list │ │ └── circular.cpp │ └── list.cpp ├── PRIORITY_QUEUES │ ├── max_pq.cpp │ └── min_pq.cpp ├── QUEUES │ ├── Queue_Implementation.cpp │ └── queues_linkedlist │ │ └── queue_with_linkedlist.cpp ├── SEGMENT TREES │ ├── lazy_propagation.cpp │ └── main.cpp ├── STACKS │ ├── Stack_Implementation.cpp │ └── Stack_linked_list │ │ └── stack_with_linkedlist.cpp ├── TREES │ └── BST.cpp └── TRIES │ ├── index.cpp │ └── practice.cpp ├── General ├── euler_totient.bin ├── euler_totient.cpp ├── gcd.cpp ├── permutations │ ├── distinct_permutations.cpp │ ├── kth permutaion.cpp │ ├── lexico.cpp │ ├── next_permute.cpp │ └── permutations.cpp └── sort_map_by_val.cpp ├── PULL_REQUEST_TEMPLATE.md ├── Practice Sessions ├── hashmap.cpp ├── hashmap_chaining.cpp └── temp.cpp ├── README.md └── assets └── ds.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Text editors settings 2 | *.project 3 | *.settings 4 | *.vscode 5 | .vscode/ 6 | *.editorconfig 7 | .DS_Store 8 | .tags 9 | .cph 10 | -------------------------------------------------------------------------------- /Algorithms/BackTracking/Find Longest Possible Route in a Matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int M = 10, N = 10; 4 | int maxpath = INT_MAX; 5 | 6 | int row[] = {0, 0, 1, -1}; 7 | int col[] = {1, -1, 0, 0}; 8 | 9 | bool isValid(int r, int c) 10 | { 11 | return r >= 0 && r < M && c >= 0 && c < N; 12 | } 13 | 14 | int mat[10][10] = 15 | { 16 | {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, 17 | {0, 1, 1, 1, 1, 1, 0, 1, 0, 1}, 18 | {0, 0, 1, 0, 1, 1, 1, 0, 0, 1}, 19 | {1, 0, 1, 1, 1, 0, 1, 1, 0, 1}, 20 | {0, 0, 0, 1, 0, 0, 0, 1, 0, 1}, 21 | {1, 0, 1, 1, 1, 0, 0, 1, 1, 0}, 22 | {0, 0, 0, 0, 1, 0, 0, 1, 0, 1}, 23 | {0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, 24 | {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, 25 | {0, 0, 1, 0, 0, 1, 1, 0, 0, 1}, 26 | }; 27 | 28 | vector> visited(M, vector(N, false)); 29 | 30 | void mazepath(int destx, int desty, int currx, int curry, int currlen) 31 | { 32 | visited[currx][curry] = true; 33 | if (currx == destx && curry == desty) 34 | { 35 | //update ans if needed 36 | if (currlen < maxpath) 37 | { 38 | maxpath = currlen; 39 | } 40 | visited[currx][curry] = false; 41 | return; 42 | } 43 | 44 | for (int i = 0; i < 4; i++) 45 | { 46 | int newx = currx + row[i]; 47 | int newy = curry + col[i]; 48 | 49 | if (mat[newx][newy] == 1 && isValid(newx, newy) && !(visited[newx][newy])) 50 | { 51 | mazepath(destx, desty, newx, newy, currlen + 1); 52 | visited[newx][newy] = false; 53 | } 54 | } 55 | } 56 | 57 | int main() 58 | { 59 | int srcx, srcy; 60 | int destx, desty; 61 | cin >> srcx >> srcy >> destx >> desty; 62 | 63 | mazepath(destx, desty, srcx, srcy, 0); 64 | 65 | cout << maxpath; 66 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/N-Queen.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | bool isSafe(int board[][10], int row, int col, int n) //This function is to check whether queen can be placed safely or not 4 | { 5 | for(int i=0;i=0 && j>=0;i--,j--) 13 | { 14 | if(board[i][j] ==1) 15 | { 16 | return false; 17 | } 18 | } 19 | for(int i=row,j=col;i=0;i++,j--) 20 | { 21 | if(board[i][j] ==1) 22 | { 23 | return false; 24 | } 25 | } 26 | return true; 27 | } 28 | bool nQueen(int board[][10], int col, int n) 29 | { 30 | if(col>=n) 31 | { 32 | for(int i=0;i>n; 61 | bool check = nQueen(board,0,n); //function calling 62 | if(check == false) 63 | cout<<-1; 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Algorithms/BackTracking/Permutations of a given string.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void permutations(string str,int i, int n){ 5 | if(i == n-1){ 6 | cout << str << " "; 7 | return; 8 | } 9 | 10 | for(int j = i+1; j < n; j++){ 11 | swap(str[i],str[j]); 12 | permutations(str,i+1,n); 13 | swap(str[i],str[j]); 14 | } 15 | } 16 | 17 | int main() 18 | { 19 | string str = "ABC"; 20 | 21 | permutations(str, 0, str.length()); 22 | 23 | return 0; 24 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/SELECTION PROBLEMS/combinations.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/BackTracking/SELECTION PROBLEMS/combinations.cpp -------------------------------------------------------------------------------- /Algorithms/BackTracking/SELECTION PROBLEMS/next_permuation.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Solution 3 | { 4 | public: 5 | void nextPermutation(vector &nums) 6 | { 7 | int n = nums.size(); 8 | int sc; 9 | int fc = -1; 10 | for (int i = n - 2; i >= 0; i--) 11 | { 12 | //rightmost element after which a greater elt occurs 13 | if (nums[i + 1] > nums[i]) 14 | { 15 | fc = i; 16 | break; 17 | } 18 | } 19 | 20 | if (fc == -1) 21 | { 22 | sort(nums.begin(), nums.end()); 23 | } 24 | else 25 | { 26 | //rightmost element greater than fc 27 | for (sc = n - 1; sc > fc; sc--) 28 | { 29 | if (nums[sc] > nums[fc]) 30 | { 31 | break; 32 | } 33 | } 34 | swap(nums[fc], nums[sc]); 35 | sort(nums.begin() + fc + 1, nums.end()); 36 | // reverse(nums.begin() + fc + 1, nums.end()); 37 | } 38 | } 39 | }; -------------------------------------------------------------------------------- /Algorithms/BackTracking/SELECTION PROBLEMS/permutations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vector arr; 4 | int n; 5 | void permute1(vector &curr, vector &visited){ 6 | if(curr.size() == n){ 7 | for(auto &i:curr) cout << i << " "; 8 | cout << "\n"; 9 | } 10 | 11 | for(int j = 0; j < n; j++){ 12 | if(visited[j]) continue; 13 | curr.push_back(arr[j]); 14 | visited[j] = 1; 15 | permute1(curr,visited); 16 | curr.pop_back(); 17 | visited[j] = 0; 18 | } 19 | } 20 | 21 | void permute2(vector &curr){ 22 | if(curr.size() == n){ 23 | for(auto &i:curr) cout << i << " "; 24 | cout << "\n"; 25 | } 26 | 27 | for(int j = 0; j < n; j++){ 28 | if(find(curr.begin(),curr.end(),arr[j]) != curr.end()) continue; 29 | curr.push_back(arr[j]); 30 | permute2(curr); 31 | curr.pop_back(); 32 | } 33 | } 34 | 35 | int main() 36 | { 37 | cin >> n; 38 | arr.resize(n); 39 | for (auto &a : arr) cin >> a; 40 | vector curr = {}; 41 | vector visited(n); 42 | permute1(curr, visited); 43 | curr = {}; 44 | permute2(curr); 45 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/SELECTION PROBLEMS/subsets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | void dfs(vector &subset, vector &arr, int i){ 6 | if(i == arr.size()){ 7 | for(int j: subset)printf("%d ",j); 8 | printf("\n"); 9 | return; 10 | } 11 | dfs(subset,arr,i+1); 12 | subset.emplace_back(arr[i]); 13 | dfs(subset,arr,i+1); 14 | subset.pop_back(); 15 | } 16 | 17 | void dfs(vector &subset, vector &arr, int i) 18 | { 19 | if (i == arr.size()){ 20 | for (auto j : subset) 21 | cout << j << " "; 22 | cout << "\n"; 23 | return; 24 | } 25 | subset.emplace_back(arr[i]); 26 | dfs(subset, arr, i + 1); 27 | subset.pop_back(); 28 | dfs(subset, arr, i + 1); 29 | } 30 | 31 | int main(){ 32 | vector arr; 33 | for (auto &a : arr) 34 | cin >> a; 35 | vector subset = {}; 36 | dfs(subset,arr,0); 37 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/binary strings that can be formed from given wildcard pattern.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void printAllCombinations(char pattern[], int idx) 5 | { 6 | if (pattern[idx] == '\0') 7 | { 8 | cout << pattern << endl; 9 | return; 10 | } 11 | 12 | if(pattern[idx] == '?'){ 13 | pattern[idx] = '1'; 14 | printAllCombinations(pattern,idx+1); 15 | pattern[idx] = '?'; 16 | 17 | pattern[idx] = '0'; 18 | printAllCombinations(pattern,idx+1); 19 | pattern[idx] = '?'; 20 | 21 | return; 22 | } 23 | else 24 | printAllCombinations(pattern,idx+1); 25 | 26 | } 27 | 28 | // main function 29 | int main() 30 | { 31 | char pattern[] = "1?11?00?1?"; 32 | 33 | printAllCombinations(pattern, 0); 34 | 35 | return 0; 36 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/determine-pattern-matches-string-not.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // Function to determine if given pattern matches with a string or not 6 | bool match(string str, int i, string pat, int j, unordered_map &map) 7 | { 8 | int n = str.size(); 9 | int m = pat.size(); 10 | 11 | if (n < m) 12 | return false; 13 | 14 | // if both pattern and the string reaches end 15 | if (i == n && j == m) 16 | return true; 17 | 18 | // if either string or pattern reaches end 19 | if (i == n || j == m) 20 | return false; 21 | 22 | //take the curr j as curr 23 | char curr = pat[j]; 24 | if (map.find(curr) != map.end()) 25 | { 26 | string s = map[curr]; 27 | int k = s.size(); 28 | 29 | //i ke baad agle k characters agar s se match na kare to return false 30 | if (str.substr(i, k).compare(s)) 31 | return false; 32 | 33 | return match(str, i + k, pat, j + 1, map); 34 | } 35 | 36 | for (int k = 1; k <= n - i; k++) 37 | { 38 | map[curr] = str.substr(i, k); 39 | 40 | if (match(str, i + k, pat, j + 1, map)) 41 | return true; 42 | 43 | map.erase(curr); 44 | } 45 | 46 | return false; 47 | } 48 | 49 | 50 | // main function 51 | int main() 52 | { 53 | // input string and pattern 54 | string str = "codesleepcode"; 55 | string pat = "XYX"; 56 | 57 | // create a map to store mappings between the pattern and string 58 | unordered_map map; 59 | 60 | // check for solution 61 | if (match(str, 0, pat, 0, map)) 62 | { 63 | for (auto entry : map) 64 | { 65 | cout << entry.first << ": " << entry.second << endl; 66 | } 67 | } 68 | else 69 | { 70 | cout << "Solution doesn't exist"; 71 | } 72 | 73 | return 0; 74 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/find-combinations-of-elements-satisfies-given-constraints.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // Find all combinations that satisfies given constraints 6 | void findAllCombinations(vector &arr, int elem, int n) 7 | { 8 | if(elem > n){ 9 | for(auto e : arr) 10 | cout << e << " "; 11 | cout << endl; 12 | return; 13 | } 14 | 15 | for(int i = 0; i < 2*n; i++){ 16 | if(arr[i] == -1 && (i+elem+1) < 2*n && arr[i+elem+1] == -1){ 17 | arr[i] = elem; 18 | arr[i+elem+1] = elem; 19 | 20 | findAllCombinations(arr,elem+1,n); 21 | 22 | arr[i] = -1; 23 | arr[i+elem+1] = -1; 24 | } 25 | } 26 | } 27 | 28 | int main() 29 | { 30 | // given number 31 | int n = 7; 32 | 33 | // create a vector of double the size of given number with 34 | // all its elements initialized by -1 35 | vector arr(2*n, -1); 36 | 37 | // start from element 1 38 | int elem = 1; 39 | findAllCombinations(arr, elem, n); 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/find-shortest-path-in-maze.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int M = 10, N = 10; 4 | int minpath = INT_MAX; 5 | 6 | int row[] = {0, 0, 1, -1}; 7 | int col[] = {1, -1, 0, 0}; 8 | 9 | bool isValid(int r, int c) 10 | { 11 | return r >= 0 && r < M && c >= 0 && c < N; 12 | } 13 | 14 | int mat[10][10] = 15 | { 16 | {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, 17 | {0, 1, 1, 1, 1, 1, 0, 1, 0, 1}, 18 | {0, 0, 1, 0, 1, 1, 1, 0, 0, 1}, 19 | {1, 0, 1, 1, 1, 0, 1, 1, 0, 1}, 20 | {0, 0, 0, 1, 0, 0, 0, 1, 0, 1}, 21 | {1, 0, 1, 1, 1, 0, 0, 1, 1, 0}, 22 | {0, 0, 0, 0, 1, 0, 0, 1, 0, 1}, 23 | {0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, 24 | {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, 25 | {0, 0, 1, 0, 0, 1, 1, 0, 0, 1}, 26 | }; 27 | 28 | vector> visited(M, vector(N, false)); 29 | 30 | void mazepath(int destx, int desty, int currx, int curry, int currlen) 31 | { 32 | visited[currx][curry] = true; 33 | if (currx == destx && curry == desty) 34 | { 35 | //update ans if needed 36 | if (currlen < minpath) 37 | { 38 | minpath = currlen; 39 | } 40 | visited[currx][curry] = false; 41 | return; 42 | } 43 | 44 | for (int i = 0; i < 4; i++) 45 | { 46 | int newx = currx + row[i]; 47 | int newy = curry + col[i]; 48 | 49 | if (mat[newx][newy] == 1 && isValid(newx, newy) && !(visited[newx][newy])) 50 | { 51 | mazepath(destx, desty, newx, newy, currlen + 1); 52 | visited[newx][newy] = false; 53 | } 54 | } 55 | } 56 | 57 | int main() 58 | { 59 | int srcx, srcy; 60 | int destx, desty; 61 | cin >> srcx >> srcy >> destx >> desty; 62 | 63 | mazepath(destx, desty, srcx, srcy, 0); 64 | 65 | cout << minpath; 66 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/find-ways-calculate-target-elements-array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int ways(vector arr, int target, int start, int currans, vector ans) 5 | { 6 | 7 | if (currans == target) 8 | { 9 | // cout << currans << " " << target << endl; 10 | for (auto c : ans) 11 | cout << c << " "; 12 | cout << endl; 13 | // ans.clear(); 14 | return 1; 15 | } 16 | 17 | if (start >= arr.size()) 18 | { 19 | return 0; 20 | } 21 | 22 | //exclude curr number 23 | int ex = ways(arr, target, start + 1, currans, ans); 24 | 25 | ans.push_back('+'); 26 | ans.push_back(arr[start]+'0'); 27 | int incp = ways(arr, target, start + 1, currans + arr[start], ans); 28 | ans.pop_back(); 29 | ans.pop_back(); 30 | 31 | ans.push_back('-'); 32 | ans.push_back(arr[start]+'0'); 33 | int incn = ways(arr, target, start + 1, currans - arr[start], ans); 34 | ans.pop_back(); 35 | ans.pop_back(); 36 | 37 | return ex + incp + incn; 38 | } 39 | 40 | int main() 41 | { 42 | int n; 43 | cin >> n; 44 | vector arr(n); 45 | for (int i = 0; i < n; i++) 46 | { 47 | cin >> arr[i]; 48 | } 49 | 50 | int target; 51 | cin >> target; 52 | vector ans = {}; 53 | 54 | cout << " hello " << ways(arr, target, 0, 0, ans); 55 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/generate-list-of-possible-words-from-a-character-matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define M 3 5 | #define N 4 6 | 7 | int row[] = {-1, -1, -1, 0, 1, 0, 1, 1}; 8 | int col[] = {-1, 1, 0, -1, -1, 1, 0, 1}; 9 | 10 | unordered_set ans = {}; 11 | 12 | bool isSafe(int x, int y, bool processed[][N]) 13 | { 14 | return (x >= 0 && x < M) && (y >= 0 && y < N) && 15 | !processed[x][y]; 16 | } 17 | 18 | int findmaxlen(vector words) 19 | { 20 | int maxlen = INT_MIN; 21 | for (auto w : words) 22 | { 23 | int len = w.size(); 24 | maxlen = max(maxlen, len); 25 | } 26 | return maxlen; 27 | } 28 | 29 | bool find(string word, unordered_set dict) 30 | { 31 | for (auto a : dict) 32 | { 33 | if (a == word) 34 | return true; 35 | } 36 | return false; 37 | } 38 | 39 | void findWords(char board[M][N], string foundword, unordered_set dict, bool processed[M][N], int x, int y, int maxlen) 40 | { 41 | if (foundword.size() > maxlen) 42 | return; 43 | if (find(foundword, dict)) 44 | { 45 | ans.insert(foundword); 46 | foundword = ""; 47 | } 48 | 49 | foundword.push_back(board[x][y]); 50 | processed[x][y] = true; 51 | for (int i = 0; i < 8; i++) 52 | { 53 | int newx = x + row[i]; 54 | int newy = y + col[i]; 55 | 56 | if (isSafe(newx, newy, processed)) 57 | { 58 | findWords(board, foundword, dict, processed, newx, newy, maxlen); 59 | } 60 | } 61 | processed[x][y] = false; 62 | foundword.pop_back(); 63 | } 64 | 65 | void searchBoggle(char board[M][N], vector words) 66 | { 67 | bool processed[M][N]{}; 68 | int maxlen = findmaxlen(words); 69 | unordered_set dict; 70 | for (auto w : words) 71 | { 72 | dict.insert(w); 73 | } 74 | string foundword = ""; 75 | for(int i = 0; i < M; i++){ 76 | for(int j = 0; j < N; j++) 77 | findWords(board, foundword, dict, processed, i, j, maxlen); 78 | } 79 | 80 | } 81 | 82 | int main() 83 | { 84 | char board[M][N] = { 85 | {'M', 'S', 'E', 'F'}, 86 | {'R', 'A', 'T', 'D'}, 87 | {'L', 'O', 'N', 'E'}}; 88 | 89 | vector words{"START", "NOTE", "SAND", "STONED"}; 90 | 91 | searchBoggle(board, words); 92 | for (auto a : ans) 93 | { 94 | cout << a << " "; 95 | } 96 | 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /Algorithms/BackTracking/hamiltonian_paths.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct Edge 5 | { 6 | int src; 7 | int dest; 8 | }; 9 | 10 | class Graph 11 | { 12 | public: 13 | vector> adjList; 14 | 15 | Graph(vector &edges, int N) 16 | { 17 | adjList.resize(N); 18 | for (auto e : edges) 19 | { 20 | adjList[e.src].push_back(e.dest); 21 | adjList[e.dest].push_back(e.src); 22 | } 23 | } 24 | }; 25 | 26 | void hamilton(Graph &G,int start,int v,vector &path,vector &visited){ 27 | if(path.size() == v){ 28 | for(auto e : path) 29 | cout << e << " "; 30 | cout << endl; 31 | } 32 | 33 | for(auto dest : G.adjList[start]){ 34 | if(!visited[dest]){ 35 | visited[dest] = true; 36 | path.push_back(dest); 37 | 38 | hamilton(G,dest,v,path,visited); 39 | 40 | visited[dest] = false; 41 | path.pop_back(); 42 | } 43 | } 44 | 45 | 46 | 47 | } 48 | 49 | int main() 50 | { 51 | vector edges; 52 | int v, e; 53 | cin >> v >> e; 54 | for (int i = 0; i < e; i++) 55 | { 56 | int src, dest; 57 | cin >> src >> dest; 58 | Edge e; 59 | e.src = src; 60 | e.dest = dest; 61 | edges.push_back(e); 62 | } 63 | Graph g(edges, v); 64 | 65 | int start = 0; 66 | vector path = {}; 67 | vector visited(v); 68 | hamilton(g,start,v,path,visited); 69 | 70 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/k-partition-problem-print-all-subsets.cpp: -------------------------------------------------------------------------------- 1 | //ID DONT KNOW WHATS WRONG WITH IT 2 | #include 3 | using namespace std; 4 | 5 | bool checksum(vector sumLeft) 6 | { 7 | for (auto e : sumLeft) 8 | if (e != 0) 9 | return false; 10 | 11 | return true; 12 | } 13 | 14 | bool subsetsum(vector sumLeft, int totalbuckets, vector home, vector nums, int n) 15 | { 16 | if (n < 0) 17 | return false; 18 | 19 | if (checksum(sumLeft)) 20 | return true; 21 | 22 | bool res = false; 23 | 24 | //nth item ko har bucket me baari baari daalo 25 | for (int i = 0; i < totalbuckets; i++) 26 | { 27 | if (sumLeft[i] - nums[n] >= 0) 28 | { 29 | 30 | //mark current elt subset 31 | home[n] = i + 1; //kaafi doubtful , isko to backtrack kiya hi nahi 32 | 33 | //add current item to ith bucket 34 | sumLeft[i] -= nums[n]; 35 | 36 | //recur for remaining items 37 | res = subsetsum(sumLeft, totalbuckets, home, nums, n - 1); 38 | 39 | //backtrack 40 | sumLeft[i] += nums[n]; 41 | } 42 | } 43 | 44 | return res; 45 | } 46 | 47 | void partition(vector S, int n, int k) 48 | { 49 | int n = S.size(), sum = 0; 50 | 51 | for (int i = 0; i < n; i++) 52 | sum += S[i]; 53 | 54 | int targetsum = sum / k; 55 | 56 | vector sumLeft(k); 57 | 58 | for (int i = 0; i < k; i++) 59 | { 60 | sumLeft[i] = targetsum; 61 | } 62 | 63 | vector home(n); 64 | 65 | bool res = !(sum % k) && subsetsum(sumLeft, k, home, S, n - 1); 66 | if (!res) 67 | { 68 | cout << "Partition to k subsets with equal sum is not possible"; 69 | return; 70 | } 71 | 72 | //print the k partitions 73 | } 74 | 75 | int main() 76 | { 77 | // Input: set of integers 78 | vector S = {7, 3, 5, 12, 2, 1, 5, 3, 8, 4, 6, 4}; 79 | 80 | // number of items in S 81 | int k = 5; 82 | vector bucket; 83 | int n = S.size(); 84 | 85 | partition(S, n, k); 86 | 87 | return 0; 88 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/kcolor_graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // data structure to store graph edges 4 | struct Edge 5 | { 6 | int src, dest; 7 | }; 8 | 9 | // class to represent a graph object 10 | class Graph 11 | { 12 | public: 13 | // An array of vectors to represent adjacency list 14 | vector> adj; 15 | 16 | // Constructor 17 | Graph(vector const &edges, int N) 18 | { 19 | // resize the vector to N elements of type vector 20 | adj.resize(N); 21 | 22 | // add edges to the undirected graph 23 | for (int i = 0; i < edges.size(); i++) 24 | { 25 | int src = edges[i].src; 26 | int dest = edges[i].dest; 27 | 28 | adj[src].push_back(dest); 29 | adj[dest].push_back(src); 30 | } 31 | } 32 | }; 33 | 34 | // string array to store colors (10-colorable graph) 35 | string COLORS[] = {"", "BLUE", "GREEN", "RED", "YELLOW", "ORANGE", 36 | "PINK", "BLACK", "BROWN", "WHITE", "PURPLE"}; 37 | 38 | bool isValid(Graph const &graph, int clr, int vertex, vector &color) 39 | { 40 | for (auto v : graph.adj[vertex]) 41 | { 42 | if (color[v] == clr) 43 | return false; 44 | } 45 | 46 | return true; 47 | } 48 | 49 | void kColorable(Graph const &graph, vector &color, int k, int v, int N) 50 | { 51 | 52 | if (v == N) 53 | { 54 | for (int v = 0; v < N; v++) 55 | cout << setw(8) << left << COLORS[color[v]]; 56 | cout << endl; 57 | 58 | return; 59 | } 60 | 61 | //color vertex v with all avaialble colors 62 | for (int c = 1; c <= k; c++) 63 | { 64 | if (isValid(graph, c, v, color)) 65 | { 66 | color[v] = c; 67 | 68 | kColorable(graph, color, k, v + 1, N); 69 | 70 | color[v] = 0; 71 | } 72 | } 73 | } 74 | 75 | int main() 76 | { 77 | vector edges = { 78 | {0, 1}, {0, 4}, {0, 5}, {4, 5}, {1, 4}, {1, 3}, {2, 3}, {2, 4}}; 79 | 80 | // Number of vertices in the graph 81 | int N = 6; 82 | 83 | // create a graph from edges 84 | Graph g(edges, N); 85 | 86 | int k = 3; 87 | 88 | vector color(N, 0); 89 | 90 | // print all k-colorable configurations of the graph 91 | kColorable(g, color, k, 0, N); 92 | } -------------------------------------------------------------------------------- /Algorithms/BackTracking/knight.cpp: -------------------------------------------------------------------------------- 1 | 2 | // https://www.youtube.com/watch?v=pwlxQeHchFQ&t=614s 3 | #include 4 | using namespace std; 5 | #define N 5 6 | int row[] = {2, 1, -1, -2, -2, -1, 1, 2, 2}; 7 | int col[] = {1, 2, 2, 1, -1, -2, -2, -1, 1}; 8 | 9 | bool isValid(int x, int y){ 10 | return x >= 0 && x < N && y >= 0 && y < N; 11 | } 12 | 13 | void knight(int x, int y, vector> ans,int moves) 14 | { 15 | ans[x][y] = moves; 16 | if (moves >= N*N) 17 | { 18 | for (int i = 0; i < N; i++) 19 | { 20 | for (int j = 0; j < N; j++) 21 | cout << ans[i][j]; 22 | } 23 | return; 24 | } 25 | 26 | for(int t = 0; t < 8; t++){ 27 | int newx = row[t] + x; 28 | int newy = col[t] + y; 29 | if(isValid(newx,newy) && !(ans[newx][newy])){ 30 | knight(newx,newy,ans,moves+1); 31 | } 32 | } 33 | 34 | ans[x][y] = 0; 35 | } 36 | 37 | int main() 38 | { 39 | int visited[N][N]; 40 | for (int i = 0; i < N; i++) 41 | { 42 | for (int j = 0; j < N; j++) 43 | visited[i][j] = 0; 44 | } 45 | 46 | vector> ans(N, vector(N)); 47 | knight(0, 0, ans,1); 48 | } -------------------------------------------------------------------------------- /Algorithms/Bit Manipulation/1.cpp: -------------------------------------------------------------------------------- 1 | //BIT MANIPULATION BASICS 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | int i; 8 | cin >> i; 9 | int x = 10, f = 0, a = 0; 10 | bool powerOf2, ithBitActive; 11 | 12 | /* Check if x is power of 2? */ 13 | if (__builtin_popcount(x) == 1) 14 | powerOf2 = 1; 15 | else 16 | powerOf2 = 0; 17 | 18 | if (x && !((x & (x - 1)))) 19 | powerOf2 = 1; 20 | else 21 | powerOf2 = 0; 22 | 23 | 24 | 25 | 26 | 27 | 28 | /* Check if ith bit is active or not */ 29 | if (x >> i & 1) 30 | ithBitActive = 1; 31 | else 32 | ithBitActive = 0; 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | /* To make ith bit active (bits current state doesn't matter) */ 42 | 43 | if (!(x >> i & 1)) 44 | x += (1 << i); 45 | // 101 - 0 - 10 46 | // 000 1 00 47 | x |= (1 << i); 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | /* To flip ith bit */ 57 | // 5 -> 101 -> flip -> 00000000000000000000101 | 58 | x ^= (1 << i); 59 | 60 | return 0; 61 | } -------------------------------------------------------------------------------- /Algorithms/Dynamic Programming/0-1Knapsack(DP).cpp: -------------------------------------------------------------------------------- 1 | Space Complexity : O(n^2) 2 | Time Complexity : O(n^2) 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | int main() 8 | { 9 | int t; 10 | cin>>t; 11 | while(t--) 12 | { 13 | int n; 14 | cin>>n; 15 | int w; 16 | cin>>w; 17 | int p[n+1]; 18 | p[0] = 0; 19 | int wt[n+1]; 20 | wt[0] = 0; 21 | for(int i=1;i>p[i]; 24 | } 25 | for(int i=1;i>wt[i]; 28 | } 29 | /*for(int i=1;i 10 | #include 11 | using namespace std; 12 | int minimum(int a,int b,int c) 13 | { 14 | int result = min(min(a,b),c); 15 | return result; 16 | } 17 | int main() 18 | { 19 | int t; 20 | cin>>t; 21 | while(t--) 22 | { 23 | int p,q; 24 | cin>>p>>q; 25 | char s1[p]; 26 | char s2[q]; 27 | cin>>s1>>s2; 28 | //cout< 7 | #include 8 | using namespace std; 9 | int main() 10 | { 11 | int t; 12 | cin>>t; 13 | while(t--) 14 | { 15 | int n; 16 | cin>>n; 17 | if(n==1) 18 | cout<<1<>arr[i]; 29 | } 30 | int max = INT_MIN; 31 | for(int i=1;i 6 | using namespace std; 7 | int main() 8 | { 9 | string s, x; 10 | cin >> s; // Input the string 11 | int n = s.length(), i, j, l; 12 | bool dp[n][n]; // n*n matrix for storing the results of sub-problems. 13 | memset(dp, 0, sizeof(dp)); 14 | for (i = 0; i < n; i++) // substring with length one is always pallindromic 15 | dp[i][i] = 1; 16 | for (i = 0; i < n - 1; i++) // substring of length two having same characters is pallindromic 17 | { 18 | if (s[i] == s[i + 1]) 19 | dp[i][i + 1] = 1; 20 | } 21 | for (l = 3; l <= n; l++) // The value of dp[i][j] is true, if the substring is palindrome, otherwise false. 22 | { 23 | for (i = 0; i < n - l + 1; i++) 24 | { 25 | j = i + l - 1; // Assigning the right index (starting index is i and length is l) 26 | if (s[i] == s[j] && dp[i + 1][j - 1] == 1) // To calculate dp[i][j], check the value of dp[i+1][j-1] and if s[i] is same as s[j] 27 | dp[i][j] = 1; // then we make dp[i][j] true otherwise false 28 | else 29 | dp[i][j] = 0; 30 | } 31 | } 32 | for (i = 0; i < n; i++) 33 | { 34 | for (j = 0; j < n; j++) 35 | { 36 | if (dp[i][j] == 1) 37 | { 38 | l = j - i + 1; // Length= right index-left index+1 39 | if (x.length() < l) // Find the longest substring 40 | x = s.substr(i, l); // x is the substring of length l starting from index i 41 | } 42 | } 43 | } 44 | cout << x; // Output the Longest Pallindromic Substring 45 | } 46 | 47 | /*Time Complexity: O(n^2) 48 | Space Complexity: O(n^2) 49 | */ -------------------------------------------------------------------------------- /Algorithms/Dynamic Programming/matrix_chain_multiplication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int dp[100][100]; 4 | int matrixChainMemoised(int* p, int i, int j) 5 | { 6 | if (i == j) 7 | { 8 | return 0; 9 | } 10 | if (dp[i][j] != -1) 11 | { 12 | return dp[i][j]; 13 | } 14 | dp[i][j] = INT_MAX; 15 | for (int k = i; k < j; k++) 16 | { 17 | dp[i][j] = min(dp[i][j], matrixChainMemoised(p, i, k)+ matrixChainMemoised(p, k + 1, j)+ p[i - 1] * p[k] * p[j]); 18 | } 19 | return dp[i][j]; 20 | } 21 | int MatrixChainOrder(int* p, int n) 22 | { 23 | int i = 1, j = n - 1; 24 | return matrixChainMemoised(p, i, j); 25 | } 26 | 27 | int main() 28 | { 29 | int n; 30 | cin>>n; 31 | 32 | int arr[n]; 33 | for(int i=0;i>arr[i]; 36 | } 37 | memset(dp, -1, sizeof dp); 38 | 39 | cout <<"Minimum number of multiplications is "< 3 | #include 4 | using namespace std; 5 | int t[9][9]; // for memorization 6 | 7 | int rodcut(int price[], int length[],int Max_len, int n) 8 | { 9 | if (n == 0 || Max_len == 0) 10 | { 11 | return 0; 12 | } 13 | if (length[n - 1] <= Max_len) 14 | { 15 | t[n][Max_len] = max(price[n - 1]+ rodcut(price, length, Max_len - length[n - 1], n),rodcut(price, length, Max_len, n - 1)); 16 | } 17 | 18 | else 19 | { 20 | t[n][Max_len]= rodcut(price, length, Max_len, n - 1); 21 | } 22 | 23 | return t[n][Max_len]; 24 | } 25 | 26 | 27 | 28 | int main() 29 | { 30 | int n; 31 | cin>>n; 32 | int price[n]; 33 | int length[n]; 34 | for(int i=0;i>price[i]; 37 | } 38 | for(int i=0;i>length[i]; 41 | } 42 | int maximum=n; 43 | cout<<"Maximum obtained value is :"< 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // Number of vertices in the adjMatrix 7 | #define N 4 8 | 9 | // Recursive Function to print path of given 10 | // vertex u from source vertex v 11 | void printPath(int path[][N], int v, int u) 12 | { 13 | if (path[v][u] == v) 14 | return; 15 | 16 | printPath(path, v, path[v][u]); 17 | cout << path[v][u] << " "; 18 | } 19 | 20 | // Function to print the shortest cost with path 21 | // information between all pairs of vertices 22 | void printSolution(int cost[N][N], int path[N][N]) 23 | { 24 | for (int v = 0; v < N; v++) 25 | { 26 | for (int u = 0; u < N; u++) 27 | { 28 | if (cost[v][u] == INT_MAX) 29 | cout << setw(5) << "inf"; 30 | else 31 | cout << setw(5) << cost[v][u]; 32 | } 33 | cout << endl; 34 | } 35 | 36 | cout << endl; 37 | for (int v = 0; v < N; v++) 38 | { 39 | for (int u = 0; u < N; u++) 40 | { 41 | if (u != v && path[v][u] != -1) 42 | { 43 | cout << "Shortest Path from vertex " << v << 44 | " to vertex " << u << " is (" << v << " "; 45 | printPath(path, v, u); 46 | cout << u << ")" << endl; 47 | } 48 | } 49 | } 50 | } 51 | 52 | // Function to run Floyd-Warshell algorithm 53 | void FloydWarshell(int adjMatrix[][N]) 54 | { 55 | // cost[] and parent[] stores shortest-path 56 | // (shortest-cost/shortest route) information 57 | int cost[N][N], path[N][N]; 58 | 59 | // initialize cost[] and parent[] 60 | for (int v = 0; v < N; v++) 61 | { 62 | for (int u = 0; u < N; u++) 63 | { 64 | // initally cost would be same as weight 65 | // of the edge 66 | cost[v][u] = adjMatrix[v][u]; 67 | 68 | if (v == u) 69 | path[v][u] = 0; 70 | else if (cost[v][u] != INT_MAX) 71 | path[v][u] = v; 72 | else 73 | path[v][u] = -1; 74 | } 75 | } 76 | 77 | // run Floyd-Warshell 78 | for (int k = 0; k < N; k++) 79 | { 80 | for (int v = 0; v < N; v++) 81 | { 82 | for (int u = 0; u < N; u++) 83 | { 84 | // If vertex k is on the shortest path from v to u, 85 | // then update the value of cost[v][u], path[v][u] 86 | 87 | if (cost[v][k] != INT_MAX && cost[k][u] != INT_MAX 88 | && cost[v][k] + cost[k][u] < cost[v][u]) 89 | { 90 | cost[v][u] = cost[v][k] + cost[k][u]; 91 | path[v][u] = path[k][u]; 92 | } 93 | } 94 | 95 | // if diagonal elements become negative, the 96 | // graph contains a negative weight cycle 97 | if (cost[v][v] < 0) 98 | { 99 | cout << "Negative Weight Cycle Found!!"; 100 | return; 101 | } 102 | } 103 | } 104 | 105 | // Print the shortest path between all pairs of vertices 106 | printSolution(cost, path); 107 | } 108 | 109 | // main function 110 | int main() 111 | { 112 | // given adjacency representation of matrix 113 | int adjMatrix[N][N] = 114 | { 115 | { 0, INT_MAX, -2, INT_MAX }, 116 | { 4, 0, 3, INT_MAX }, 117 | { INT_MAX, INT_MAX, 0, 2 }, 118 | { INT_MAX, -1, INT_MAX, 0 } 119 | }; 120 | 121 | // Run Floyd Warshell algorithm 122 | FloydWarshell(adjMatrix); 123 | 124 | return 0; 125 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Bipartite graph/code.cpp: -------------------------------------------------------------------------------- 1 | // https://practice.geeksforgeeks.org/problems/bipartite-graph/1 2 | bool dfs(int G[][MAX], int v, int src, int color, vector &col, vector &visited){ 3 | visited[src] = 1; 4 | col[src] = color; 5 | for(int i = 0; i < v; i++){ 6 | if(G[src][i] == 1){ 7 | int nbr = i; 8 | if(visited[nbr] && col[nbr] == color) return false; 9 | if(visited[nbr]) continue; 10 | if(!dfs(G,v,nbr,!color,col,visited)) return false; 11 | } 12 | } 13 | 14 | return true; 15 | } 16 | 17 | bool isBipartite(int G[][MAX],int V) 18 | { 19 | vector visited(V,0), col(V,-1); 20 | for(int i = 0; i < V; i++){ 21 | if(!visited[i]) 22 | if(!dfs(G,V,i,0,col,visited)) return false; 23 | } 24 | return true; 25 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Bridges/bridge.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/GRAPHS/Bridges/bridge.bin -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Bridges/bridge.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int v, e; 4 | vector g[100]; 5 | vector vis; 6 | 7 | vector> bridges() 8 | { 9 | vector dis(v), low(v); //dis - discovery time, low - earliest possible node from which we can reach this node 10 | int current = 0; 11 | vector> bridges; 12 | function dfs = [&](int src, int par) { 13 | dis[src] = low[src] = ++current; 14 | for (auto dest : g[src]) 15 | { 16 | if (dest == par) 17 | continue; 18 | if (dis[dest]) 19 | { 20 | low[dest] = min(low[dest], low[src]); 21 | } 22 | else 23 | { 24 | dfs(dest, src); 25 | low[src] = min(low[src], low[dest]); 26 | if (low[dest] > low[src]) 27 | { 28 | bridges.emplace_back(src, dest); 29 | } 30 | } 31 | } 32 | }; 33 | 34 | for (int i = 1; i <= v; i++) 35 | if (!dis[i]) 36 | dfs(i, -1); 37 | 38 | return bridges; 39 | } 40 | 41 | int main() 42 | { 43 | string pdfpath = "manvi"; 44 | cout << "the Report is in Path: " + pdfpath + "saved, do you want to open it"; 45 | cin >> v >> e; 46 | vis.resize(v + 1); 47 | for (auto i = 0; i < e; i++) 48 | { 49 | int u, v; 50 | cin >> u >> v; 51 | g[u].emplace_back(v); 52 | g[v].emplace_back(u); 53 | } 54 | return 0; 55 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Cycle Detection/Directed Graph/dfs.cpp: -------------------------------------------------------------------------------- 1 | const int N = 10001; 2 | vector visited(N); 3 | 4 | bool dfs(vector g[], int src, int parent){ 5 | visited[src] = 1; 6 | for(auto dest : g[src]){ 7 | if(visited[dest] == 2) continue; 8 | if(visited[dest] == 1) return true; 9 | if(dfs(g,dest,src)) return true; 10 | } 11 | visited[src] = 2; 12 | return false; 13 | } 14 | 15 | bool isCyclic(vector g[], int v) 16 | { 17 | fill(visited.begin(),visited.end(),0); 18 | for(int i = 0; i < v; i++) 19 | if(!visited[i]){ 20 | bool cycle = dfs(g,i,-1); 21 | if(cycle) return true; 22 | } 23 | return false; 24 | 25 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Cycle Detection/Undirected Graph/dfs.cpp: -------------------------------------------------------------------------------- 1 | const int N = 10001; 2 | vector visited(N); 3 | 4 | bool dfs(vector g[], int src, int parent){ 5 | 6 | visited[src] = 1; 7 | for(auto dest : g[src]){ 8 | if(visited[dest] && dest != parent) return true; 9 | if(visited[dest]) continue; 10 | if(dfs(g,dest,src)) return true; 11 | } 12 | return false; 13 | } 14 | 15 | bool isCyclic(vector g[], int v) 16 | { 17 | fill(visited.begin(),visited.end(),0); 18 | for(int i = 0; i < v; i++) 19 | if(!visited[i]){ 20 | bool cycle = dfs(g,i,-1); 21 | if(cycle) return true; 22 | } 23 | return false; 24 | 25 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Cycle Detection/Undirected Graph/dsu.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/GRAPHS/Cycle Detection/Undirected Graph/dsu.cpp -------------------------------------------------------------------------------- /Algorithms/GRAPHS/DSU/dsu.cpp: -------------------------------------------------------------------------------- 1 | /*------------------------------------------NAIVE------------------------------------------------------*/ 2 | 3 | void make_set(int v) // Time - O(1) 4 | { 5 | parent[v] = v; 6 | } 7 | 8 | int find_set(int v) // Time O(n) 9 | { 10 | if (v == parent[v]) 11 | return v; 12 | return find_set(parent[v]); 13 | } 14 | 15 | void union_sets(int a, int b) // Time - O(n) 16 | { 17 | a = find_set(a); 18 | b = find_set(b); 19 | if (a != b) 20 | parent[b] = a; 21 | } 22 | 23 | /*-------------------------Path compression optimization - for speeding up find_set------------------------------------------------------*/ 24 | /* 25 | If we call find_set(v) for some vertex v, we actually find the representative p 26 | for all vertices that we visit on the path between v and the actual representative p. 27 | The trick is to make the paths for all those nodes shorter, 28 | by setting the parent of each visited vertex directly to p. 29 | */ 30 | 31 | int find_set(int v) 32 | { //time complexity O(logn) per call on average 33 | if (v == parent[v]) 34 | return v; 35 | return parent[v] = find_set(parent[v]); 36 | } 37 | 38 | /*-------------------------Union by size / rank - change the union_set operation------------------------------------------------------*/ 39 | 40 | /* 41 | We will change which tree gets attached to the other one. 42 | In the native implementation the second tree always got attached to the first one. 43 | In practice that can lead to trees containing chains of length O(n). 44 | With this optimization we will avoid this by choosing very carefully which tree gets attached. 45 | 46 | In the first approach we use the size of the trees as rank, 47 | and in the second one we use the depth of the tree (more precisely, the upper bound on the tree depth, 48 | because the depth will get smaller when applying path compression). 49 | 50 | In both approaches the essence of the optimization is the same: 51 | we attach the tree with the lower rank to the one with the bigger rank. 52 | */ 53 | 54 | /*-------------------------------Union by size------------------------------------------------------*/ 55 | void make_set(int v) 56 | { 57 | parent[v] = v; 58 | size[v] = 1; 59 | } 60 | 61 | void union_sets(int a, int b) 62 | { 63 | a = find_set(a); 64 | b = find_set(b); 65 | if (a != b) 66 | { 67 | if (size[a] < size[b]) 68 | swap(a, b); 69 | parent[b] = a; 70 | size[a] += size[b]; 71 | } 72 | } 73 | 74 | /*-------------------------------Union by Rank------------------------------------------------------*/ 75 | void make_set(int v) 76 | { 77 | parent[v] = v; 78 | rank[v] = 0; 79 | } 80 | 81 | void union_sets(int a, int b) 82 | { 83 | a = find_set(a); 84 | b = find_set(b); 85 | if (a != b) 86 | { 87 | if (rank[a] < rank[b]) 88 | swap(a, b); 89 | parent[b] = a; 90 | if (rank[a] == rank[b]) 91 | rank[a]++; 92 | } 93 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Euler Path and Cycle/a.cpp: -------------------------------------------------------------------------------- 1 | /* Euler Cycle 2 | 1. All vertices with non-zero degree are connected. 3 | 2. All vertices have even degree. 4 | */ 5 | 6 | 7 | /*Euler Path 8 | 1. All vertices with non-zero degree are connected. 9 | 2. 0 or 2 vertices have odd degree and all other vertices have even degree. 10 | */ 11 | 12 | 13 | bool Graph::isConnected() { 14 | bool found = 0; 15 | bool visited[V]; 16 | for(int i = 0; i < V; i++) visited[i] = 0; 17 | 18 | int i; 19 | for(i = 0; i < V; i++) 20 | if(adj[i].size() != 0) break; 21 | 22 | if(i == V) return 1; 23 | 24 | DFSUtil(i,visited); 25 | 26 | //check if everything is visited 27 | for(int i = 0; i < V; i++) 28 | if(!visited[i] && adj[i].size() > 1) return 0; 29 | 30 | return 1; 31 | } 32 | 33 | int Graph::isEulerian(){ 34 | if(!isConnected()) return 0; 35 | 36 | int odd = 0; 37 | for(int i = 0; i < V; i++) 38 | if(adj[i].size() & 1) odd++; 39 | 40 | if(odd == 0) return 2; //cycle 41 | if(odd == 2) return 1; //path 42 | return 0; //none 43 | 44 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Hamiltonian Path and cycle/a.cpp: -------------------------------------------------------------------------------- 1 | 2 | void hamiltonianCycle(int N, vector > &graph, unordered_set &visited, int src, string psf, int osrc) { 3 | if(visited.size() == N-1){ 4 | cout << psf; 5 | bool cycle = false; 6 | for(auto nbr : graph[src]){ 7 | if(nbr == osrc){ 8 | cycle = true; 9 | break; 10 | } 11 | } 12 | if(cycle) cout << "*"; 13 | else cout << "."; 14 | } 15 | 16 | visited.insert(src); 17 | for(auto nbr : graph[src]){ 18 | if(visited.find(nbr) == visited.end()){ 19 | hamiltonianCycle(N,graph,visited,nbr,psf + to_string(nbr),osrc); 20 | } 21 | } 22 | visited.erase(src); 23 | } 24 | -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Longest Path in a DAG/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 110; 4 | int indegree[N][N]; 5 | int length[N][N]; 6 | int arr[N][N]; 7 | int dx[] = {1, -1, 0, 0}; 8 | int dy[] = {0, 0, 1, -1}; 9 | int m, n, ans; 10 | 11 | bool valid(int a, int b) 12 | { 13 | return a >= 0 && a < n && b >= 0 && b < m; 14 | } 15 | 16 | int main() 17 | { 18 | cin >> m >> n; 19 | for (int i = 0; i < m; i++) 20 | for (int j = 0; j < n; j++) cin >> arr[i][j]; 21 | for (int i = 0; i < m; i++) { 22 | for (int j = 0; j < m; j++) { 23 | for (int k = 0; k < 4; k++) { 24 | int newi = i + dx[k]; 25 | int newj = j + dy[k]; 26 | if(!valid(newi,newj)) continue; 27 | if (arr[newi][newj] == arr[i][j] + 1) indegree[newi][newj]++; 28 | } 29 | } 30 | } 31 | queue> q; 32 | 33 | for (int i = 0; i < n; i++) 34 | for (int j = 0; j < n; j++) if (indegree[i] == 0) q.emplace(i, j), length[i][j] = 1; 35 | 36 | while(q.size()) 37 | { 38 | auto front = q.front(); 39 | q.pop(); 40 | int i = front.first, j = front.second; 41 | ans = max(ans,length[i][j]); 42 | for(int k = 0; k < 4; k++) 43 | { 44 | int newi = i + dx[k], newj = j + dy[k]; 45 | if(!valid(newi, newj)) continue; 46 | if(arr[newi][newj] == arr[i][j] + 1) { 47 | length[i][j]++; 48 | indegree[newi][newj]--; 49 | if(indegree[newi][newj] == 0) q.emplace(newi,newj); 50 | } 51 | } 52 | } 53 | cout << ans << "\n"; 54 | } 55 | -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Minimum Spanning Tree/my_kruskal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vector parent; 4 | struct Edge{ 5 | int src; 6 | int dest; 7 | int wt; 8 | Edge(int src, int dest, int wt){ 9 | this->src = src; 10 | this->dest = dest; 11 | this->wt = wt; 12 | } 13 | }; 14 | vector edges; 15 | 16 | bool comp(const Edge &a, const Edge &b){ 17 | return a.wt < b.wt; 18 | } 19 | 20 | int find_parent(int v){ //constant - max 5,6 steps 21 | if(v == parent[v]) return; 22 | return parent[v] = find_parent(parent[v]); 23 | } 24 | 25 | void union_set(int u, int v){ 26 | u = find_parent(u); 27 | v = find_parent(v); 28 | if(u != v) parent[u] = v; 29 | } 30 | 31 | int main(){ 32 | int v,e; 33 | cin >> v >> e; 34 | parent.resize(v+1); 35 | iota(parent.begin(),parent.end(),0); 36 | 37 | for(int i = 0; i < e; i++){ 38 | int src,dest,wt; 39 | cin >> src >> dest >> wt; 40 | Edge e(src,dest,wt); 41 | edges.emplace_back(e); 42 | } 43 | sort(edges.begin(),edges.end(),comp); //ElogE 44 | vector MST; 45 | long long ans = 0; 46 | for(auto a : edges){ 47 | if(find_parent(a.src) != find_parent(a.dest)) { 48 | MST.emplace_back(a); 49 | ans += a.wt; 50 | union_set(a.src,a.dest); 51 | } 52 | } 53 | cout << ans; 54 | return 0; 55 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Minimum Spanning Tree/prims_CN.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | int findMinVertex(int *weights, bool *visited, int V) 5 | { 6 | int minVertex = -1; 7 | for (int i = 0; i < V; i++) 8 | { 9 | if (visited[i] == false) 10 | { 11 | if (minVertex == -1 || weights[i] < weights[minVertex]) 12 | minVertex = i; 13 | } 14 | } 15 | return minVertex; 16 | } 17 | 18 | void prim(int **adjMatrix, int V) 19 | { 20 | bool *visited = new bool[V]; 21 | int *parents = new int[V]; 22 | int *weights = new int[V]; 23 | 24 | for (int i = 0; i < V; i++) 25 | { 26 | weights[i] = INT_MAX; 27 | visited[i] = false; 28 | } 29 | 30 | parents[0] = -1; 31 | weights[0] = 0; 32 | 33 | for (int i = 0; i < V - 1; i++) 34 | { 35 | //find minVertex 36 | int minVertex = findMinVertex(weights, visited, V); 37 | visited[minVertex] = true; 38 | //explore unvisited neighbours 39 | for (int j = 0; j < V; j++) 40 | { 41 | if (adjMatrix[minVertex][j] != 0 && !visited[j]) 42 | { 43 | if (adjMatrix[minVertex][j] < weights[j]) 44 | { 45 | weights[j] = adjMatrix[minVertex][j]; 46 | parents[j] = minVertex; 47 | } 48 | } 49 | } 50 | } 51 | 52 | //printing 53 | for (int i = 1; i < V; i++) 54 | { 55 | if (parents[i] < i) 56 | cout << parents[i] << " " << i << " " << weights[i] << endl; 57 | else 58 | cout << i << " " << parents[i] << " " << weights[i] << endl; 59 | } 60 | } 61 | 62 | int main() 63 | { 64 | int V, E, tempX, tempY; 65 | cin >> V >> E; 66 | 67 | int **adjMatrix = new int *[V]; 68 | for (int i = 0; i < V; i++) 69 | { 70 | adjMatrix[i] = new int[V]; 71 | for (int j = 0; j < V; j++) 72 | adjMatrix[i][j] = 0; 73 | } 74 | 75 | for (int i = 0; i < E; i++) 76 | { 77 | int s, d, w; 78 | cin >> s >> d >> w; 79 | adjMatrix[s][d] = w; 80 | adjMatrix[d][s] = w; 81 | } 82 | 83 | prim(adjMatrix, V); 84 | 85 | for (int i = 0; i < V; i++) 86 | delete[] adjMatrix[i]; 87 | 88 | delete[] adjMatrix; 89 | 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Single_source_Shortest_distance/bellman_ford.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int v, e; 4 | const int N = 100; 5 | vector> g[N]; 6 | 7 | struct Edge{ 8 | int src; 9 | int dest; 10 | int wt; 11 | Edge(int src, int dest, int wt){ 12 | this->src = src; 13 | this->dest = dest; 14 | this->wt = wt; 15 | } 16 | }; 17 | vector edges; 18 | 19 | int main() 20 | { 21 | cin >> v >> e; 22 | int source = 0; 23 | for (int i = 0; i < e; i++){ 24 | int src, dest, wt; 25 | cin >> src >> dest >> wt; 26 | Edge e(src, dest, wt); 27 | edges.emplace_back(e); 28 | } 29 | //INT_MAX = 2e9 30 | vector distance(v+1,1e9); 31 | distance[source] = 0; 32 | for(int i = 1; i <= v-1; i++){ 33 | for(auto a : edges){ 34 | if(distance[a.dest] > distance[a.src] + a.wt){ 35 | distance[a.dest] = distance[a.src] + a.wt; 36 | } 37 | } 38 | } 39 | 40 | for(auto a : edges){ 41 | if(distance[a.dest] > distance[a.src] + a.wt){ 42 | cout << "Negative Weight Cycle dtected"; 43 | break; 44 | } 45 | } 46 | 47 | return 0; 48 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Single_source_Shortest_distance/dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int v, e; 5 | const int N = 100; 6 | vector> g[N]; 7 | 8 | vector bfs(){ 9 | vector distance(v,INT_MAX); 10 | set> q; //distance, vertex - so that it is automatically sorted by distance 11 | vector visited(v,0); 12 | q.emplace(0,0); 13 | 14 | while(!q.empty()){ 15 | int src = q.begin()->second; 16 | if(visited[src]) continue; 17 | visited[src] = 1; 18 | q.erase(q.begin()); 19 | 20 | for(auto u : g[src]){ 21 | int dest = u.first, wt = u.second; 22 | if(visited[dest]) continue; 23 | 24 | if(distance[dest] > distance[src] + wt){ 25 | distance[dest] = distance[src] + wt; 26 | q.emplace(distance[dest],dest); 27 | } 28 | } 29 | } 30 | return distance; 31 | } 32 | 33 | int main(){ 34 | cin >> v >> e; 35 | for(int i = 0; i < e; i++){ 36 | int src,dest,wt; 37 | cin >> src >> dest >> wt; 38 | g[src].emplace_back(dest,wt); 39 | g[dest].emplace_back(src,wt); 40 | } 41 | 42 | auto shortestPaths = bfs(); 43 | for(auto u : shortestPaths) cout << u << " "; 44 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Single_source_Shortest_distance/dijsktra practice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int v,e,src; 4 | vector> g[1000]; 5 | 6 | void dijkstra(){ 7 | set> q; //distance, vertex 8 | vector distance(v+1); 9 | vector visited(v+1); 10 | 11 | distance[src] = 0; 12 | q.emplace(0,src); 13 | 14 | while(!q.empty()){ 15 | auto rem = q.begin(); 16 | int currV = rem->second, currDis = rem->first; 17 | if(visited[currV]) continue; 18 | q.erase(q.begin()); 19 | 20 | visited[currV] = 1; 21 | 22 | for(auto nbr : g[currV]){ 23 | int nbrV = nbr.second, nbrDis = nbr.first; 24 | if(visited[nbrV]) continue; 25 | if(distance[nbrV] > distance[currV] + nbrDis){ 26 | distance[nbrV] = distance[currV] + nbrDis; 27 | q.emplace(distance[nbrV],nbrV); 28 | } 29 | } 30 | 31 | } 32 | 33 | } 34 | 35 | int main(){ 36 | cin >> v >> e >> src; 37 | dijkstra(); 38 | } 39 | -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Topological Sort/dfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct Edge 6 | { 7 | int src, dest; 8 | }; 9 | 10 | class Graph 11 | { 12 | public: 13 | vector> adjList; 14 | 15 | Graph(vector const &edges, int N) 16 | { 17 | adjList.resize(N); 18 | 19 | for (auto &edge : edges) 20 | adjList[edge.src].push_back(edge.dest); 21 | } 22 | }; 23 | 24 | void dfs(Graph &G, int N, int u, vector &visited, vector &departure, int& time) 25 | { 26 | 27 | visited[u] = true; 28 | time++; 29 | 30 | for (auto v : G.adjList[u]) 31 | { 32 | if (!visited[v]) 33 | dfs(G, N, v, visited, departure, time); 34 | } 35 | 36 | departure[time] = u; 37 | time++; 38 | } 39 | 40 | void doTopologicalSort(Graph &G, int N) 41 | { 42 | vector departure(2 * N, -1); 43 | int time = 0; 44 | vector visited(N, false); 45 | 46 | for (int i = 0; i < N; i++) 47 | if (!visited[i]) 48 | dfs(G, N, i, visited, departure, time); 49 | 50 | for (int i = 2 * N - 1; i >= 0; i--) 51 | { 52 | if (departure[i] != -1) 53 | { 54 | cout << departure[i] << " "; 55 | } 56 | } 57 | } 58 | 59 | int main() 60 | { 61 | vector edges = 62 | { 63 | {0, 6}, {1, 2}, {1, 4}, {1, 6}, {3, 0}, {3, 4}, {5, 1}, {7, 0}, {7, 1}}; 64 | 65 | int N = 8; 66 | 67 | Graph graph(edges, N); 68 | 69 | doTopologicalSort(graph, N); 70 | 71 | return 0; 72 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Topological Sort/kahn.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vector topologicalSort(vector> adjList, int n) 4 | { 5 | vector indegree; 6 | for (auto src : adjList){ 7 | for (auto dest : src) 8 | indegree[dest]++; 9 | } 10 | 11 | queue zero_indegree; 12 | for (int i = 0; i < n; i++){ 13 | if (!indegree[i]) 14 | zero_indegree.push(i); 15 | } 16 | 17 | vector ans; 18 | while (!zero_indegree.empty()){ 19 | int u = zero_indegree.front(); 20 | zero_indegree.pop(); 21 | ans.emplace_back(u); 22 | for (int &v : adjList[u]){ 23 | indegree[v]--; 24 | if (!indegree[v]) 25 | zero_indegree.push(v); 26 | } 27 | } 28 | 29 | return ans; 30 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Traversals/BFS/ITERATIVE.CPP: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5; 4 | int v, e; 5 | vector g[N]; 6 | void bfs() 7 | { 8 | vector visited(v, 0); 9 | queue q; 10 | q.push(0); 11 | while (!q.empty()) 12 | { 13 | int front = q.front(); 14 | q.pop(); 15 | for(auto u : g[front]){ 16 | if(visited[u]) continue; 17 | visited[u] = 1; 18 | q.emplace(u); 19 | } 20 | } 21 | } 22 | 23 | int main() { 24 | cin >> v>> e; 25 | for (int i = 0; i < e; i++) { 26 | int src, dest; 27 | cin >> src >> dest; 28 | g[src].emplace_back(dest); 29 | g[dest].emplace_back(src); 30 | } 31 | bfs(); 32 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Traversals/BFS/RECURSIVE.CPP: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // Data structure to store graph edges 7 | struct Edge { 8 | int src, dest; 9 | }; 10 | 11 | // Class to represent a graph object 12 | class Graph 13 | { 14 | public: 15 | // construct a vector of vectors to represent an adjacency list 16 | vector> adjList; 17 | 18 | // Graph Constructor 19 | Graph(vector const &edges, int N) 20 | { 21 | // resize the vector to N elements of type vector 22 | adjList.resize(N); 23 | 24 | // add edges to the undirected graph 25 | for (auto &edge: edges) 26 | { 27 | adjList[edge.src].push_back(edge.dest); 28 | adjList[edge.dest].push_back(edge.src); 29 | } 30 | } 31 | }; 32 | 33 | // Perform BFS recursively on graph 34 | void recursiveBFS(Graph const &graph, queue &q, 35 | vector &discovered) 36 | { 37 | if (q.empty()) 38 | return; 39 | 40 | // pop front node from queue and print it 41 | int v = q.front(); 42 | q.pop(); 43 | cout << v << " "; 44 | 45 | // do for every edge (v -> u) 46 | for (int u : graph.adjList[v]) 47 | { 48 | if (!discovered[u]) 49 | { 50 | // mark it discovered and push it into queue 51 | discovered[u] = true; 52 | q.push(u); 53 | } 54 | } 55 | 56 | recursiveBFS(graph, q, discovered); 57 | } 58 | 59 | // Recursive C++ implementation of Breadth first search 60 | int main() 61 | { 62 | // vector of graph edges as per above diagram 63 | vector edges = { 64 | {1, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}, {5, 9}, 65 | {5, 10}, {4, 7}, {4, 8}, {7, 11}, {7, 12} 66 | // vertex 0, 13 and 14 are single nodes 67 | }; 68 | 69 | // Number of nodes in the graph 70 | int N = 15; 71 | 72 | // create a graph from edges 73 | Graph graph(edges, N); 74 | 75 | // stores vertex is discovered or not 76 | vector discovered(N, false); 77 | 78 | // create a queue used to do BFS 79 | queue q; 80 | 81 | // Do BFS traversal from all undiscovered nodes to 82 | // cover all unconnected components of graph 83 | for (int i = 0; i < N; i++) { 84 | if (discovered[i] == false) 85 | { 86 | // mark source vertex as discovered 87 | discovered[i] = true; 88 | 89 | // push source vertex into the queue 90 | q.push(i); 91 | 92 | // start BFS traversal from vertex i 93 | recursiveBFS(graph, q, discovered); 94 | } 95 | } 96 | 97 | return 0; 98 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Traversals/DFS/iterative.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // data structure to store graph edges 7 | struct Edge { 8 | int src, dest; 9 | }; 10 | 11 | // class to represent a graph object 12 | class Graph 13 | { 14 | public: 15 | // construct a vector of vectors to represent an adjacency list 16 | vector> adjList; 17 | 18 | // Graph Constructor 19 | Graph(vector const &edges, int N) 20 | { 21 | // resize the vector to N elements of type vector 22 | adjList.resize(N); 23 | 24 | // add edges to the undirected graph 25 | for (auto &edge: edges) 26 | { 27 | adjList[edge.src].push_back(edge.dest); 28 | adjList[edge.dest].push_back(edge.src); 29 | } 30 | } 31 | }; 32 | 33 | // Perform iterative DFS on graph g starting from vertex v 34 | void iterativeDFS(Graph const &graph, int v, vector &discovered) 35 | { 36 | // create a stack used to do iterative DFS 37 | stack stack; 38 | 39 | // push the source node into stack 40 | stack.push(v); 41 | 42 | // run till stack is not empty 43 | while (!stack.empty()) 44 | { 45 | // Pop a vertex from stack 46 | v = stack.top(); 47 | stack.pop(); 48 | 49 | // if the vertex is already discovered yet, 50 | // ignore it 51 | if (discovered[v]) 52 | continue; 53 | 54 | // we will reach here if the popped vertex v 55 | // is not discovered yet. We print it and process 56 | // its undiscovered adjacent nodes into stack 57 | discovered[v] = true; 58 | cout << v << " "; 59 | 60 | // do for every edge (v -> u) 61 | // we're using reverse iterator (Why?) 62 | for (auto it = graph.adjList[v].rbegin(); 63 | it != graph.adjList[v].rend(); ++it) 64 | { 65 | int u = *it; 66 | if (!discovered[u]) 67 | stack.push(u); 68 | } 69 | } 70 | } 71 | 72 | // Depth First Search (DFS) Iterative Implementation 73 | int main() 74 | { 75 | // vector of graph edges as per above diagram 76 | vector edges = { 77 | // Notice that node 0 is unconnected node 78 | {1, 2}, {1, 7}, {1, 8}, {2, 3}, {2, 6}, {3, 4}, 79 | {3, 5}, {8, 9}, {8, 12}, {9, 10}, {9, 11} 80 | // , {6, 9} // introduce cycle 81 | }; 82 | 83 | // Number of nodes in the graph (0-12) 84 | int N = 13; 85 | 86 | // create a graph from given edges 87 | Graph graph(edges, N); 88 | 89 | // stores vertex is discovered or not 90 | vector discovered(N); 91 | 92 | // Do iterative DFS traversal from all undiscovered nodes to 93 | // cover all unconnected components of graph 94 | for (int i = 0; i < N; i++) 95 | if (discovered[i] == false) 96 | iterativeDFS(graph, i, discovered); 97 | 98 | return 0; 99 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/Traversals/DFS/recursive.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct Edge { 6 | int src, dest; 7 | }; 8 | class Graph 9 | { 10 | public: 11 | vector> adjList; 12 | Graph(vector const &edges, int N) 13 | { 14 | adjList.resize(N); 15 | for (auto &edge: edges) 16 | { 17 | adjList[edge.src].push_back(edge.dest); 18 | adjList[edge.dest].push_back(edge.src); 19 | } 20 | } 21 | }; 22 | 23 | void DFS(Graph const &graph, int v, vector &discovered) 24 | { 25 | discovered[v] = true; 26 | cout << v << " "; 27 | for (int u : graph.adjList[v]) 28 | { 29 | if (!discovered[u]) 30 | DFS(graph, u, discovered); 31 | } 32 | } 33 | 34 | int main() 35 | { 36 | vector edges = { 37 | {1, 2}, {1, 7}, {1, 8}, {2, 3}, {2, 6}, {3, 4}, 38 | {3, 5}, {8, 9}, {8, 12}, {9, 10}, {9, 11} 39 | }; 40 | int N = 13; 41 | Graph graph(edges, N); 42 | 43 | vector discovered(N); 44 | for (int i = 0; i < N; i++) 45 | if (discovered[i] == false) 46 | DFS(graph, i, discovered); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Algorithms/GRAPHS/arr_dept_time_dfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct edge{ 5 | int src,dest; 6 | }; 7 | 8 | class Graph { 9 | public: 10 | vector> adjList; 11 | //constructor 12 | Graph(vector const &edges, int N){ 13 | adjList.resize(N); 14 | for(auto &edge : edges){ 15 | adjList[edge.src].push_back(edge.dest); 16 | } 17 | } 18 | }; 19 | 20 | void dfs(Graph const &graph, int v, vector arrival, vector dept, vector &discovered, int &time) 21 | { 22 | arrival[v] = time++; 23 | discovered[v] = true; 24 | for(auto u : graph.adjList[v]) { 25 | if(!discovered[u]){ 26 | dfs(graph,u,arrival,dept,discovered,time); 27 | } 28 | } 29 | dept[v] = time++; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Algorithms/Others/Stable_Matching.cpp: -------------------------------------------------------------------------------- 1 | /*Given n men and n women, where each person has ranked all members of the opposite sex in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners. When there are no such pairs of people, the set of marriages is deemed stable. 2 | A matching is stable when there does not exist any match (A, B) which both prefer each other to their current partner under the matching.*/ 3 | #include 4 | using namespace std; 5 | 6 | // Number of Men or Women 7 | int N; 8 | 9 | // This function returns true if woman 'w' prefers man 'm1' over man 'm' 10 | bool wPrefersM1OverM(vector> &prefer, int w, int m, int m1) 11 | { 12 | // Check if w prefers m over her current engagment m1 13 | for (int i = 0; i < N; i++) 14 | { 15 | // If m1 comes before m in lisr of w, then w prefers her 16 | // cirrent engagement, don't do anything 17 | if (prefer[w][i] == m1) 18 | return true; 19 | 20 | // If m comes before m1 in w's list, then free her current 21 | // engagement and engage her with m 22 | if (prefer[w][i] == m) 23 | return false; 24 | } 25 | } 26 | 27 | void stableMarriage(vector> &prefer) 28 | { 29 | int size = prefer[0].size(); 30 | vector wPartner(size, -1); 31 | 32 | vector mFree(size, false); 33 | 34 | int freeCount = N; 35 | 36 | // While there are free men 37 | while (freeCount > 0) 38 | { 39 | // Pick the first free man (we could pick any) 40 | int m; 41 | for (m = 0; m < N; m++) 42 | if (mFree[m] == false) 43 | break; 44 | 45 | for (int i = 0; i < N && mFree[m] == false; i++) 46 | { 47 | int w = prefer[m][i]; 48 | 49 | // The woman of preference is free, w and m become partners 50 | if (wPartner[w - N] == -1) 51 | { 52 | wPartner[w - N] = m; 53 | mFree[m] = true; 54 | freeCount--; 55 | } 56 | else // If w is not free 57 | { 58 | // Find current engagement of w 59 | int m1 = wPartner[w - N]; 60 | 61 | // If w prefers m over her current engagement m1, 62 | // then break the engagement between w and m1 and 63 | // engage m with w. 64 | if (wPrefersM1OverM(prefer, w, m, m1) == false) 65 | { 66 | wPartner[w - N] = m; 67 | mFree[m] = true; 68 | mFree[m1] = false; 69 | } 70 | } 71 | } 72 | } 73 | 74 | // Print the solution 75 | cout << " W" << "\t" << "M" << endl; 76 | for (int i = 0; i < N; i++) 77 | cout << " " << i + N << "\t" << wPartner[i] << endl; 78 | } 79 | 80 | // Driver program to test above functions 81 | int main() 82 | { 83 | int testcases; 84 | cin >> testcases; 85 | while (testcases-- > 0) 86 | { 87 | int a; 88 | cin >> a; 89 | N = a; 90 | vector> prefer; 91 | //below is an empty 1D vector 92 | vector one_D_vector(5, 0); 93 | //pushing back the above 1D vector to the 94 | //empty 2D vector each time 95 | for (int i = 0; i < 2 * a; i++) 96 | { 97 | prefer.push_back(one_D_vector); 98 | } 99 | 100 | for (int i = 0; i < 2 * a; i++) 101 | { 102 | for (int j = 0; j < a; j++) 103 | { 104 | int jj; 105 | cin >> jj; 106 | prefer[i][j] = jj; 107 | } 108 | } 109 | 110 | stableMarriage(prefer); 111 | } 112 | 113 | return 0; 114 | } 115 | 116 | /*Sample Input/Output 117 | 1 118 | 4 119 | 7 5 6 4 120 | 5 4 6 7 121 | 4 5 6 7 122 | 4 5 6 7 123 | 0 1 2 3 124 | 0 1 2 3 125 | 0 1 2 3 126 | 0 1 2 3 127 | 128 | Woman Man 129 | 4 2 130 | 5 1 131 | 6 3 132 | 7 0 133 | 134 | time complexity: O(n^2) 135 | space complexity: O(n^2)*/ -------------------------------------------------------------------------------- /Algorithms/Search/Linear search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | int n, i; 7 | cin >> n; 8 | int a[n]; 9 | for (i = 0; i < n; i++) 10 | cin >> a[i]; 11 | int x; 12 | cin >> x; 13 | // To check if x is present in the array 14 | for (i = 0; i < n; i++) 15 | { 16 | if (a[i] == x) // if element is found then break the loop 17 | break; 18 | } 19 | 20 | if (i == n) 21 | cout << "Element not found" << endl; 22 | else 23 | cout << "Element found at index = " << i << endl; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Algorithms/Search/binarySearch.cp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int binarySearch(int *arr,int n,int x){ 4 | int low=0,high=n-1,mid; 5 | while(low<=high){ //we will stop running this loop when low will become greater than high 6 | mid=low+(high-low)/2; 7 | if(x==arr[mid]){ //if value of x become equal to mid value of array then we return mid 8 | return mid; 9 | } 10 | else if(x>n; 22 | cin>>x; //value of number 23 | int arr[n+1]; //array 24 | for(int i=0;i>arr[i]; 26 | } 27 | ans=binarySearch(arr,n,x); 28 | cout<<"The number "< 2 | using namespace std; 3 | 4 | 5 | int ternarySearch(int l, int r, int key, int arr[]) 6 | { 7 | if (l<=r) { 8 | // Finding mid1 and mid2 9 | int mid1 = l + (r - l) / 3; 10 | int mid2 = r - (r - l) / 3; 11 | 12 | // Check if key is present at any mid 13 | if (arr[mid1] == key) { 14 | return mid1; 15 | } 16 | if (arr[mid2] == key) { 17 | return mid2; 18 | } 19 | 20 | // when key not present in any mid 21 | if (key < arr[mid1]) { 22 | 23 | return ternarySearch(l, mid1 - 1, key, arr); 24 | } 25 | else if (key > arr[mid2]) { 26 | return ternarySearch(mid2 + 1, r, key, arr); 27 | } 28 | else { 29 | return ternarySearch(mid1 + 1, mid2 - 1, key, arr); 30 | } 31 | } 32 | 33 | 34 | return -1; // when key not found 35 | } 36 | 37 | int main() 38 | { 39 | 40 | int n; 41 | cin>>n; 42 | int arr[n]; 43 | for(int i=0;i>arr[i]; 45 | int elem; 46 | cin>>elem; 47 | 48 | sort(arr,arr+n); // we sort the array provided 49 | 50 | int res=ternarySearch(0,n-1,elem,arr); 51 | if(res==-1) 52 | cout<<"Element not found"; 53 | else 54 | cout<<"Index of"< 2 | using namespace std; 3 | 4 | //implementing counting sort sorting algorithm 5 | void countingSort(int *input_arr,int n,int range){ 6 | int count_arr[range]; 7 | int output_arr[n]; 8 | // initialize all elements to 0 in count array 9 | for(int i=0;i>n; 35 | int range=10; 36 | int input_arr[n+1]; 37 | for(int i=0;i>input_arr[i]; 39 | } 40 | cout<<"Before sorting: "; 41 | for(int i=0;i 2 | #include 3 | using namespace std; 4 | 5 | class Heap { 6 | vector v; 7 | bool minHeap; 8 | 9 | bool compare(int a, int b){ 10 | if(minHeap == true){ 11 | return a < b; 12 | } 13 | return a > b; 14 | } 15 | 16 | void heapify(int idx){ 17 | //find the left and right children of the idx 18 | int left = 2*idx; 19 | int right = 2*idx + 1; 20 | 21 | //compare 22 | int last_idx = v.size() - 1; 23 | int min_idx = idx; 24 | 25 | //if left exists and _ 26 | if(left <= last_idx && compare(v[left],v[min_idx]) ){ 27 | min_idx = left; 28 | } 29 | //similarly for right 30 | if(right <= last_idx && compare(v[right],v[min_idx] ) ){ 31 | min_idx = right; 32 | } 33 | 34 | //recuresive and base case 35 | if(min_idx != idx){ 36 | swap( v[min_idx],v[idx] ); 37 | heapify(min_idx); 38 | } 39 | } 40 | public: 41 | //Constructor 42 | Heap(int default_size = 10, bool type = true) { //these are the default parameters 43 | v.reserve(default_size); //vector size defined, example if it is 10, it will not expand before the vector is filled upto 10 elements 44 | minHeap = type; //if true -> minheap, if false -> maxHeap 45 | //block the 0th index 46 | v.push_back(-1); 47 | } 48 | 49 | //Insertion in heap 50 | void push(int d){ 51 | //1. Insert the element at the end of the vector 52 | v.push_back(d); 53 | 54 | //2. Comparison 55 | //the index of the element inserted -> idx 56 | int idx = v.size() - 1; 57 | //parent of this index = idx/2 58 | int parent = idx/2; 59 | 60 | //keep pushing to the top till you reach the root node OR stop midway because current element is already greater (in case of minheap) than the parent 61 | while(idx > 1 && compare(v[idx],v[parent])){ 62 | swap(v[idx],v[parent]); 63 | //update 64 | idx = parent; 65 | parent = parent/2; 66 | } 67 | } 68 | 69 | bool empty(){ 70 | return v.size() == 1; //because we blocked the 0th postion so size should atleast be 2, size =1 1 means heap is empty 71 | } 72 | 73 | int top(){ //get function 74 | return v[1]; 75 | } 76 | 77 | void pop(){ 78 | //step 1. swap v[1] (root) and v[last] 79 | int last = v.size() - 1; 80 | swap(v[1] , v[last]); 81 | //step 2. remove the last node 82 | v.pop_back(); 83 | //step 3. restore the heap using heapify function 84 | heapify(1); // start from the root node 85 | } 86 | }; 87 | 88 | int main(){ 89 | //give some heap size and type(minheap / maxheap) 90 | Heap h; //by default size = 10, type = minheap(by default) 91 | //to make max heap --> Heap h(10,false); 92 | int n; 93 | cin >> n; 94 | for(int i = 0; i < n; i++){ 95 | int no; 96 | cin >> no; 97 | h.push(no); 98 | } 99 | 100 | //remove all the elements one by one 101 | while(!h.empty()){ 102 | cout << h.top() << " "; 103 | h.pop(); 104 | } 105 | 106 | return 0; 107 | } -------------------------------------------------------------------------------- /Algorithms/Sorting/RadixSort.cpp: -------------------------------------------------------------------------------- 1 | // C++ implementation of Radix Sort 2 | 3 | #include 4 | using namespace std; 5 | 6 | // A utility function to get maximum value in arr[] 7 | int maxValue(int *arr,int n){ 8 | int max=arr[0]; 9 | for(int i=1;imax) 11 | max=arr[i]; 12 | return max; 13 | } 14 | //implementing counting sort sorting algorithm 15 | void countingSort(int *arr,int n,int div){ 16 | int range=10; 17 | // initialize all elements to 0 in count array 18 | int count[range]={0}; 19 | int output[n]; 20 | // to take a count of all elements in the input array 21 | for(int i=0;i0;div*=10){ 45 | countingSort(arr,n,div); 46 | } 47 | } 48 | int main() { 49 | int n; 50 | cin>>n; 51 | int arr[n+1]; 52 | for(int i=0;i>arr[i]; 54 | } 55 | cout<<"Before Sorting: "< 2 | using namespace std; 3 | 4 | void insertionSort(vector &arr) 5 | { 6 | int n = arr.size(); 7 | for (int i = 1; i < n; i++) 8 | { 9 | int hole = i; 10 | int val = arr[hole]; 11 | while (hole > 0 && arr[hole - 1] > val) 12 | { 13 | arr[hole] = arr[hole - 1]; 14 | hole--; 15 | } 16 | arr[hole] = val; 17 | } 18 | } 19 | 20 | int main() 21 | { 22 | int n; 23 | cin >> n; 24 | vector arr(n); 25 | for (auto &i : arr) 26 | cin >> i; 27 | insertionSort(arr); 28 | for (auto &i : arr) 29 | cout << i; 30 | return 0; 31 | } -------------------------------------------------------------------------------- /Algorithms/Sorting/mergeSort.cpp: -------------------------------------------------------------------------------- 1 | void merge(int a[], int si, int ei) 2 | { 3 | int final[1000]; 4 | if (si >= ei) 5 | return; 6 | int mid = (si + ei) / 2; 7 | int i = si; 8 | int j = mid + 1; 9 | int k = 0; 10 | while (i <= mid && j <= ei) 11 | { 12 | if (a[i] < a[j]) 13 | final[k++] = a[i++]; 14 | else 15 | final[k++] = a[j++]; 16 | } 17 | while (i <= mid) 18 | final[k++] = a[i++]; 19 | 20 | while (j <= ei) 21 | final[k++] = a[j++]; 22 | 23 | for (i = si; i <= ei; i++) 24 | { 25 | a[i] = final[i - si]; 26 | } 27 | } 28 | 29 | void mergesort(int a[], int si, int ei) 30 | { 31 | if (si >= ei) 32 | return; 33 | int mid = (si + ei) / 2; 34 | mergesort(a, si, mid); 35 | mergesort(a, mid + 1, ei); 36 | merge(a, si, ei); 37 | } 38 | 39 | void mergeSort(int a[], int n) 40 | { 41 | mergesort(a, 0, n - 1); 42 | } 43 | -------------------------------------------------------------------------------- /Algorithms/Sorting/quickSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int partitionArray(int input[], int start, int end) 4 | { 5 | // Chose pivot 6 | int pivot = input[start]; 7 | // Count elements smaller than pivot and swap 8 | int count = 0; 9 | for (int i = start + 1; i <= end; i++) 10 | { 11 | if (input[i] <= pivot) 12 | count++; 13 | } 14 | int pivotIndex = start + count; 15 | int temp = input[start]; 16 | input[start] = input[pivotIndex]; 17 | input[pivotIndex] = temp; 18 | 19 | // ensure left half contains elements smaller than pivot // and right half larger 20 | int i = start, j = end; 21 | while (i < pivotIndex && j > pivotIndex) 22 | { 23 | while (input[i] <= pivot) 24 | i++; 25 | while (input[j] > pivot) 26 | j--; 27 | if (i < pivotIndex && j > pivotIndex) 28 | { 29 | int temp = input[i]; 30 | input[i] = input[j]; 31 | input[j] = temp; 32 | i++; 33 | j--; 34 | } 35 | } 36 | return pivotIndex; 37 | } 38 | 39 | void quickSort(int input[], int start, int end) 40 | { 41 | if (start >= end) 42 | return; 43 | int pivotIndex = partitionArray(input, start, end); 44 | quickSort(input, start, pivotIndex - 1); 45 | quickSort(input, pivotIndex + 1, end); 46 | } 47 | 48 | void quickSort(int input[], int n) 49 | { 50 | quickSort(input, 0, n - 1); 51 | } -------------------------------------------------------------------------------- /Algorithms/Sorting/selectionSort.cpp: -------------------------------------------------------------------------------- 1 | // arr - input array 2 | // n - size of array 3 | void SelectionSort(int arr[], int n) 4 | { 5 | int min_i; 6 | 7 | for (int i = 0; i < n; i++) 8 | { 9 | min_i = i; 10 | for (int j = i + 1; j < n; j++) 11 | { 12 | if (arr[j] < arr[min_i]) 13 | min_i = j; 14 | } 15 | int temp = arr[i]; 16 | arr[i] = arr[min_i]; 17 | arr[min_i] = temp; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Algorithms/String Matching/Z-algo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector calZ(string s){ 5 | int n = 0; 6 | vector z(n,0); 7 | for(int i = 1, l = 0, r = 0; i < n; i++){ 8 | if(i >= r) z[i] = min(r-i+1,z[i-l]); 9 | while(i+z[i] < n && s[z[i]] == s[i+z[i]]) z[i]++; 10 | if(i+z[i]-1 > r) l = i, r = i + z[i] - 1; 11 | } 12 | return z; 13 | } 14 | 15 | int main(){ 16 | 17 | } -------------------------------------------------------------------------------- /Algorithms/String Matching/kmp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector calculateLPS(string pat) 5 | { 6 | int n = pat.size(); 7 | vector LPS(n); 8 | LPS[0] = 0; 9 | int j = 1, i = 0; 10 | while (i < n && j < n) 11 | { 12 | if (pat[i] == pat[j]) 13 | { 14 | LPS[j] = i + 1; 15 | i++; 16 | j++; 17 | } 18 | else 19 | { 20 | if (i != 0) 21 | i = LPS[i - 1]; 22 | else 23 | { 24 | LPS[j] = 0; 25 | j++; 26 | } 27 | } 28 | } 29 | 30 | return LPS; 31 | } 32 | 33 | int KMPSearch(string pat, string txt) 34 | { 35 | vector LPS = calculateLPS(pat); 36 | //LPS[i] = where to start mathcing in pat after a mismatch at pos i+1 37 | int i = 0, j = 0; 38 | int n = txt.size(), m = pat.size(); 39 | while (i < n) 40 | { 41 | if (txt[i] == pat[j]) 42 | { 43 | i++, j++; 44 | } 45 | else 46 | { 47 | if (j > 0) 48 | j = LPS[j - 1]; 49 | else 50 | i++; 51 | } 52 | 53 | if (j == m) 54 | return (i - j); 55 | } 56 | 57 | return -1; 58 | } 59 | int main() 60 | { 61 | string txt = "hello"; 62 | string pat = "ll"; 63 | cout << "Found at " << KMPSearch(pat, txt); 64 | return 0; 65 | } -------------------------------------------------------------------------------- /Algorithms/TREES/BST/inorder_pred.cpp: -------------------------------------------------------------------------------- 1 | class Solution 2 | { 3 | public: 4 | //recursion 5 | int recursion(int l, int r) 6 | { 7 | if (l >= r) 8 | return 1; 9 | int count = 0; 10 | for (int root = l; root <= r; root++) 11 | { 12 | count += recursion(l, root - 1) * recursion(root + 1, r); 13 | } 14 | return count; 15 | } 16 | 17 | vector> memo(n + 1, vector(n + 1, -1)); 18 | 19 | //memo 20 | int memo(n) 21 | { 22 | if () 23 | } 24 | 25 | int numTrees(int n) 26 | { 27 | // return recursion(1,n); 28 | return memo(n); 29 | } 30 | }; -------------------------------------------------------------------------------- /Algorithms/TREES/BST/inorder_suc.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/TREES/BST/inorder_suc.cpp -------------------------------------------------------------------------------- /Algorithms/TREES/LCA/Naive_1.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/TREES/LCA/Naive_1.cpp -------------------------------------------------------------------------------- /Algorithms/TREES/LCA/Naive_2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/TREES/LCA/Naive_2.cpp -------------------------------------------------------------------------------- /Algorithms/TREES/LCA/RMQ.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/TREES/LCA/RMQ.cpp -------------------------------------------------------------------------------- /Algorithms/TREES/LCA/nary_naive.cpp: -------------------------------------------------------------------------------- 1 | /* Program to find LCA of n1 and n2 using one DFS on 2 | the Tree */ 3 | #include 4 | using namespace std; 5 | 6 | // Maximum number of nodes is 100000 and nodes are 7 | // numbered from 1 to 100000 8 | #define MAXN 100001 9 | 10 | vector tree[MAXN]; 11 | int path[3][MAXN]; // storing root to node path 12 | 13 | // storing the path from root to node 14 | //1, 0, 1, 1, a, flag 15 | //1, 0, 2, 1, b, flag 16 | void dfs(int cur, int prev, int pathNumber, int ptr, 17 | int node, bool &flag) 18 | { 19 | for (int i = 0; i < tree[cur].size(); i++) 20 | { 21 | if (tree[cur][i] != prev and !flag) 22 | { 23 | // pushing current node into the path 24 | path[pathNumber][ptr] = tree[cur][i]; 25 | if (tree[cur][i] == node) 26 | { 27 | // node found 28 | flag = true; 29 | 30 | // terminating the path 31 | path[pathNumber][ptr + 1] = -1; 32 | return; 33 | } 34 | dfs(tree[cur][i], cur, pathNumber, ptr + 1, 35 | node, flag); 36 | } 37 | } 38 | } 39 | 40 | // This Function compares the path from root to 'a' & root 41 | // to 'b' and returns LCA of a and b. Time Complexity : O(n) 42 | int LCA(int a, int b) 43 | { 44 | // trivial case 45 | if (a == b) 46 | return a; 47 | 48 | // setting root to be first element in path 49 | path[1][0] = path[2][0] = 1; 50 | 51 | // calculating path from root to a 52 | bool flag = false; 53 | dfs(1, 0, 1, 1, a, flag); 54 | 55 | // calculating path from root to b 56 | flag = false; 57 | dfs(1, 0, 2, 1, b, flag); 58 | 59 | // runs till path 1 & path 2 mathches 60 | int i = 0; 61 | while (path[1][i] == path[2][i]) 62 | i++; 63 | 64 | // returns the last matching node in the paths 65 | return path[1][i - 1]; 66 | } 67 | 68 | void addEdge(int a, int b) 69 | { 70 | tree[a].push_back(b); 71 | tree[b].push_back(a); 72 | } 73 | 74 | // Driver code 75 | int main() 76 | { 77 | int n = 8; // Number of nodes 78 | addEdge(1, 2); 79 | addEdge(1, 3); 80 | addEdge(2, 4); 81 | addEdge(2, 5); 82 | addEdge(2, 6); 83 | addEdge(3, 7); 84 | addEdge(3, 8); 85 | 86 | cout << "LCA(4, 7) = " << LCA(4, 7) << endl; 87 | cout << "LCA(4, 6) = " << LCA(4, 6) << endl; 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /Algorithms/TREES/LCA/sparse_matrix_nary.cpp: -------------------------------------------------------------------------------- 1 | // https://www.geeksforgeeks.org/lca-for-general-or-n-ary-trees-sparse-matrix-dp-approach-onlogn-ologn/ -------------------------------------------------------------------------------- /Algorithms/TREES/LCA/sqrt_decom_optimized.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/TREES/LCA/sqrt_decom_optimized.cpp -------------------------------------------------------------------------------- /Algorithms/TREES/LCA/sqrt_decomposition_naive.cpp: -------------------------------------------------------------------------------- 1 | // https://www.geeksforgeeks.org/sqrt-square-root-decomposition-set-2-lca-tree-osqrth-time/ -------------------------------------------------------------------------------- /Algorithms/TREES/LCA/using_parent_pointer.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/TREES/LCA/using_parent_pointer.cpp -------------------------------------------------------------------------------- /Algorithms/TREES/Traversals/Iterative/inorder.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/binary-tree-inorder-traversal/ 2 | 3 | // Definition for a binary tree node. 4 | 5 | #include 6 | struct TreeNode 7 | { 8 | int val; 9 | TreeNode *left; 10 | TreeNode *right; 11 | TreeNode() : val(0), left(nullptr), right(nullptr) {} 12 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 13 | TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 14 | }; 15 | 16 | class Solution 17 | { 18 | public: 19 | vector inorderTraversal(TreeNode *root) 20 | { 21 | if (!root) 22 | return {}; 23 | 24 | stack st; 25 | vector ans; 26 | while (true) 27 | { 28 | if (root) 29 | { 30 | st.emplace(root); 31 | root = root->left; 32 | } 33 | else 34 | { 35 | if (st.empty()) 36 | break; 37 | root = st.top(); 38 | st.pop(); 39 | ans.emplace_back(root->val); 40 | root = root->right; 41 | } 42 | } 43 | return ans; 44 | } 45 | }; -------------------------------------------------------------------------------- /Algorithms/TREES/Traversals/Iterative/postorder.cpp: -------------------------------------------------------------------------------- 1 | vector Solution::postorderTraversal(TreeNode *root) 2 | { 3 | 4 | if (!root) 5 | return {}; 6 | vector ans; 7 | stack st; 8 | st.push(root); 9 | 10 | while (!st.empty()) 11 | { 12 | root = st.top(); 13 | st.pop(); 14 | ans.push_back(root->val); 15 | 16 | if (root->left) 17 | st.push(root->left); 18 | if (root->right) 19 | st.push(root->right); 20 | } 21 | 22 | reverse(ans.begin(), ans.end()); 23 | return ans; 24 | } 25 | -------------------------------------------------------------------------------- /Algorithms/TREES/Traversals/Iterative/postorder_using_1_stacks.cpp: -------------------------------------------------------------------------------- 1 | vector Solution::postorderTraversal(TreeNode *root) 2 | { 3 | 4 | if (!root) 5 | return {}; 6 | vector ans; 7 | stack st; 8 | st.push(root); 9 | 10 | while (!st.empty()) 11 | { 12 | root = st.top(); 13 | st.pop(); 14 | ans.push_back(root->val); 15 | 16 | if (root->left) 17 | st.push(root->left); 18 | if (root->right) 19 | st.push(root->right); 20 | } 21 | 22 | reverse(ans.begin(), ans.end()); 23 | return ans; 24 | } 25 | -------------------------------------------------------------------------------- /Algorithms/TREES/Traversals/Iterative/preorder.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution 13 | { 14 | public: 15 | vector preorderTraversal(TreeNode *root) 16 | { 17 | if (!root) 18 | return {}; 19 | stack st; 20 | st.push(root); 21 | vector ans; 22 | while (!st.empty()) 23 | { 24 | 25 | root = st.top(); 26 | st.pop(); 27 | ans.push_back(root->val); 28 | 29 | if (root->right) 30 | st.push(root->right); 31 | if (root->left) 32 | st.push(root->left); 33 | } 34 | 35 | return ans; 36 | } 37 | }; -------------------------------------------------------------------------------- /Algorithms/TREES/Traversals/bottmo view.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | map> mp; 5 | 6 | void helper(Node* root, int hd, int level){ 7 | if(!root) return; 8 | 9 | if(mp[hd].second <= level) 10 | mp[hd] = {root->data,level}; 11 | 12 | helper(root->left,hd-1,level+1); 13 | helper(root->right,hd+1,level+1); 14 | } 15 | 16 | vector bottomView(Node *root){ 17 | mp.clear(); 18 | vector ans; 19 | helper(root,0, 0); 20 | for(auto it : mp) ans.emplace_back(it.second.first); 21 | 22 | return ans; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Algorithms/TREES/Traversals/top view.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Algorithms/TREES/Traversals/top view.cpp -------------------------------------------------------------------------------- /Algorithms/TREES/Traversals/vertical order traversal.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution 13 | { 14 | public: 15 | unordered_map> mp; 16 | int minhd = INT_MAX, maxhd = INT_MIN; 17 | 18 | void helper(TreeNode *root, int hd) 19 | { 20 | if (!root) 21 | return; 22 | minhd = min(minhd, hd); 23 | maxhd = max(maxhd, hd); 24 | 25 | mp[hd].push_back(root); 26 | helper(root->left, hd - 1); 27 | helper(root->right, hd + 1); 28 | } 29 | 30 | vector> verticalTraversal(TreeNode *root) 31 | { 32 | vector> ans; 33 | for (int i = minhd; i <= maxhd; i++) 34 | ans.emplace_back(mp[i]); 35 | 36 | return ans; 37 | } 38 | }; -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution is fun! :green_heart: 2 | From opening a bug report to creating a pull request: every contribution is appreciated and welcome. If you're planning to implement a new data structure or algorithm create an issue first. 3 | 4 | Please take a moment to review this document in order to make the contribution process easy and effective for everyone involved. 5 | 6 | Happy Contributing :slightly_smiling_face: 7 | 8 | ## Creating Issues 9 | ### Bug Reports 10 | A bug is a _demonstrable problem_ that is caused by the code in the repository. 11 | Good bug reports are extremely helpful, so thanks! 12 | 13 | ### New DS or Algo 14 | Any important new algortihm or Data Structure not already present in the list is welcome. 15 | Do create an issue first for the same and then make the PR. 16 | 17 | ## Pull Requests 18 | 19 | ## :arrow_down: Installation 20 | 21 | - First, fork this repository :fork_and_knife: and follow the given instructions: 22 | 23 | ```bash 24 | # clone the repository to your local machine 25 | $ git clone https://github.com//Data-Structures-and-Algorithms.git 26 | 27 | # navigate to the project's directory and install all the relevant dev-dependencies 28 | $ cd Data-Structures-and-Algorithms 29 | 30 | # add upstream 31 | $ git remote add upstream https://github.com/Manvityagi/Data-Structures-and-Algorithms 32 | 33 | # include all the latest changes from the remote repository 34 | $ git fetch upstream 35 | $ git merge upstream/develop 36 | ``` 37 | 38 | - Once you have made your changes, run the following command: 39 | 40 | ```bash 41 | # add your changes 42 | $ git add . 43 | 44 | # make your commit 45 | $ git commit -m "" 46 | The commit message should be in the format - `Added 'DS/ALGO NAME'` 47 | 48 | #push your changes 49 | git push -u origin master 50 | ``` 51 | 52 | > Think you're ready :grey_question: Make the PR :tropical_drink: -------------------------------------------------------------------------------- /DOCUMENTATION.md: -------------------------------------------------------------------------------- 1 | ## Table of Contents 2 | 3 | ### Data Structures Implementation 4 | 1. [Priority Queue](./DS%20implementations/PRIORITY_QUEUES/) 5 | 2. [Hashmaps](./DS%20implementations/HASHMAPS/) 6 | 3. [Trees](./DS%20implementations/TREES) 7 | 4. [Graphs](./DS%20implementations/GRAPHS/) 8 | 5. [Tries](./DS%20implementations/TRIES/) 9 | 6. [Segment Trees](./DS%20implementations/Segment%20TREES/) 10 | 7. [Fenwick Trees](./DS%20implementations/FENWICK%20TREES) 11 | 8. [Stacks](./DS%20implementations/STACKS) 12 | 9. [Queues](./DS%20implementations/QUEUES) 13 | 10. [Linked List](./DS%20implementations/Linked%20List) 14 | 11. [Queues with linked list](./DS%20implementations/QUEUES/queues_linkedlist) 15 | 12. [Stacks with linked list](./DS%20implementations/STACKS/Stack_linked_list) 16 | 13. [Double Linked List](./DS%20implementations/Linked%20List/Double_linked_list) 17 | 14. [Circular Linked List](./DS%20implementations/Linked%20List/circular_linked_list) 18 | 19 | ### Important Algorithms 20 | 21 | 1. [Sorting Algos](#Sorting-Algos) 22 | 2. [Backtracking](#BackTracking) 23 | 3. [Dynamic Programming](#Dynamic-Programming) 24 | 4. [Graphs](#Graphs) 25 | 5. [String-Matching](#String-Matching) 26 | 6. [Tree Algorithms](#Tree-Algorithms) 27 | 7. [Searching Algorithms](#Searching-Algorithms) 28 | 8. [Others](#Other-Algorithms) 29 | 30 |

Sorting Algos

31 | 32 | 1. [Bubble Sort](./Algorithms/Sorting/bubbleSort.cpp) 33 | 2. [Insertion Sort](./Algorithms/Sorting/insertionSort.cpp) 34 | 3. [Merge Sort](./Algorithms/Sorting/mergeSort.cpp) 35 | 4. [Selection Sort](./Algorithms/Sorting/selectionSort.cpp) 36 | 5. [Quick Sort](./Algorithms/Sorting/quickSort.cpp) 37 | 6. [Counting Sort](./Algorithms/Sorting/CountingSort.cpp) 38 | 7. [Radix Sort](./Algorithms/Sorting/RadixSort.cpp) 39 | 8. [Heap Sort](./Algorithms/Sorting/HeapSort.cpp) 40 | 41 |

BackTracking

42 | 43 | 1. [Selection Problems](./Algorithms/BackTracking/SELECTION%20PROBLEMS) 44 | 2. [Binary strings that can be formed from given wildcard pattern](./Algorithms/BackTracking/binary%20strings%20that%20can%20be%20formed%20from%20given%20wildcard%20pattern.cpp) 45 | 3. [Determine-pattern-matches-string-not](./Algorithms/BackTracking/determine-pattern-matches-string-not.cpp) 46 | 4. [Find Longest Possible Route in a Matrix](./Algorithms/BackTracking/Find%20Longest%20Possible%20Route%20in%20a%20Matrix.cpp) 47 | 5. [Find-combinations-of-elements-satisfies-given-constraints](./Algorithms/BackTracking/find-combinations-of-elements-satisfies-given-constraints.cpp) 48 | 6. [Find-shortest-path-in-maze](./Algorithms/BackTracking/find-shortest-path-in-maze.cpp) 49 | 7. [Find-ways-calculate-target-elements-array](./Algorithms/BackTracking/find-ways-calculate-target-elements-array.cpp) 50 | 8. [Generate-list-of-possible-words-from-a-character-matrix](./Algorithms/BackTracking/generate-list-of-possible-words-from-a-character-matrix.cpp) 51 | 9. [Hamiltonian_paths](./Algorithms/BackTracking/hamiltonian_paths.cpp) 52 | 10. [k-partition-problem-print-all-subsets](./Algorithms/BackTracking/k-partition-problem-print-all-subsets.cpp) 53 | 11. [kcolor_graph](./Algorithms/BackTracking/kcolor_graph.cpp) 54 | 12. [knight](./Algorithms/BackTracking/knight.cpp) 55 | 13. [N-Queen](./Algorithms/BackTracking/N-Queen.cpp) 56 | 14. [Permutations of a given string](./Algorithms/BackTracking/Permutations%20of%20a%20given%20string.cpp) 57 | 58 | 59 |

Dynamic Programming

60 | 61 | 1. [0-1 Knapsack](./Algorithms/Dynamic%20Programming/0-1Knapsack(DP).cpp) 62 | 2. [Edit Distance](./Algorithms/Dynamic%20Programming/EditDistance(DP).cpp) 63 | 3. [Longest Increasing Subsequence](./Dynamic%20Programming/LongestIncSubsequence(DP).cpp) 64 | 4. [Longest Palindromic Substring](./Algorithms/Dynamic%20Programming/LongestPallindromicSubstring(DP).cpp) 65 | 5. [Rod Cutting Problem](./Algorithms/Dynamic%20Programming/rod_cutting(DP).cpp) 66 | 6. [Matrix Chain Multiplication](./Algorithms/Dynamic%20Programming/matrix_chain_mutliplication.cpp) 67 | 68 |

Graphs

69 | 70 | 1. [All Pair Shortest Path ](./Algorithms/GRAPHS/All_pair_shortest_path) 71 | 2. [Bipartite Graph](./Algorithms/GRAPHS/Bipartite%20graph) 72 | 3. [Cycle Detection ](./Algorithms/GRAPHS/Cycle%20Detection) 73 | 4. [DSU](./Algorithms/GRAPHS/DSU) 74 | 5. [Euler Path and Cycle](./Algorithms/GRAPHS/Euler%20Path%20and%20Cycle) 75 | 6. [Hamiltonian Path and Cycle](./Algorithms/GRAPHS/Hamiltonian%20Path%20and%20cycle) 76 | 7. [Longest Path in a DAG](./Algorithms/GRAPHS/Longest%20Path%20in%20a%20DAG) 77 | 8. [Minimum Spanning Tree](./Algorithms/GRAPHS/Minimum%20Spanning%20Tree) 78 | 9. [Single Source Shortest Path](./Algorithms/GRAPHS/Single_source_Shortest_distance) 79 | 10. [Topological Sort](./Algorithms/GRAPHS/Topological%20Sort) 80 | 11. [Traversals](./Algorithms/GRAPHS/Traversals) 81 | 82 |

String Matching

83 | 84 | 1. [KMP Algorithm](./Algorithms/String%20Matching/kmp.cpp) 85 | 2. [Z-algo](./Algorithms/String%20Matching/Z-algo.cpp) 86 | 87 |

Tree Algorithms

88 | 89 | 1. [Traversals](./Algorithms/TREES/Traversals) 90 | 2. [LCA](./Algorithms/TREES/LCA) 91 | 3. [BST](./Algorithms/TREES/BST) 92 | 93 |

Searching Algorithms

94 | 95 | 1. [Binary Search](./Algorithms/Search/binarySearch.cpp) 96 | 2. [Linear search]( ./Algorithms/Search/LinearSearch.cpp) 97 | 3. [Ternary Search]( ./Algorithms/Search/ternarySearch.cpp) 98 | 99 |

Other Algorithms

100 | 101 | 1. [Stable Matching]( ./Algorithms/Others/Stable_Matching.cpp) 102 | -------------------------------------------------------------------------------- /DS implementations/FENWICK TREES/index.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void update(int index,int value, int* BIT, int n){ 5 | for(;index <= n; index += (index & (-index)) ) 6 | BIT[index] += value; 7 | } 8 | int query(int index, int* BIT){ 9 | int sum = 0; 10 | for(;index > 0; index -= index&(-index)) 11 | sum += BIT[index]; 12 | 13 | return sum; 14 | } 15 | 16 | int main(){ 17 | int n; 18 | int* arr = new int[n+1](); 19 | int* BIT = new int[n+1](); 20 | for(int i = 1; i <= n; i++){ 21 | cin >> arr[i]; 22 | update(i,arr[i],BIT,n); 23 | } 24 | cout << "Sum of first 5 elements " << query(5,BIT); 25 | cout << "Sum of elts from index 2 to index 6 " << query(6,BIT) - query(1,BIT) << endl; 26 | return 0; 27 | 28 | } -------------------------------------------------------------------------------- /DS implementations/GRAPHS/Impl_USING STL/directed_weighted_graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // data structure to store graph edges 6 | struct Edge { 7 | int src, dest, weight; 8 | }; 9 | 10 | typedef pair Pair; 11 | 12 | // class to represent a graph object 13 | class Graph 14 | { 15 | public: 16 | // construct a vector of vectors of Pairs to represent an adjacency list 17 | vector> adjList; 18 | 19 | // Graph Constructor 20 | Graph(vector const &edges, int N) 21 | { 22 | // resize the vector to N elements of type vector 23 | adjList.resize(N); 24 | 25 | // add edges to the directed graph 26 | for (auto &edge: edges) 27 | { 28 | int src = edge.src; 29 | int dest = edge.dest; 30 | int weight = edge.weight; 31 | 32 | // insert at the end 33 | adjList[src].push_back(make_pair(dest, weight)); 34 | 35 | // Uncomment below line for undirected graph 36 | // adjList[dest].push_back(make_pair(src, weight)); 37 | } 38 | } 39 | }; 40 | 41 | // print adjacency list representation of graph 42 | void printGraph(Graph const &graph, int N) 43 | { 44 | for (int i = 0; i < N; i++) 45 | { 46 | // print all neighboring vertices of given vertex 47 | for (Pair v : graph.adjList[i]) 48 | cout << "(" << i << ", " << v.first << 49 | ", " << v.second << ") "; 50 | cout << endl; 51 | } 52 | } 53 | 54 | // Graph Implementation using STL 55 | int main() 56 | { 57 | // vector of graph edges as per above diagram. 58 | // Please note that initialization vector in below format will 59 | // work fine in C++11, C++14, C++17 but will fail in C++98. 60 | vector edges = 61 | { 62 | // (x, y, w) -> edge from x to y having weight w 63 | { 0, 1, 6 }, { 1, 2, 7 }, { 2, 0, 5 }, { 2, 1, 4 }, 64 | { 3, 2, 10 }, { 4, 5, 1 }, { 5, 4, 3 } 65 | }; 66 | 67 | // Number of nodes in the graph 68 | int N = 6; 69 | 70 | // construct graph 71 | Graph graph(edges, N); 72 | 73 | // print adjacency list representation of graph 74 | printGraph(graph, N); 75 | 76 | return 0; 77 | } -------------------------------------------------------------------------------- /DS implementations/GRAPHS/Impl_USING STL/un_directed_graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // data structure to store graph edges 6 | struct Edge { 7 | int src, dest; 8 | }; 9 | 10 | // class to represent a graph object 11 | class Graph 12 | { 13 | public: 14 | // construct a vector of vectors to represent an adjacency list 15 | vector> adjList; 16 | 17 | // Graph Constructor 18 | Graph(vector const &edges, int N) 19 | { 20 | // resize the vector to N elements of type vector 21 | adjList.resize(N); 22 | 23 | // add edges to the directed graph 24 | for (auto &edge: edges) 25 | { 26 | // insert at the end 27 | adjList[edge.src].push_back(edge.dest); 28 | 29 | // Uncomment below line for undirected graph 30 | // adjList[edge.dest].push_back(edge.src); 31 | } 32 | } 33 | }; 34 | 35 | // print adjacency list representation of graph 36 | void printGraph(Graph const& graph, int N) 37 | { 38 | for (int i = 0; i < N; i++) 39 | { 40 | // print current vertex number 41 | cout << i << " --> "; 42 | 43 | // print all neighboring vertices of vertex i 44 | for (int v : graph.adjList[i]) 45 | cout << v << " "; 46 | cout << endl; 47 | } 48 | } 49 | 50 | // Graph Implementation using STL 51 | int main() 52 | { 53 | // vector of graph edges as per above diagram. 54 | // Please note that initialization vector in below format will 55 | // work fine in C++11, C++14, C++17 but will fail in C++98. 56 | vector edges = 57 | { 58 | { 0, 1 }, { 1, 2 }, { 2, 0 }, { 2, 1 }, 59 | { 3, 2 }, { 4, 5 }, { 5, 4 } 60 | }; 61 | 62 | // Number of nodes in the graph 63 | int N = 6; 64 | 65 | // construct graph 66 | Graph graph(edges, N); 67 | 68 | // print adjacency list representation of graph 69 | printGraph(graph, N); 70 | 71 | return 0; 72 | } -------------------------------------------------------------------------------- /DS implementations/GRAPHS/Impl_WITHOUT STL/directed_graph.cpp: -------------------------------------------------------------------------------- 1 | ///////NOT DONE///// 2 | 3 | #include 4 | using namespace std; 5 | 6 | // Data structure to store Adjacency list nodes 7 | struct Node { 8 | int val; 9 | Node* next; 10 | }; 11 | 12 | // Data structure to store graph edges 13 | struct Edge { 14 | int src, dest; 15 | }; 16 | 17 | class Graph 18 | { 19 | // Function to allocate new node of Adjacency List 20 | Node* getAdjListNode(int dest, Node* head) 21 | { 22 | Node* newNode = new Node; 23 | newNode->val = dest; 24 | 25 | // point new node to current head 26 | newNode->next = head; 27 | 28 | return newNode; 29 | } 30 | 31 | int N; // number of nodes in the graph 32 | 33 | public: 34 | 35 | // An array of pointers to Node to represent 36 | // adjacency list 37 | Node **head; 38 | 39 | // Constructor 40 | Graph(Edge edges[], int n, int N) 41 | { 42 | // allocate memory 43 | head = new Node*[N](); 44 | this->N = N; 45 | 46 | // initialize head pointer for all vertices 47 | for (int i = 0; i < N; i++) 48 | head[i] = nullptr; 49 | 50 | // add edges to the directed graph 51 | for (unsigned i = 0; i < n; i++) 52 | { 53 | int src = edges[i].src; 54 | int dest = edges[i].dest; 55 | 56 | // insert in the beginning 57 | Node* newNode = getAdjListNode(dest, head[src]); 58 | 59 | // point head pointer to new node 60 | head[src] = newNode; 61 | 62 | // Uncomment below lines for undirected graph 63 | 64 | /* 65 | newNode = getAdjListNode(src, head[dest]); 66 | 67 | // change head pointer to point to the new node 68 | head[dest] = newNode; 69 | */ 70 | } 71 | } 72 | 73 | // Destructor 74 | ~Graph() { 75 | for (int i = 0; i < N; i++) 76 | delete[] head[i]; 77 | 78 | delete[] head; 79 | } 80 | }; 81 | 82 | // print all neighboring vertices of given vertex 83 | void printList(Node* ptr) 84 | { 85 | while (ptr != nullptr) 86 | { 87 | cout << " -> " << ptr->val << " "; 88 | ptr = ptr->next; 89 | } 90 | cout << endl; 91 | } 92 | 93 | // Graph Implementation in C++ without using STL 94 | int main() 95 | { 96 | // array of graph edges as per above diagram. 97 | Edge edges[] = 98 | { 99 | // pair (x, y) represents edge from x to y 100 | { 0, 1 }, { 1, 2 }, { 2, 0 }, { 2, 1 }, 101 | { 3, 2 }, { 4, 5 }, { 5, 4 } 102 | }; 103 | 104 | // Number of vertices in the graph 105 | int N = 6; 106 | 107 | // calculate number of edges 108 | int n = sizeof(edges)/sizeof(edges[0]); 109 | // cout << "helllo " << n << " " << sizeof(edges) << " " << sizeof(edges[0]) << endl; 110 | // construct graph 111 | Graph graph(edges, n, N); 112 | 113 | // print adjacency list representation of graph 114 | for (int i = 0; i < N; i++) 115 | { 116 | // print given vertex 117 | cout << i << " --"; 118 | 119 | // print all its neighboring vertices 120 | printList(graph.head[i]); 121 | } 122 | 123 | return 0; 124 | } -------------------------------------------------------------------------------- /DS implementations/GRAPHS/Impl_WITHOUT STL/directed_graph.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/DS implementations/GRAPHS/Impl_WITHOUT STL/directed_graph.exe -------------------------------------------------------------------------------- /DS implementations/GRAPHS/Impl_WITHOUT STL/weighted_directed_graph.cpp: -------------------------------------------------------------------------------- 1 | ///////NOT DONE///// 2 | 3 | 4 | #include 5 | using namespace std; 6 | 7 | // Data structure to store Adjacency list nodes 8 | struct Node { 9 | int val, cost; 10 | Node* next; 11 | }; 12 | 13 | // Data structure to store graph edges 14 | struct Edge { 15 | int src, dest, weight; 16 | }; 17 | 18 | class Graph 19 | { 20 | // Function to allocate new node of Adjacency List 21 | Node* getAdjListNode(int value, int weight, Node* head) 22 | { 23 | Node* newNode = new Node; 24 | newNode->val = value; 25 | newNode->cost = weight; 26 | 27 | // point new node to current head 28 | newNode->next = head; 29 | 30 | return newNode; 31 | } 32 | 33 | int N; // number of nodes in the graph 34 | 35 | public: 36 | 37 | // An array of pointers to Node to represent 38 | // adjacency list 39 | Node **head; 40 | 41 | // Constructor 42 | Graph(Edge edges[], int n, int N) 43 | { 44 | // allocate memory 45 | head = new Node*[N](); 46 | this->N = N; 47 | 48 | // initialize head pointer for all vertices 49 | for (int i = 0; i < N; ++i) 50 | head[i] = nullptr; 51 | 52 | // add edges to the directed graph 53 | for (unsigned i = 0; i < n; i++) 54 | { 55 | int src = edges[i].src; 56 | int dest = edges[i].dest; 57 | int weight = edges[i].weight; 58 | 59 | // insert in the beginning 60 | Node* newNode = getAdjListNode(dest, weight, head[src]); 61 | 62 | // point head pointer to new node 63 | head[src] = newNode; 64 | 65 | // Uncomment below lines for undirected graph 66 | 67 | /* 68 | newNode = getAdjListNode(src, weight, head[dest]); 69 | 70 | // change head pointer to point to the new node 71 | head[dest] = newNode; 72 | */ 73 | } 74 | } 75 | 76 | // Destructor 77 | ~Graph() { 78 | for (int i = 0; i < N; i++) 79 | delete[] head[i]; 80 | 81 | delete[] head; 82 | } 83 | }; 84 | 85 | // print all neighboring vertices of given vertex 86 | void printList(Node* ptr, int i) 87 | { 88 | while (ptr != nullptr) 89 | { 90 | cout << "(" << i << ", " << ptr->val 91 | << ", " << ptr->cost << ") "; 92 | 93 | ptr = ptr->next; 94 | } 95 | 96 | cout << endl; 97 | } 98 | 99 | // Graph Implementation in C++ without using STL 100 | int main() 101 | { 102 | // array of graph edges as per above diagram. 103 | Edge edges[] = 104 | { 105 | // (x, y, w) -> edge from x to y having weight w 106 | { 0, 1, 6 }, { 1, 2, 7 }, { 2, 0, 5 }, { 2, 1, 4 }, 107 | { 3, 2, 10 }, { 4, 5, 1 }, { 5, 4, 3 } 108 | }; 109 | 110 | // Number of vertices in the graph 111 | int N = 6; 112 | 113 | // calculate number of edges 114 | int n = sizeof(edges)/sizeof(edges[0]); 115 | 116 | // construct graph 117 | Graph graph(edges, n, N); 118 | 119 | // print adjacency list representation of graph 120 | for (int i = 0; i < N; i++) 121 | { 122 | // print all neighboring vertices of vertex i 123 | printList(graph.head[i], i); 124 | } 125 | 126 | return 0; 127 | } -------------------------------------------------------------------------------- /DS implementations/HASHMAPS/INDEX2.CPP: -------------------------------------------------------------------------------- 1 | // time complexity remains O(1). 2 | 3 | #include 4 | 5 | template 6 | class MapNode 7 | { 8 | public: 9 | string key; 10 | V value; 11 | MapNode *next; 12 | MapNode(string key, V value) 13 | { 14 | this->key = key; 15 | this->value = value; 16 | next = NULL; 17 | } 18 | }; 19 | 20 | template 21 | class HashMap 22 | { 23 | 24 | // Dynamically 25 | MapNode **bucket; 26 | int count; // Number of key value pairs inserted in map 27 | int bucketSize; // Size of bucket Array 28 | 29 | public: 30 | HashMap() 31 | { 32 | bucketSize = 10; 33 | count = 0; 34 | bucket = new MapNode *[bucketSize]; 35 | for (int i = 0; i < bucketSize; i++) 36 | { 37 | bucket[i] = NULL; 38 | } 39 | } 40 | 41 | int size() 42 | { 43 | return count; 44 | } 45 | 46 | // Hash Function 47 | int getBucketIndex(string key) 48 | { 49 | // Hashcode 50 | long hashCode = 0; 51 | long currentFactor = 1; 52 | for (int i = key.size() - 1; i >= 0; i--) 53 | { 54 | hashCode += key[i] * currentFactor; 55 | currentFactor *= 37; 56 | } 57 | // Compress 58 | return hashCode % bucketSize; 59 | } 60 | 61 | V search(string key) 62 | { 63 | 64 | int bucketIndex = getBucketIndex(key); 65 | MapNode *head = bucket[bucketIndex]; 66 | if (head == NULL) 67 | { 68 | // key does not exist 69 | return 0; 70 | } 71 | MapNode *temp = head; 72 | while (temp != NULL) 73 | { 74 | if (temp->key == key) 75 | { 76 | // Found 77 | return temp->value; 78 | } 79 | temp = temp->next; 80 | } 81 | // Key doesn't exist 82 | return 0; 83 | } 84 | 85 | void insert(string key, V value) 86 | { 87 | 88 | int bucketIndex = getBucketIndex(key); 89 | MapNode *head = bucket[bucketIndex]; 90 | if (head == NULL) 91 | { 92 | // key does not exist 93 | MapNode *newNode = new MapNode(key, value); 94 | // Bakwas head = newNode; 95 | bucket[bucketIndex] = newNode; 96 | count++; 97 | } 98 | else 99 | { 100 | MapNode *temp = head; 101 | MapNode *prev = NULL; 102 | while (temp != NULL) 103 | { 104 | if (temp->key == key) 105 | { 106 | // Found -> Override value 107 | temp->value = value; 108 | return; 109 | } 110 | prev = temp; 111 | temp = temp->next; 112 | } 113 | // Insert at End 114 | MapNode *newNode = new MapNode(key, value); 115 | prev->next = newNode; 116 | count++; 117 | } 118 | 119 | double loadFactor = (1.0 * count) / bucketSize; 120 | if (loadFactor >= 0.75) 121 | { 122 | rehash(); 123 | } 124 | } 125 | 126 | void erase(string key) 127 | { 128 | 129 | int bucketIndex = getBucketIndex(key); 130 | MapNode *head = bucket[bucketIndex]; 131 | if (head == NULL) 132 | { 133 | return; 134 | } 135 | MapNode *temp = head; 136 | MapNode *prev = NULL; 137 | while (temp != NULL) 138 | { 139 | if (temp->key == key) 140 | { 141 | if (prev == NULL) 142 | { 143 | bucket[bucketIndex] = temp->next; 144 | } 145 | else 146 | { 147 | prev->next = temp->next; 148 | } 149 | count--; 150 | delete temp; 151 | return; 152 | } 153 | prev = temp; 154 | temp = temp->next; 155 | } 156 | } 157 | 158 | void rehash() 159 | { 160 | 161 | MapNode **temp = bucket; 162 | bucket = new MapNode *[2 * bucketSize]; 163 | 164 | bucketSize = bucketSize * 2; 165 | for (int i = 0; i < bucketSize; i++) 166 | { 167 | bucket[i] = NULL; 168 | } 169 | count = 0; 170 | for (int i = 0; i < bucketSize / 2; i++) 171 | { 172 | MapNode *head = temp[i]; 173 | while (head != NULL) 174 | { 175 | insert(head->key, head->value); 176 | MapNode *temp2 = head; 177 | head = head->next; 178 | delete temp2; 179 | } 180 | } 181 | } 182 | }; 183 | -------------------------------------------------------------------------------- /DS implementations/HASHMAPS/basic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Hashmap{ 5 | int size; 6 | struct node{ 7 | int key; 8 | int value; 9 | node(int key = -1, int value = -1) : key(key), value(value){} 10 | }; 11 | node *arr; 12 | public: 13 | Hashmap(int size = 512){ 14 | this->size = size; 15 | this->arr = new node[size]; 16 | } 17 | 18 | int hash(int key){ 19 | return (key*key)%size; //return index on which given key has to be placed 20 | } 21 | 22 | void add(int key, int value){ 23 | int index = hash(key); 24 | arr[index] = node(key,value); 25 | } 26 | 27 | int get(int key){ 28 | int index = hash(key); 29 | if(arr[index].key == key){ 30 | return arr[index].value; 31 | } 32 | cout << "Collison or Wrong Key\n"; 33 | return -1; 34 | } 35 | 36 | }; 37 | 38 | int main(){ 39 | // Hashmap *H = new Hashmap; 40 | Hashmap H; 41 | H.add(12,100); 42 | H.add(15,200); 43 | cout << H.get(12) << "\n"; 44 | cout << H.get(15) << "\n"; 45 | cout << H.get(2) << "\n"; 46 | 47 | } -------------------------------------------------------------------------------- /DS implementations/HASHMAPS/chaining.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Hashmap{ 5 | int size; 6 | struct node{ 7 | int key; 8 | int value; 9 | node(int key = -1, int value = -1) : key(key), value(value){} 10 | }; 11 | list *arr; 12 | public: 13 | Hashmap(int size = 512){ 14 | this->size = size; 15 | this->arr = new list[size]; 16 | } 17 | 18 | int hash(int key){ 19 | return (key*key)%size; //return index on which given key has to be placed 20 | } 21 | 22 | void add(int key, int value){ 23 | int index = hash(key); 24 | arr[index].emplace_back(key,value); 25 | } 26 | 27 | int get(int key){ 28 | int index = hash(key); 29 | for(auto p : arr[index]){ 30 | if(p.key == key) return p.value; 31 | } 32 | return -1; 33 | } 34 | }; 35 | 36 | int main(){ 37 | // Hashmap *H = new Hashmap; 38 | Hashmap H(5); 39 | H.add(12,100); 40 | H.add(18,200); 41 | cout << H.get(12) << "\n"; 42 | cout << H.get(18) << "\n"; 43 | cout << H.get(2) << "\n"; 44 | 45 | } -------------------------------------------------------------------------------- /DS implementations/HASHMAPS/open_addressing.cpp: -------------------------------------------------------------------------------- 1 | //pending 2 | -------------------------------------------------------------------------------- /DS implementations/HASHMAPS/theory.md: -------------------------------------------------------------------------------- 1 | ### Collision Handling 2 | Since a hash function gets us a small number for a big key, there is possibility that two keys result in same value. The situation where a newly inserted key maps to an already occupied slot in hash table is called collision and must be handled using some collision handling technique. Following are the ways to handle collisions: 3 | 4 | - Chaining: The idea is to make each cell of hash table point to a linked list of records that have same hash function value. Chaining is simple, but requires additional memory outside the table. 5 | 6 | - Open Addressing 7 | Like separate chaining, open addressing is a method for handling collisions. In Open Addressing, all elements are stored in the hash table itself. So at any point, the size of the table must be greater than or equal to the total number of keys (Note that we can increase table size by copying old data if needed). 8 | 9 | Insert(k): Keep probing until an empty slot is found. Once an empty slot is found, insert k. 10 | 11 | Search(k): Keep probing until slot’s key doesn’t become equal to k or an empty slot is reached. 12 | 13 | Delete(k): Delete operation is interesting. If we simply delete a key, then the search may fail. So slots of deleted keys are marked specially as “deleted”. 14 | The insert can insert an item in a deleted slot, but the search doesn’t stop at a deleted slot. 15 | 16 | https://www.geeksforgeeks.org/hashing-set-3-open-addressing/ 17 | 18 | 19 | ### Load Factor 20 | When the total number of items in hashmap goes on increasing keeping the default initial capacity of hashmap 16, At one point of time, 21 | hashmap performance will start degrading and need to increase buckets for improving performance. 22 | Load Factor is a measure, which decides when exactly to increase the hashmap capacity(buckets) to maintain get and put operation complexity of O(1). 23 | Default load factor of Hashmap is 0.75f (i.e 75% of current map size). 24 | You can also say, load factor is a measure "Till what load, hashmap can allow elements to put in it before its capacity is automatically increased" 25 | 26 | When the size of hashmap is changed, the process of re-calculating the hashcode of already placed key-value pair again is known as Rehashing. 27 | Rehashing is done to distribute items across the new length hashmap, so that get and put operation 28 | 29 | Read Closed Hashing from here: 30 | https://www.hackerearth.com/practice/data-structures/hash-tables/basics-of-hash-tables/tutorial/ 31 | -------------------------------------------------------------------------------- /DS implementations/Linked List/Double_linked_list/doublelinkedlist.cpp: -------------------------------------------------------------------------------- 1 | // C++ PROGRAM TO IMPLEMENT DOUBLY LINKED LIST BY TAKING INPUT FROM THE USER 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct node 9 | { 10 | struct node *prev_node; 11 | int info; 12 | struct node *next_node; 13 | }; 14 | 15 | struct node *create_list(struct node *begin); 16 | void display(struct node *begin); 17 | struct node *addtoemptylist(struct node *begin,int data_element); 18 | struct node *addatbeglist(struct node *begin,int data_element); 19 | struct node *addatendlist(struct node *begin,int data_element); 20 | struct node *addafterlist(struct node *begin,int data_element,int item_pos); 21 | struct node *addbeforelist(struct node *begin,int data_element,int item_pos); 22 | struct node *deletenode(struct node *begin,int data_element); 23 | struct node *reverselist(struct node *begin); 24 | 25 | int main() 26 | { 27 | int option,data_element,item_pos; 28 | struct node *begin=NULL; 29 | while(1) 30 | { 31 | cout<<"-------Implementation of Doubly Linked List---------\n"; 32 | cout<<"\n1.Create A New Doubly Linked List\n"; 33 | cout<<"2.Display the Doubly Linked List\n"; 34 | cout<<"3.Add to an Empty Doubly Linked List\n"; 35 | cout<<"4.Add at Starting of the Doubly Linked List\n"; 36 | cout<<"5.Add at Ending\n"; 37 | cout<<"6.Add After a Node\n"; 38 | cout<<"7.Add Before a Node\n"; 39 | cout<<"8.Delete a Node\n"; 40 | cout<<"9.Reverse the Doubly Linked List\n"; 41 | cout<<"10.Exit\n"; 42 | cout<<"Enter your option : "; 43 | cin>>option; 44 | 45 | switch(option) 46 | { 47 | case 1: 48 | begin=create_list(begin); 49 | break; 50 | case 2: 51 | display(begin); 52 | break; 53 | case 3: 54 | cout<<"Enter the element:"; 55 | cin>>data_element; 56 | begin=addtoemptylist(begin,data_element); 57 | break; 58 | case 4: 59 | cout<<"Enter the element:"; 60 | cin>>data_element; 61 | begin=addatbeglist(begin,data_element); 62 | break; 63 | case 5: 64 | cout<<"Enter the element:"; 65 | cin>>data_element; 66 | begin=addatendlist(begin,data_element); 67 | break; 68 | case 6: 69 | cout<<"Enter the element:"; 70 | cin>>data_element; 71 | cout<<"Enter the element after which to insert : "; 72 | cin>>item_pos; 73 | begin=addafterlist(begin,data_element,item_pos); 74 | break; 75 | case 7: 76 | cout<<"Enter the element: "; 77 | cin>>data_element; 78 | cout<<"Enter the element before which to insert : "; 79 | cin>>item_pos; 80 | begin=addbeforelist(begin,data_element,item_pos); 81 | break; 82 | case 8: 83 | cout<<"Enter the element to be Deleted : "; 84 | cin>>data_element; 85 | begin=deletenode(begin,data_element); 86 | break; 87 | case 9: 88 | begin=reverselist(begin); 89 | break; 90 | case 10: 91 | exit(1); 92 | default: 93 | cout<<"Wrong option\n"; 94 | } 95 | } 96 | 97 | return 0; 98 | } 99 | 100 | struct node *create_list(struct node *begin) 101 | { 102 | int i,n,data_element; 103 | cout<<"Enter the number of nodes : "; 104 | cin>>n; 105 | begin=NULL; 106 | if(n==0) 107 | return begin; 108 | cout<<"Enter the element: "; 109 | cin>>data_element; 110 | begin=addtoemptylist(begin,data_element); 111 | 112 | for(i=2;i<=n;i++) 113 | { 114 | cout<<"Enter the element to be inserted : "; 115 | cin>>data_element; 116 | begin=addatendlist(begin,data_element); 117 | } 118 | return begin; 119 | } 120 | 121 | void display(struct node *begin) 122 | { 123 | struct node *p; 124 | if(begin==NULL) 125 | { 126 | cout<<"List is empty\n"; 127 | return; 128 | } 129 | p=begin; 130 | cout<<"List is :\n"; 131 | while(p!=NULL) 132 | { 133 | cout<info<<" "; 134 | p=p->next_node; 135 | } 136 | cout<<"\n"; 137 | } 138 | 139 | struct node *addtoemptylist(struct node *begin,int data_element) 140 | { 141 | struct node *temp; 142 | temp=new struct node; 143 | temp->info=data_element; 144 | temp->prev_node=NULL; 145 | temp->next_node=NULL; 146 | begin=temp; 147 | return begin; 148 | } 149 | struct node *addatbeglist(struct node *begin,int data_element) 150 | { 151 | if(begin==NULL) 152 | { 153 | cout<<"List is empty\n"; 154 | return begin; 155 | } 156 | 157 | struct node *temp; 158 | temp = new struct node; 159 | temp->info=data_element; 160 | temp->prev_node=NULL; 161 | temp->next_node=begin; 162 | begin->prev_node=temp; 163 | begin=temp; 164 | return begin; 165 | } 166 | 167 | struct node *addatendlist(struct node *begin,int data_element) 168 | { 169 | if(begin==NULL) 170 | { 171 | cout<<"List is empty\n"; 172 | return begin; 173 | } 174 | 175 | struct node *temp,*p; 176 | temp=new struct node; 177 | temp->info=data_element; 178 | p=begin; 179 | while(p->next_node!=NULL) 180 | p=p->next_node; 181 | p->next_node=temp; 182 | temp->next_node=NULL; 183 | temp->prev_node=p; 184 | return begin; 185 | } 186 | struct node *addafterlist(struct node *begin,int data_element,int item_pos) 187 | { 188 | struct node *temp,*p; 189 | temp=new struct node; 190 | temp->info=data_element; 191 | p=begin; 192 | while(p!=NULL) 193 | { 194 | if(p->info==item_pos) 195 | { 196 | temp->prev_node=p; 197 | temp->next_node=p->next_node; 198 | if(p->next_node!=NULL) 199 | p->next_node->prev_node=temp; 200 | p->next_node=temp; 201 | return begin; 202 | } 203 | p=p->next_node; 204 | } 205 | cout<info==item_pos) 218 | { 219 | temp = new struct node; 220 | temp->info=data_element; 221 | temp->prev_node=NULL; 222 | temp->next_node=begin; 223 | begin->prev_node=temp; 224 | begin=temp; 225 | return begin; 226 | } 227 | q=begin; 228 | while(q!=NULL) 229 | { 230 | if(q->info==item_pos) 231 | { 232 | temp=new struct node; 233 | temp->info=data_element; 234 | temp->prev_node=q->prev_node; 235 | temp->next_node = q; 236 | q->prev_node->next_node=temp; 237 | q->prev_node=temp; 238 | return begin; 239 | } 240 | q=q->next_node; 241 | } 242 | cout<next_node==NULL) 255 | if(begin->info==data_element) 256 | { 257 | temp=begin; 258 | begin=NULL; 259 | delete(temp); 260 | return begin; 261 | } 262 | else 263 | { 264 | cout<<"Element "<info==data_element) 269 | { 270 | temp=begin; 271 | begin=begin->next_node; 272 | begin->prev_node=NULL; 273 | delete(temp); 274 | return begin; 275 | } 276 | 277 | temp=begin->next_node; 278 | while(temp->next_node!=NULL ) 279 | { 280 | if(temp->info==data_element) 281 | { 282 | temp->prev_node->next_node=temp->next_node; 283 | temp->next_node->prev_node=temp->prev_node; 284 | delete(temp); 285 | return begin; 286 | } 287 | temp=temp->next_node; 288 | } 289 | 290 | if(temp->info==data_element) 291 | { 292 | temp->prev_node->next_node=NULL; 293 | delete(temp); 294 | return begin; 295 | } 296 | cout<<"Element "<next_node; 311 | p1->next_node=NULL; 312 | p1->prev_node=p2; 313 | while(p2!=NULL) 314 | { 315 | p2->prev_node=p2->next_node; 316 | p2->next_node=p1; 317 | p1=p2; 318 | p2=p2->prev_node; 319 | } 320 | begin=p1; 321 | cout<<"List reverselistd\n"; 322 | return begin; 323 | } 324 | -------------------------------------------------------------------------------- /DS implementations/Linked List/circular_linked_list/circular.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct node { 5 | int num; 6 | struct node * next; 7 | }*head; 8 | 9 | void make(int n)//function to build circular linked list 10 | { 11 | int i, num; 12 | struct node *preptr, *newnode; 13 | 14 | if(n >= 1) 15 | { 16 | head = (struct node *)malloc(sizeof(struct node)); 17 | 18 | cout<<"Enter data of the list:\n"; 19 | cin>>num; 20 | head->num = num; 21 | head->next = NULL; 22 | preptr = head; 23 | for(i=2; i<=n; i++) 24 | { 25 | newnode = (struct node *)malloc(sizeof(struct node)); 26 | cin>>num; 27 | newnode->num = num; 28 | newnode->next = NULL; 29 | preptr->next = newnode; 30 | preptr = newnode; 31 | } 32 | preptr->next = head; //linking last node with head node 33 | } 34 | } 35 | void display()//function to display list 36 | { 37 | struct node *tmp; 38 | int n = 1; 39 | 40 | if(head == NULL) 41 | { 42 | cout<<"List is empty"; 43 | } 44 | else 45 | { 46 | tmp = head; 47 | 48 | cout<<"\nCircular linked list data:\n"; 49 | do { 50 | cout<num<<" "; 51 | tmp = tmp->next; 52 | n++; 53 | }while(tmp != head); 54 | } 55 | } 56 | void insertSpecific(int num, int pos)//function to insert element at specific position 57 | { 58 | struct node *newnode, *curNode; 59 | int i; 60 | 61 | if(head == NULL) 62 | { 63 | cout<<"List is empty"; 64 | } 65 | else 66 | { 67 | newnode = (struct node *)malloc(sizeof(struct node)); 68 | newnode->num = num; 69 | curNode = head; 70 | for(i=0; i<=pos-3; i++) 71 | { 72 | curNode = curNode->next; 73 | } 74 | newnode->next = curNode->next; 75 | curNode->next = newnode; 76 | } 77 | } 78 | 79 | 80 | int main()//main function 81 | { 82 | int n,num,pos; 83 | head = NULL; 84 | cout<<"Enter the size of circular linked list: "; 85 | cin>>n; 86 | make(n); 87 | display(); 88 | cout<<"\nEnter data to be inserted : "; 89 | cin>>num; 90 | cout<<"Enter position where you want to enter the data:\n"; 91 | cin>>pos; 92 | cout<<"\nAfter insertion data at specific position in list is:"; 93 | insertSpecific( num, pos); 94 | display(); 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /DS implementations/Linked List/list.cpp: -------------------------------------------------------------------------------- 1 | // Program to Insert node at nth position in a linked list 2 | // Time Complexity - O(N) 3 | 4 | #include 5 | using namespace std; 6 | 7 | struct Node 8 | { 9 | //To store the element 10 | int data; 11 | //To store the address of next element 12 | Node *next; 13 | }; 14 | 15 | //Pointer to head Node initialize to NULL 16 | Node *head = NULL; 17 | int size = 0; 18 | 19 | void insertAtNthNode(int x, int n) 20 | { 21 | if (n < 1 || n > size + 1) 22 | { 23 | cout << "Position is not valid.\n"; 24 | return; 25 | } 26 | 27 | // Increase size 28 | ++size; 29 | 30 | //Extra space for new Node 31 | Node *temp = (Node *)malloc(sizeof(Node)); 32 | 33 | //Store the value in the Node 34 | temp->data = x; 35 | 36 | //Initialize address as NULL 37 | temp->next = NULL; 38 | 39 | //If Insertion taking place at Beginning 40 | if (n == 1) 41 | { 42 | temp->next = head; 43 | head = temp; //It Point Head Node 44 | return; 45 | } 46 | 47 | //To connect link with (n-1)th Node 48 | Node *temp1 = head; 49 | 50 | //Iterate to get (n-1)th Node address 51 | for (int i = 0; i < n - 2; i++) 52 | temp1 = temp1->next; 53 | 54 | //Store new address 55 | temp->next = temp1->next; 56 | temp1->next = temp; 57 | } 58 | 59 | //Fxn to delete N'th Node 60 | void Delete(int n) 61 | { 62 | if (n < 1 || n > size + 1) 63 | { 64 | cout << "Position is not valid.\n"; 65 | return; 66 | } 67 | 68 | // Decrease the Size 69 | --size; 70 | 71 | Node *temp1 = head; 72 | 73 | if (n == 1) 74 | { 75 | //Head node is deleted and 76 | //Now head is pointed to next element 77 | head = temp1->next; 78 | free(temp1); 79 | return; 80 | } 81 | 82 | for (int i = 0; i < n - 2; i++) 83 | temp1 = temp1->next; 84 | 85 | //Pointer who point to N'th node 86 | Node *temp2 = temp1->next; 87 | temp1->next = temp2->next; 88 | 89 | //delete N'th node 90 | free(temp2); 91 | } 92 | 93 | void Update(int x, int n) 94 | { 95 | if (n < 1 || n > size + 1) 96 | { 97 | cout << "Position is not valid.\n"; 98 | return; 99 | } 100 | 101 | Node* temp = head; 102 | 103 | // Iterate n-1 times 104 | while (--n) 105 | temp = temp->next; 106 | 107 | //Update its value 108 | temp->data = x; 109 | } 110 | 111 | //function to Reverse linked list 112 | void Reverse() 113 | { 114 | Node *current, *prev, *next; 115 | 116 | current = head; 117 | prev = NULL; 118 | 119 | while (current != NULL) 120 | { 121 | next = current->next; 122 | current->next = prev; 123 | prev = current; 124 | current = next; 125 | } 126 | head = prev; 127 | } 128 | 129 | void PrintList() 130 | { 131 | //Initialize to Head Node 132 | Node *temp = head; 133 | 134 | cout << "\nList is : "; 135 | 136 | //Print until Last node 137 | while (temp != NULL) 138 | { 139 | cout << temp->data << " "; 140 | temp = temp->next; 141 | } 142 | 143 | cout << "\n"; 144 | } 145 | 146 | int main() 147 | { 148 | int n, x, op; 149 | while (true) 150 | { 151 | cout << "\n" 152 | << "Enter 1 for Insertion\n" 153 | << "2 for Delete a node\n" 154 | << "3 for Updating Value\n" 155 | << "4 for Priniting List\n" 156 | << "5 for Reverse given list\n" 157 | << "Any Number for Quit\n"; 158 | cin >> op; 159 | 160 | if (op == 1) 161 | { 162 | cout << "Enter Number and its position : "; 163 | cin >> x >> n; 164 | insertAtNthNode(x, n); 165 | } 166 | else if (op == 2) 167 | { 168 | cout << "Enter the position of Node : "; 169 | cin >> n; 170 | Delete(n); 171 | } 172 | else if (op == 3) 173 | { 174 | cout << "Enter Number and its position : "; 175 | cin >> x >> n; 176 | Update(x, n); 177 | } 178 | else if (op == 4) 179 | PrintList(); 180 | else if (op == 5) 181 | Reverse(); 182 | else 183 | break; 184 | } 185 | 186 | return 0; 187 | } -------------------------------------------------------------------------------- /DS implementations/PRIORITY_QUEUES/max_pq.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void swap(vector pq, int a, int b) 5 | { 6 | int temp = pq[a]; 7 | pq[a] = pq[b]; 8 | pq[b] = temp; 9 | } 10 | 11 | class PriorityQueue 12 | { 13 | vector pq; 14 | 15 | public: 16 | PriorityQueue() 17 | { 18 | } 19 | 20 | bool isEmpty() 21 | { 22 | return pq.size() == 0; 23 | } 24 | 25 | // Return the size of priorityQueue - no of elements present 26 | int getSize() 27 | { 28 | return pq.size(); 29 | } 30 | 31 | int getMax() 32 | { 33 | if (isEmpty()) 34 | { 35 | return 0; // Priority Queue is empty 36 | } 37 | return pq[0]; 38 | } 39 | 40 | void insert(int element) 41 | { 42 | pq.push_back(element); 43 | 44 | int childIndex = pq.size() - 1; 45 | int parentIndex = (childIndex - 1) / 2; 46 | //Compare data we just inserted to parents data. If its greater than parents we swap 47 | //Continue to do this until we reach the root node 48 | while (childIndex > 0 && pq[parentIndex] < pq[childIndex]) 49 | { 50 | swap(pq, parentIndex, childIndex); 51 | 52 | childIndex = parentIndex; 53 | parentIndex = (childIndex - 1) / 2; 54 | } 55 | } 56 | 57 | int removeMax() 58 | { 59 | if (pq.size() == 0) 60 | return 0; 61 | int todel = pq[0]; 62 | pq[0] = pq[pq.size() - 1]; 63 | pq.pop_back(); 64 | 65 | int parent = 0, c1 = 1, c2 = 2; 66 | 67 | while ((parent < pq.size() - 1) && (pq[parent] < pq[c1] || pq[parent] < pq[c2])) 68 | { 69 | int newparent = (pq[c1] > pq[c2]) ? c1 : c2; 70 | swap(pq, newparent, parent); 71 | parent = newparent; 72 | c1 = 2 * parent + 1, c2 = 2 * parent + 2; 73 | } 74 | 75 | return todel; 76 | } 77 | 78 | void display() 79 | { 80 | for (int i = 0; i < pq.size(); i++) 81 | cout << pq[i] << " "; 82 | cout << endl; 83 | } 84 | }; 85 | 86 | int main() 87 | { 88 | PriorityQueue pq; 89 | int choice; 90 | cin >> choice; 91 | while (choice != -1) 92 | { 93 | switch (choice) 94 | { 95 | case 1: // insert 96 | int element; 97 | cin >> element; 98 | pq.insert(element); 99 | break; 100 | case 2: // getmax 101 | cout << pq.getMax() << endl; 102 | break; 103 | case 3: // removemax 104 | cout << pq.removeMax() << endl; 105 | break; 106 | case 4: // size 107 | cout << pq.getSize() << endl; 108 | break; 109 | case 5: // isEmpty 110 | if (pq.isEmpty()) 111 | { 112 | cout << "true" << endl; 113 | } 114 | else 115 | { 116 | cout << "false" << endl; 117 | } 118 | break; 119 | case 6: // show 120 | pq.display(); 121 | break; 122 | 123 | default: 124 | return 0; 125 | } 126 | cin >> choice; 127 | } 128 | 129 | getchar(); 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /DS implementations/PRIORITY_QUEUES/min_pq.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class PriorityQueue 5 | { 6 | vector pq; 7 | 8 | public: 9 | PriorityQueue() 10 | { 11 | } 12 | 13 | bool isEmpty() 14 | { 15 | return pq.size() == 0; 16 | } 17 | 18 | // Return the size of priorityQueue - no of elements present 19 | int getSize() 20 | { 21 | return pq.size(); 22 | } 23 | 24 | int getMin() 25 | { 26 | if (isEmpty()) 27 | return 0; // Priority Queue is empty 28 | 29 | return pq[0]; 30 | } 31 | 32 | void insert(int element) 33 | { 34 | pq.push_back(element); 35 | int childIndex = pq.size() - 1; 36 | //Compare data we just inserted to parents data. If its less than parents we swap 37 | //Continue to do this until we reach the root node 38 | while (childIndex > 0) 39 | { 40 | int parentIndex = (childIndex - 1) / 2; 41 | 42 | if (pq[childIndex] < pq[parentIndex]) 43 | { 44 | int temp = pq[childIndex]; 45 | pq[childIndex] = pq[parentIndex]; 46 | pq[parentIndex] = temp; 47 | } 48 | else 49 | { 50 | break; 51 | } 52 | childIndex = parentIndex; 53 | } 54 | } 55 | int removeMin() 56 | { 57 | if (pq.size() == 0) 58 | return 0; 59 | int minindex; 60 | int todel = pq[0]; 61 | pq[0] = pq[pq.size() - 1]; 62 | pq.pop_back(); 63 | 64 | int parentindex = 0; 65 | int childindex1 = 1; 66 | int childindex2 = 2; 67 | while (childindex1 < pq.size()) 68 | { 69 | if (pq[childindex1] < pq[parentindex] || pq[childindex2] < pq[parentindex]) 70 | { 71 | if (pq[childindex1] < pq[childindex2]) 72 | minindex = childindex1; 73 | else 74 | minindex = childindex2; 75 | 76 | int temp = pq[parentindex]; 77 | pq[parentindex] = pq[minindex]; 78 | pq[minindex] = temp; 79 | 80 | parentindex = minindex; 81 | childindex1 = 2 * parentindex + 1; 82 | childindex2 = 2 * parentindex + 2; 83 | } 84 | else 85 | break; 86 | } 87 | return todel; 88 | } 89 | void display() 90 | { 91 | for (int i = 0; i < pq.size(); i++) 92 | cout << pq[i] << " "; 93 | cout << endl; 94 | } 95 | }; 96 | int main() 97 | { 98 | PriorityQueue pq; 99 | int choice; 100 | cin >> choice; 101 | while (choice != -1) 102 | { 103 | switch (choice) 104 | { 105 | case 1: // insert 106 | int element; 107 | cin >> element; 108 | pq.insert(element); 109 | break; 110 | case 2: // getMin 111 | cout << pq.getMin() << endl; 112 | break; 113 | case 3: // removeMin 114 | cout << pq.removeMin() << endl; 115 | break; 116 | case 4: // size 117 | cout << pq.getSize() << endl; 118 | break; 119 | case 5: // isEmpty 120 | if (pq.isEmpty()) 121 | cout << "true" << endl; 122 | else 123 | cout << "false" << endl; 124 | case 6: // show 125 | pq.display(); 126 | break; 127 | default: 128 | return 0; 129 | } 130 | cin >> choice; 131 | } 132 | getchar(); 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /DS implementations/QUEUES/Queue_Implementation.cpp: -------------------------------------------------------------------------------- 1 | // C++ program for array implementation of q 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // A class to represent a q 8 | class Queue 9 | { 10 | public: 11 | int front, rear, size; 12 | unsigned capacity; 13 | int *array; 14 | }; 15 | 16 | // function to create a queue of given capacity, it initializes size of queue as 0 17 | Queue *createQueue(unsigned capacity) 18 | { 19 | Queue *q = new Queue(); 20 | q->capacity = capacity; 21 | q->front = q->size = 0; 22 | 23 | // assigning last index of the q to the rear. 24 | q->rear = capacity - 1; 25 | // dynamically allocating int array of capacity. 26 | q->array = new int[q->capacity]; 27 | return q; 28 | } 29 | 30 | // Queue is full when size becomes equal to the capacity 31 | int isFull(Queue *q) 32 | { 33 | return (q->size == q->capacity); 34 | } 35 | 36 | // Queue is empty when size is 0 37 | int isEmpty(Queue *q) 38 | { 39 | return (q->size == 0); 40 | } 41 | 42 | // Function to add an item to the queue. It changes rear and size 43 | void enqueue(Queue *q, int item) 44 | { 45 | // if queue is full then we can't push more. 46 | if (isFull(q)) 47 | return; 48 | // updating rear to next index. 49 | q->rear = (q->rear + 1) % q->capacity; 50 | // storing the item at the rear index of the queue. 51 | q->array[q->rear] = item; 52 | // as we added one more element so increment the size of the queue. 53 | q->size = q->size + 1; 54 | cout << item << " enqueued to q\n"; 55 | } 56 | 57 | // Function to remove an item from queue. It changes front and size 58 | int dequeue(Queue *q) 59 | { 60 | // if queue is empty then we can't dequeue more, so for handling the underflow we will return INT_MIN. 61 | if (isEmpty(q)) 62 | return INT_MIN; 63 | // as we dequeue from the front of the queue so we will store the front element in item variable. 64 | int item = q->array[q->front]; 65 | // updating the front to the next index. 66 | q->front = (q->front + 1) % q->capacity; 67 | // as we have removed one element so we will decrement the size of the queue by 1. 68 | q->size = q->size - 1; 69 | return item; 70 | } 71 | 72 | // Function to get front of queue 73 | int front(Queue *q) 74 | { 75 | // in underflow condition we will return INT_MIN. 76 | if (isEmpty(q)) 77 | return INT_MIN; 78 | // otherwise returning the element at the front index of the queue. 79 | return q->array[q->front]; 80 | } 81 | 82 | // Function to get rear of queue 83 | int rear(Queue *q) 84 | { 85 | // in underflow condition we will return INT_MIN. 86 | if (isEmpty(q)) 87 | return INT_MIN; 88 | // otherwise returning the element at the rear index of the queue. 89 | return q->array[q->rear]; 90 | } 91 | 92 | // Driver code 93 | int main() 94 | { 95 | // creating a queue of maximum capacity 1000. 96 | Queue *q = createQueue(1000); 97 | 98 | enqueue(q, 10); 99 | enqueue(q, 20); 100 | enqueue(q, 30); 101 | enqueue(q, 40); 102 | 103 | cout << dequeue(q) << " dequeued from queue\n"; 104 | 105 | cout << "Front item is " << front(q) << endl; 106 | cout << "Rear item is " << rear(q) << endl; 107 | 108 | return 0; 109 | } -------------------------------------------------------------------------------- /DS implementations/QUEUES/queues_linkedlist/queue_with_linkedlist.cpp: -------------------------------------------------------------------------------- 1 | // IMPLEMENTING QUEUES USING LINKED LISR BY TAKING INPUT FROM THE USER 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct node 9 | { 10 | int data; 11 | struct node *next; 12 | }*front=NULL,*rear,*temp; 13 | 14 | void ins() // function to insert node 15 | { 16 | temp=new node; 17 | cout<<"ENTER DATA:"; 18 | cin>>temp->data; 19 | temp->next=NULL; 20 | 21 | if(front==NULL) 22 | front=rear=temp; 23 | else 24 | { 25 | rear->next=temp; 26 | rear=temp; 27 | } 28 | } 29 | 30 | void del() // function for deletion of node 31 | { 32 | if(front==NULL) 33 | cout<<"EMPTY QUEUE!!!!!!!!!!!!!!!!!\n"; 34 | else 35 | { 36 | temp=front; 37 | front=front->next; 38 | cout<<"DELETED NODE IS "<data<<"\n"; 39 | delete(temp); 40 | } 41 | } 42 | 43 | void dis() // function to display elements of a queue 44 | { 45 | if(front==NULL) 46 | cout<<"EMPTY QUEUE!!!!!!!!!!!!!!!!!!!!!\n"; 47 | else 48 | { 49 | temp=front; 50 | while(temp!=NULL) 51 | { 52 | cout<data<<"->"; 53 | temp=temp->next; 54 | } 55 | } 56 | } 57 | 58 | int main() 59 | { 60 | int ch; 61 | while(1) 62 | { 63 | cout<<"\n-------IMPLEMENTATION OF QUEUE USING LINKED LIST--------"<<"\n1.PUSH\n2.POP\n3.DISPLAY\n4.EXIT"; 64 | cout<<"\n\nENTER A VALID CHOICE TO PERFORM THE OPERATIONS (1-4):"; 65 | cin>>ch; 66 | cout<<"\n"; 67 | 68 | switch(ch) 69 | { 70 | case 1: ins(); 71 | break; 72 | case 2: del(); 73 | break; 74 | case 3: dis(); 75 | break; 76 | case 4: exit(0); 77 | break; 78 | default: cout<<"INVALID CHOICE!!!!!!!!"; 79 | } 80 | } 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /DS implementations/SEGMENT TREES/lazy_propagation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void buildTree(int* arr, int* tree, int start, int end, int treenode) 5 | { 6 | //base case 7 | if(start == end) 8 | { 9 | tree[treenode] = arr[start]; 10 | return; 11 | } 12 | 13 | int mid = start + (end-start)/2; 14 | 15 | buildTree(arr,tree,start,mid,2*treenode); 16 | buildTree(arr,tree,mid+1,end,2*treenode+1); 17 | 18 | tree[treenode] = tree[2*treenode] + tree[2*treenode+1]; 19 | } 20 | 21 | void updateSegmentTreeLazy(int* tree, int* lazy, int treeIndex, int start, int end, int qs, int qe, int inc){ 22 | //base case 23 | if(start > end || qs > qe) return; 24 | //update tree a/c to lazy tree before moving on to other operations 25 | if(lazy[treeIndex] != 0){ 26 | tree[treeIndex] += lazy[treeIndex]; 27 | if(start != end){ 28 | lazy[2*treeIndex] += lazy[treeIndex]; 29 | lazy[2*treeIndex+1] += lazy[treeIndex]; 30 | } 31 | lazy[treeIndex] = 0; 32 | } 33 | //no overlap 34 | if(qe < start || qs > end) 35 | return; 36 | //complete overlap 37 | if(qs <= start && qe >= end){ 38 | tree[treeIndex] += inc; 39 | if(start != end){ 40 | lazy[2*treeIndex] += inc; 41 | lazy[2*treeIndex+1] += inc; 42 | } 43 | return; 44 | } 45 | //partial overlap 46 | int mid = (start + end )/2; 47 | updateSegmentTreeLazy(tree,lazy,2*treeIndex,start,mid,qs,qe,inc); 48 | updateSegmentTreeLazy(tree,lazy,2*treeIndex+1,mid+1,end,qs,qe,inc); 49 | tree[treeIndex] = tree[2*treeIndex] + tree[2*treeIndex+1]; 50 | } 51 | 52 | int query(int* tree, int* lazy, int s, int e, int treeIndex, int left, int right){ 53 | if(s > right || e < left) 54 | return 0; 55 | 56 | if(lazy[treeIndex] != 0){ 57 | tree[treeIndex] += lazy[treeIndex]; 58 | if(s != e){ 59 | lazy[2*treeIndex] += lazy[treeIndex]; 60 | lazy[2*treeIndex+1] += lazy[treeIndex]; 61 | } 62 | lazy[treeIndex] = 0; 63 | } 64 | 65 | if(left <= s && right >= e) 66 | return tree[treeIndex]; 67 | 68 | int mid = s + (e-s)/2; 69 | int ans1 = query(tree,lazy,s,mid,2*treeIndex,left,right); 70 | int ans2 = query(tree,lazy,mid+1,e,2*treeIndex+1,left,right); 71 | 72 | return ans1+ans2; 73 | } 74 | 75 | int main(){ 76 | int arr[] = {1,2,3,4,5,6,7,8,9}; 77 | int* tree = new int[18]; 78 | 79 | buildTree(arr,tree,0,8,1); 80 | 81 | for(int i = 1; i <= 18; i++) 82 | cout << tree[i] << endl; 83 | 84 | // update(arr,tree,0,8,4,10,1); 85 | 86 | 87 | // for(int i = 1; i <= 18; i++) 88 | // cout << tree[i] << endl; 89 | 90 | // cout << query(tree,0,8,1,2,7); 91 | 92 | } -------------------------------------------------------------------------------- /DS implementations/SEGMENT TREES/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void buildTree(int* arr, int* tree, int start, int end, int treenode) 5 | { 6 | //base case 7 | if(start == end) 8 | { 9 | tree[treenode] = arr[start]; 10 | return; 11 | } 12 | 13 | int mid = start + (end-start)/2; 14 | 15 | buildTree(arr,tree,start,mid,2*treenode); 16 | buildTree(arr,tree,mid+1,end,2*treenode+1); 17 | 18 | tree[treenode] = tree[2*treenode] + tree[2*treenode+1]; 19 | } 20 | 21 | void update(int* arr, int* tree, int s, int e, int idx, int value, int TN){ 22 | if(s == e){ 23 | arr[idx] = value; 24 | tree[TN] = value; 25 | return; 26 | } 27 | 28 | int mid = s + (e-s)/2; 29 | 30 | if(idx > mid) 31 | update(arr,tree,mid+1,e,idx,value,2*TN+1); 32 | else 33 | update(arr,tree,s,mid,idx,value,2*TN); 34 | 35 | tree[TN] = tree[2*TN] + tree[2*TN+1]; 36 | } 37 | 38 | int query(int* tree,int s, int e, int TN, int left, int right){ 39 | if(s > right || e < left) 40 | return 0; 41 | 42 | if(left <= s && right >= e) 43 | return tree[TN]; 44 | 45 | int mid = s + (e-s)/2; 46 | int ans1 = query(tree,s,mid,2*TN,left,right); 47 | int ans2 = query(tree,mid+1,e,2*TN+1,left,right); 48 | 49 | return ans1+ans2; 50 | } 51 | 52 | int main(){ 53 | int arr[] = {1,2,3,4,5,6,7,8,9}; 54 | int* tree = new int[18]; 55 | 56 | buildTree(arr,tree,0,8,1); 57 | 58 | for(int i = 1; i <= 18; i++) 59 | cout << tree[i] << endl; 60 | 61 | update(arr,tree,0,8,4,10,1); 62 | 63 | 64 | for(int i = 1; i <= 18; i++) 65 | cout << tree[i] << endl; 66 | 67 | cout << query(tree,0,8,1,2,7); 68 | 69 | } -------------------------------------------------------------------------------- /DS implementations/STACKS/Stack_Implementation.cpp: -------------------------------------------------------------------------------- 1 | /* C++ program to implement basic stack operations */ 2 | #include 3 | 4 | using namespace std; 5 | 6 | #define MAX 1000 7 | 8 | class Stack 9 | { 10 | int top; 11 | 12 | public: 13 | int a[MAX]; // Maximum size of Stack 14 | 15 | Stack() 16 | { 17 | top = -1; 18 | } 19 | 20 | bool push(int x); 21 | int pop(); 22 | int peek(); 23 | bool isEmpty(); 24 | }; 25 | 26 | bool Stack::push(int x) 27 | { 28 | // if top reaches the end of the stack then stack is full, we can't push more. 29 | if (top >= (MAX - 1)) 30 | { 31 | cout << "Stack Overflow"; 32 | return false; 33 | } 34 | // otherwise just push the value in the stack. 35 | else 36 | { 37 | a[++top] = x; 38 | cout << x << " pushed into stack\n"; 39 | return true; 40 | } 41 | 42 | return false; 43 | } 44 | 45 | int Stack::pop() 46 | { 47 | // if top is less than 0 means our stack is empty, we can't pop more. 48 | if (top < 0) 49 | { 50 | cout << "Stack Underflow"; 51 | return 0; 52 | } 53 | else 54 | { 55 | int x = a[top--]; 56 | return x; 57 | } 58 | 59 | return -1; 60 | } 61 | 62 | int Stack::peek() 63 | { 64 | // if top is less than 0 means stack is having no element. 65 | if (top < 0) 66 | { 67 | cout << "Stack is Empty"; 68 | return 0; 69 | } 70 | else 71 | { 72 | // return the element at top index. 73 | int x = a[top]; 74 | return x; 75 | } 76 | 77 | return -1; 78 | } 79 | 80 | // if top is less than 0 means our stack is empty. 81 | bool Stack::isEmpty() 82 | { 83 | return (top < 0); 84 | } 85 | 86 | // Driver program 87 | int main() 88 | { 89 | class Stack s; 90 | s.push(10); 91 | s.push(20); 92 | s.push(30); 93 | s.peek(); 94 | cout << s.pop() << " Popped from stack\n"; 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /DS implementations/STACKS/Stack_linked_list/stack_with_linkedlist.cpp: -------------------------------------------------------------------------------- 1 | // IMPLEMENTING STACKS USING LINKED LIST BY TAKING INPUTS FROM THE USER 2 | 3 | #include 4 | 5 | 6 | using namespace std; 7 | 8 | struct Node 9 | { 10 | int data; 11 | Node *next; 12 | }*top=NULL,*p; 13 | 14 | Node* newnode(int x) 15 | { 16 | p=new Node; 17 | p->data=x; 18 | p->next=NULL; 19 | return(p); 20 | } 21 | 22 | void push(Node *q) // function to push elements into stack 23 | { 24 | if(top==NULL) 25 | top=q; 26 | else 27 | { 28 | q->next=top; 29 | top=q; 30 | } 31 | } 32 | 33 | void pop() // function to delete elements from stack 34 | { 35 | if(top==NULL) 36 | { 37 | cout<<"STACK IS EMPTY!!!!!!!!!!!!!!"; 38 | } 39 | else 40 | { 41 | cout<<"DELETED ELEMENT IS : "<data; 42 | p=top; 43 | top=top->next; 44 | delete(p); 45 | } 46 | } 47 | 48 | void showstack() 49 | { 50 | Node *q; 51 | q=top; 52 | 53 | if(top==NULL) 54 | { 55 | cout<<"STACK IS EMPTY !!!!!!!!!!"; 56 | } 57 | else 58 | { 59 | while(q!=NULL) 60 | { 61 | cout<data<<" "; 62 | q=q->next; 63 | } 64 | } 65 | } 66 | 67 | int main() 68 | { 69 | int ch,x; 70 | Node *nptr; 71 | 72 | while(1) 73 | { 74 | cout<<"\n-----IMPLEMENTING STACS USING LINKED LIST -----\n"; 75 | cout<<"\nENTER A VALID CHOICE (1-4):"; 76 | 77 | cout<<"\n\n1.PUSH\n2.POP\n3.DISPLAY\n4.EXIT"; 78 | 79 | cin>>ch; 80 | 81 | switch(ch){ 82 | case 1: cout<<"\nENTER DATA:"; 83 | cin>>x; 84 | nptr=newnode(x); 85 | push(nptr); 86 | break; 87 | 88 | case 2: pop(); 89 | break; 90 | 91 | case 3: showstack(); 92 | break; 93 | 94 | case 4: exit(0); 95 | 96 | default: cout<<"\nINVALID CHOICE !!!!!!!"; 97 | } 98 | } 99 | 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /DS implementations/TREES/BST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | template 5 | class BinaryTreeNode 6 | { 7 | public: 8 | T data; 9 | BinaryTreeNode *left; 10 | BinaryTreeNode *right; 11 | 12 | BinaryTreeNode(T data) 13 | { 14 | this->data = data; 15 | this->left = NULL; 16 | this->right = NULL; 17 | } 18 | }; 19 | 20 | class BST 21 | { 22 | int input; 23 | 24 | public: 25 | BinaryTreeNode *root = NULL; 26 | 27 | bool hasData(int input) 28 | { 29 | return hasData(root, input); 30 | } 31 | 32 | BinaryTreeNode *insert(int input) 33 | { 34 | root = insert(root, input); 35 | return root; 36 | } 37 | 38 | BinaryTreeNode *deleteData(int input) 39 | { 40 | return deleteData(root, input); 41 | } 42 | 43 | void printTree() 44 | { 45 | printTree(root); 46 | } 47 | 48 | BinaryTreeNode *printTree(BinaryTreeNode *root) 49 | { 50 | if (root == NULL) 51 | { 52 | return root; 53 | } 54 | cout << root->data << ":"; 55 | if (root->left != NULL) 56 | { 57 | cout << "L:" << root->left->data << ","; 58 | } 59 | if (root->right != NULL) 60 | { 61 | cout << "R:" << root->right->data; 62 | } 63 | cout << endl; 64 | printTree(root->left); 65 | printTree(root->right); 66 | } 67 | 68 | BinaryTreeNode *minvalue(BinaryTreeNode *root) 69 | { 70 | if (root == NULL) 71 | return root; 72 | 73 | BinaryTreeNode *current = root; 74 | while (current->left != NULL) 75 | current = current->left; 76 | 77 | return current; 78 | } 79 | 80 | bool hasData(BinaryTreeNode *root, int input) 81 | { 82 | if (root == NULL) 83 | return false; 84 | 85 | if (root->data == input) 86 | return true; 87 | bool ans; 88 | 89 | if (input < root->data) 90 | ans = hasData(root->left, input); 91 | else 92 | ans = hasData(root->right, input); 93 | 94 | if (ans == true) 95 | return ans; 96 | } 97 | 98 | BinaryTreeNode *insert(BinaryTreeNode *root, int input) 99 | { 100 | BinaryTreeNode *newnode = new BinaryTreeNode(input); 101 | if (root == NULL) 102 | { 103 | root = newnode; 104 | return root; 105 | } 106 | if (input > root->data) 107 | root->right = insert(root->right, input); 108 | if (input < root->data) 109 | root->left = insert(root->left, input); 110 | return root; 111 | } 112 | 113 | BinaryTreeNode *deleteData(BinaryTreeNode *root, int input) 114 | { 115 | if (root == NULL) 116 | return root; 117 | 118 | if (input < root->data) 119 | root->left = deleteData(root->left, input); 120 | else if (input > root->data) 121 | root->right = deleteData(root->right, input); 122 | else 123 | { 124 | if (root->left == NULL) 125 | { 126 | BinaryTreeNode *temp = root->right; 127 | free(root); 128 | return temp; 129 | } 130 | else if (root->right == NULL) 131 | { 132 | BinaryTreeNode *temp = root->left; 133 | free(root); 134 | return temp; 135 | } 136 | else 137 | { 138 | BinaryTreeNode *temp = minvalue(root->right); 139 | root->data = temp->data; 140 | root->right = deleteData(root->right, temp->data); 141 | } 142 | } 143 | return root; 144 | } 145 | }; 146 | 147 | int main() 148 | { 149 | BST *tree = new BST(); 150 | int choice, input; 151 | while (true) 152 | { 153 | cin >> choice; 154 | switch (choice) 155 | { 156 | case 1: 157 | cin >> input; 158 | tree->insert(input); 159 | break; 160 | case 2: 161 | cin >> input; 162 | tree->deleteData(input); 163 | break; 164 | case 3: 165 | cin >> input; 166 | if (tree->hasData(input)) 167 | { 168 | cout << "true" << endl; 169 | } 170 | else 171 | { 172 | cout << "false" << endl; 173 | } 174 | break; 175 | default: 176 | tree->printTree(); 177 | return 0; 178 | break; 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /DS implementations/TRIES/index.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Trie 5 | { 6 | struct node 7 | { 8 | bool end; 9 | unordered_map child; 10 | node() : end(false) {} 11 | }; 12 | struct node *root; 13 | 14 | public: 15 | Trie() 16 | { 17 | root = new node; 18 | } 19 | void add(string &s) 20 | { 21 | node *cur = root; 22 | for (char i : s) 23 | { 24 | if (cur->child.count(i) == 0) 25 | cur->child[i] = new node; 26 | cur = cur->child[i]; 27 | } 28 | cur->end = true; 29 | } 30 | bool prefixMatch(string &s) 31 | { 32 | node *cur = root; 33 | for (char i : s) 34 | { 35 | if (cur->child.count(i) == 0) 36 | return false; 37 | cur = cur->child[i]; 38 | } 39 | return true; 40 | } 41 | bool stringPresent(string &s) 42 | { 43 | node *cur = root; 44 | for (char i : s) 45 | { 46 | if (cur->child.count(i) == 0) 47 | return false; 48 | cur = cur->child[i]; 49 | } 50 | return cur->end; 51 | } 52 | }; -------------------------------------------------------------------------------- /DS implementations/TRIES/practice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Trie{ 5 | struct node{ 6 | bool end; 7 | unordered_map child; 8 | node() : end(false){} 9 | }; 10 | struct node* root; 11 | public: 12 | 13 | void add(string &s){ 14 | node* cur = root; 15 | for(char i : s){ 16 | if(cur->child.count(i) == 0) cur->child[i] = new node; 17 | cur = cur->child[i]; 18 | } 19 | cur->end = true; 20 | } 21 | 22 | bool prefixMatch(string &s){ 23 | node* cur = root; 24 | for(char i : s){ 25 | if(cur->child.count(i) == 0) return false; 26 | cur = cur->child[i]; 27 | } 28 | return 1; 29 | } 30 | 31 | bool stringPresent(string &s){ 32 | node* cur = root; 33 | for(char i : s){ 34 | if(cur->child.count(i) == 0) return false; 35 | cur = cur->child[i]; 36 | } 37 | return cur->end; 38 | } 39 | 40 | }; -------------------------------------------------------------------------------- /General/euler_totient.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/General/euler_totient.bin -------------------------------------------------------------------------------- /General/euler_totient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Euler Totient Function phi(n) = No if in in range (1,n) such that gcd(i,n) = 1 4 | 5 | 1. For a prime number p, phi(p) = p-1 6 | 2. For a number x = p^k, 7 | phi(x) = p^k - p^k/p; (because only multiples of p^k will have non-one gcd) 8 | 3. For two co-prime numbers A,B(gcd(A,B) = 1), phi(A*B) = phi(A)*phi(B) 9 | 4. For a number x = P1^K1 * P2^K2 * P3^K3............ 10 | P1^K1,P2^K2 are co-primes, 11 | so by property 3 12 | phi(X) = phi(p1^k1) * phi(p2^k2)....... 13 | */ 14 | 15 | #include 16 | using namespace std; 17 | #define int long long 18 | #define pii pair //factor,its power 19 | 20 | int fastpower(int a, int p){ 21 | if(a == 0) return 0; 22 | if(a == 1 || p == 0) return 1; 23 | if(p == 1) return a; 24 | 25 | int power = fastpower(a,p/2); 26 | power *= power; 27 | if(p & 1){ 28 | power *= a; 29 | } 30 | return power; 31 | } 32 | 33 | vector getFactors(int x){ 34 | vector factors; 35 | for(int i = 2; i*i <= x; i++){ 36 | if(x%i) continue; 37 | int cnt = 0; 38 | while(x%i == 0){ 39 | x /= i; 40 | cnt++; 41 | } 42 | factors.emplace_back(i,cnt); 43 | } 44 | return factors; 45 | } 46 | 47 | signed main() { 48 | int x; 49 | cin >> x; 50 | auto factors = getFactors(x); 51 | int ans = 1; 52 | for(auto f : factors){ 53 | int p = f.first; 54 | int k = f.second; 55 | ans *= ((fastpower(p,k) - fastpower(p,k-1))); 56 | } 57 | 58 | cout << ans; 59 | return 0; 60 | } -------------------------------------------------------------------------------- /General/gcd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Iterative function to calculate gcd of two numbers 4 | // using euclid's algortihm 5 | int euclid(int a, int b) 6 | { 7 | int r; 8 | 9 | // the algorithm stops when reaching a zero remainder 10 | while (b > 0) 11 | { 12 | r = a % b; 13 | // a becomes b and b becomes r (a % b) 14 | a = b; 15 | b = r; 16 | } 17 | 18 | return a; 19 | } 20 | 21 | 22 | //sahi h ye , chakkar hi ni koi 23 | int gcd(int a, int b) 24 | { 25 | if (a == 0 || b == 0) 26 | { 27 | return a == 0 ? b : a; 28 | } 29 | return gcd(a % b, b % a); 30 | } 31 | 32 | // main function 33 | int main() 34 | { 35 | int b = 2740; 36 | int a = 1760; 37 | 38 | printf("euclid(%d, %d) = %d", a, b, euclid(a, b)); 39 | 40 | return 0; 41 | } -------------------------------------------------------------------------------- /General/permutations/distinct_permutations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int factorial(int n) 5 | { 6 | // single line to find factorial 7 | return (n == 1 || n == 0) ? 1 : n * factorial(n - 1); 8 | } 9 | 10 | vector lexpermute(string s) 11 | { 12 | vector output; 13 | int n = s.size(); 14 | char first_char, sec_char; 15 | sort(s.begin(), s.end()); 16 | output.push_back(s); 17 | int anscount = factorial(s.size()), fc_pos, sc_pos; 18 | 19 | for (int i = 1; i < anscount; i++) 20 | { 21 | //previously printed string 22 | string prev = output[i - 1]; 23 | 24 | //find rightmost character which is smaller than its next character 25 | for (int i = n - 2; i >= 0; i--) 26 | { 27 | if (prev[i] < prev[i + 1]) 28 | { 29 | first_char = prev[i]; 30 | fc_pos = i; 31 | break; 32 | } 33 | } 34 | 35 | //find second char // smallest character greater than first character 36 | sec_char = first_char; 37 | for (int i = fc_pos + 1; i < n; i++) 38 | { 39 | if (prev[i] < sec_char && prev[i] > first_char) 40 | { 41 | sec_char = prev[i]; 42 | sc_pos = i; 43 | } 44 | } 45 | 46 | //swap fc & sc 47 | swap(prev[fc_pos], prev[sc_pos]); 48 | 49 | //sort the substring after fc original index 50 | sort(prev.begin() + fc_pos + 1, prev.end()); 51 | output.push_back(prev); 52 | } 53 | 54 | return output; 55 | } 56 | 57 | int main() 58 | { 59 | string s; 60 | cin >> s; 61 | 62 | vector output = lexpermute(s); 63 | 64 | for(auto a : output){ 65 | cout << a << " "; 66 | } 67 | } -------------------------------------------------------------------------------- /General/permutations/kth permutaion.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | say n = 4, you have {1, 2, 3, 4} 3 | 4 | If you were to list out all the permutations you have 5 | 6 | 1 + (permutations of 2, 3, 4) 7 | 8 | 2 + (permutations of 1, 3, 4) 9 | 10 | 3 + (permutations of 1, 2, 4) 11 | 12 | 4 + (permutations of 1, 2, 3) 13 | 14 | 15 | We know how to calculate the number of permutations of n numbers... n! So each of those with permutations of 3 numbers means there are 6 possible permutations. Meaning there would be a total of 24 permutations in this particular one. So if you were to look for the (k = 14) 14th permutation, it would be in the 16 | 17 | 3 + (permutations of 1, 2, 4) subset. 18 | 19 | To programmatically get that, you take k = 13 (subtract 1 because of things always starting at 0) and divide that by the 6 we got from the factorial, which would give you the index of the number you want. In the array {1, 2, 3, 4}, k/(n-1)! = 13/(4-1)! = 13/3! = 13/6 = 2. The array {1, 2, 3, 4} has a value of 3 at index 2. So the first number is a 3. 20 | 21 | Then the problem repeats with less numbers. 22 | 23 | The permutations of {1, 2, 4} would be: 24 | 25 | 1 + (permutations of 2, 4) 26 | 27 | 2 + (permutations of 1, 4) 28 | 29 | 4 + (permutations of 1, 2) 30 | 31 | But our k is no longer the 14th, because in the previous step, we've already eliminated the 12 4-number permutations starting with 1 and 2. So you subtract 12 from k.. which gives you 1. Programmatically that would be... 32 | 33 | k = k - (index from previous) * (n-1)! = k - 2*(n-1)! = 13 - 2*(3)! = 1 34 | 35 | In this second step, permutations of 2 numbers has only 2 possibilities, meaning each of the three permutations listed above a has two possibilities, giving a total of 6. We're looking for the first one, so that would be in the 1 + (permutations of 2, 4) subset. 36 | 37 | Meaning: index to get number from is k / (n - 2)! = 1 / (4-2)! = 1 / 2! = 0.. from {1, 2, 4}, index 0 is 1 38 | 39 | 40 | so the numbers we have so far is 3, 1... and then repeating without explanations. 41 | 42 | 43 | {2, 4} 44 | 45 | k = k - (index from pervious) * (n-2)! = k - 0 * (n - 2)! = 1 - 0 = 1; 46 | 47 | third number's index = k / (n - 3)! = 1 / (4-3)! = 1/ 1! = 1... from {2, 4}, index 1 has 4 48 | 49 | Third number is 4 50 | 51 | 52 | {2} 53 | 54 | k = k - (index from pervious) * (n - 3)! = k - 1 * (4 - 3)! = 1 - 1 = 0; 55 | 56 | third number's index = k / (n - 4)! = 0 / (4-4)! = 0/ 1 = 0... from {2}, index 0 has 2 57 | 58 | Fourth number is 2 59 | 60 | Explanation credits - leetcode discuss 61 | */ 62 | class Solution 63 | { 64 | public: 65 | string ans; 66 | long long fact(int n) 67 | { 68 | if (n == 1) 69 | return n; 70 | return n * fact(n - 1); 71 | } 72 | void helper(string &avail, int &k) 73 | { 74 | int n = avail.size(); 75 | if (!n || !k || k == 1) 76 | { 77 | ans += avail; 78 | return; 79 | } 80 | int curr_idx = (k - 1) / fact(n - 1); 81 | if (curr_idx < n) 82 | ans += avail[curr_idx]; 83 | string newavail = avail.substr(0, curr_idx); 84 | if (curr_idx < n - 1) 85 | newavail += avail.substr(curr_idx + 1); 86 | 87 | int newk = k - (curr_idx * fact(n - 1)); 88 | 89 | helper(newavail, newk); 90 | } 91 | 92 | string getPermutation(int n, int k) 93 | { 94 | string avail; 95 | for (int i = 1; i <= n; i++) 96 | avail += to_string(i); 97 | helper(avail, k); 98 | return ans; 99 | } 100 | }; -------------------------------------------------------------------------------- /General/permutations/lexico.cpp: -------------------------------------------------------------------------------- 1 | // Steps to generate the next higher permutation: 2 | 3 | // 1. Take the previously printed permutation and find the rightmost character in it, 4 | //which is smaller than its next character. Let us call this character as ‘first character’. 5 | 6 | // 2. Now find the ceiling of the ‘first character’. 7 | // Ceiling is the smallest character on right of ‘first character’, which is greater than ‘first character’. 8 | // Let us call the ceil character as ‘second character’. 9 | 10 | // 3. Swap the two characters found in above 2 steps. 11 | 12 | // 4. Sort the substring (in non-decreasing order) after the original index of ‘first character’. 13 | 14 | #include 15 | using namespace std; 16 | 17 | /* Following function is needed for library function qsort(). Refer 18 | http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/ */ 19 | int compare (const void *a, const void * b) 20 | { return ( *(char *)a - *(char *)b ); } 21 | 22 | // A utility function two swap two characters a and b 23 | void swap (char* a, char* b) 24 | { 25 | char t = *a; 26 | *a = *b; 27 | *b = t; 28 | } 29 | 30 | // This function finds the index of the smallest character 31 | // which is greater than 'first' and is present in str[l..h] 32 | int findCeil (char str[], char first, int l, int h) 33 | { 34 | // initialize index of ceiling element 35 | int ceilIndex = l; 36 | 37 | // Now iterate through rest of the elements and find 38 | // the smallest character greater than 'first' 39 | for (int i = l+1; i <= h; i++) 40 | if (str[i] > first && str[i] < str[ceilIndex]) 41 | ceilIndex = i; 42 | 43 | return ceilIndex; 44 | } 45 | 46 | // Print all permutations of str in sorted order 47 | void sortedPermutations ( char str[] ) 48 | { 49 | // Get size of string 50 | int size = strlen(str); 51 | 52 | // Sort the string in increasing order 53 | qsort( str, size, sizeof( str[0] ), compare ); 54 | 55 | // Print permutations one by one 56 | bool isFinished = false; 57 | while ( ! isFinished ) 58 | { 59 | // print this permutation 60 | cout << str << endl; 61 | 62 | // Find the rightmost character which is 63 | // smaller than its next character. 64 | // Let us call it 'first char' 65 | int i; 66 | for ( i = size - 2; i >= 0; --i ) 67 | if (str[i] < str[i+1]) 68 | break; 69 | 70 | // If there is no such character, all are 71 | // sorted in decreasing order, means we 72 | // just printed the last permutation and we are done. 73 | if ( i == -1 ) 74 | isFinished = true; 75 | else 76 | { 77 | // Find the ceil of 'first char' in 78 | // right of first character. 79 | // Ceil of a character is the smallest 80 | // character greater than it 81 | int ceilIndex = findCeil( str, str[i], i + 1, size - 1 ); 82 | 83 | // Swap first and second characters 84 | swap( &str[i], &str[ceilIndex] ); 85 | 86 | // Sort the string on right of 'first char' 87 | qsort( str + i + 1, size - i - 1, sizeof(str[0]), compare ); 88 | } 89 | } 90 | } 91 | 92 | // Driver program to test above function 93 | int main() 94 | { 95 | char str[] = "ABCD"; 96 | sortedPermutations( str ); 97 | return 0; 98 | } 99 | 100 | // This is code is contributed by rathbhupendra 101 | -------------------------------------------------------------------------------- /General/permutations/next_permute.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | /* 5 | 1. Find rightmost element smaller than its next element - fc 6 | 2. Find smallest number after fc which is greater than fc 7 | 3. swap fc & sc 8 | 4. sort after original index of fc 9 | 10 | */ 11 | 12 | void next_permute(vector &nums){ 13 | int n = nums.size(); 14 | int fc = -1; 15 | for (int i = n - 2; i >= 0; i--){ 16 | if (nums[i] < nums[i + 1]){ 17 | fc = i; 18 | break; 19 | } 20 | } 21 | if (fc == -1){ 22 | reverse(nums.begin(), nums.end()); 23 | return; 24 | } 25 | int sc = fc + 1; 26 | for (int i = fc + 1; i < n; i++){ 27 | if (nums[i] > nums[fc] && nums[i] < nums[sc]) 28 | sc = i; 29 | } 30 | swap(nums[fc], nums[sc]); 31 | sort(nums.begin() + fc + 1, nums.end()); 32 | } 33 | int main(){ 34 | int n; 35 | cin >> n; 36 | vector nums(n); 37 | for (auto &i : nums) 38 | cin >> i; 39 | next_permute(nums); 40 | for (auto &i : nums) 41 | cout << i; 42 | return 0; 43 | } -------------------------------------------------------------------------------- /General/permutations/permutations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | //lexicographically sorted 5 | void permute(string s, int i, int n){ 6 | if(i == n){ 7 | cout << s << " "; 8 | return; 9 | } 10 | 11 | for(int j = i; j < n; j++){ 12 | swap(s[j],s[i]); 13 | sort(s.begin()+i+1,s.end()); 14 | permute(s,i+1,n); 15 | swap(s[j],s[i]); 16 | } 17 | } 18 | 19 | int main() 20 | { 21 | string s; 22 | cin >> s; 23 | sort(s.begin(),s.end()); 24 | permute(s,0,s.size()-1); 25 | } -------------------------------------------------------------------------------- /General/sort_map_by_val.cpp: -------------------------------------------------------------------------------- 1 | static bool sortByVal(pair a, pair b) 2 | { 3 | if (a.second != b.second) 4 | return (a.second < b.second); 5 | else 6 | return (a.first < b.first); 7 | } 8 | 9 | vector> vec; 10 | 11 | // copy key-value pairs from the map to the vector 12 | map::iterator it2; 13 | for (it2 = mp.begin(); it2 != mp.end(); it2++) 14 | { 15 | vec.push_back(make_pair(it2->first, it2->second)); 16 | } 17 | 18 | // // sort the vector by increasing order of its pair's second value 19 | sort(vec.begin(), vec.end(), sortByVal); -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Please include a summary of the change and which issue is fixed. List any dependencies that are required for this change. 4 | 5 | Fixed # (issue) (e.g. Fixed #8) 6 | 7 | ## Type of change 8 | 9 | Please check options that are relevant to your PR. 10 | 11 | - [ ] Bug fix (non-breaking change which fixes an issue) 12 | - [ ] New Data Structure 13 | - [ ] New Algorithm 14 | 15 | # Checklist: 16 | 17 | - [ ] I have squashed my commits 18 | - [ ] I have commented my code, particularly in hard-to-understand areas 19 | - [ ] I have made corresponding changes to the documentation 20 | - [ ] My code is a working bug-free code 21 | -------------------------------------------------------------------------------- /Practice Sessions/hashmap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class hashmap{ 5 | int size; 6 | struct node{ 7 | int key; 8 | int value; 9 | node(int key = -1, int value = -1) : key(key), value(value){} 10 | }; 11 | node* arr; 12 | 13 | public: 14 | hashmap(int size = 512){ 15 | this->size = size; 16 | this->arr = new node[size]; 17 | } 18 | 19 | int hash(int key){ 20 | return (key*key)%size; 21 | } 22 | 23 | void add(int key, int value){ 24 | int index = hash(key); 25 | arr[index] = key; 26 | } 27 | 28 | int get(int key){ 29 | int index = hash(key); 30 | if(arr[index].key == key) return arr[index].value; 31 | return -1; 32 | } 33 | }; 34 | 35 | int main(){ 36 | return 0; 37 | } -------------------------------------------------------------------------------- /Practice Sessions/hashmap_chaining.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class hashmap{ 5 | int size; 6 | struct node{ 7 | int key; 8 | int value; 9 | node(int key = -1, int value = -1) : key(key), value(value){} 10 | }; 11 | list* arr; 12 | public: 13 | hashmap(int size = 512){ 14 | this->size = size; 15 | this->arr = new list[size]; 16 | } 17 | 18 | int hash(int key){ 19 | return (key*key)%size; 20 | } 21 | 22 | void add(int key, int value){ 23 | int index = hash(key); 24 | arr[index].emplace_back(key,value); 25 | } 26 | 27 | int get(int key){ 28 | int index = hash(key); 29 | for(auto k : arr[index]){ 30 | if(key == k.key){ 31 | return k.value; 32 | } 33 | } 34 | return -1; 35 | } 36 | 37 | }; 38 | 39 | int main(){ 40 | return 0; 41 | } -------------------------------------------------------------------------------- /Practice Sessions/temp.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/Practice Sessions/temp.cpp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures and Algorithms - Quick Revision 2 | 3 | [![Contributors][contributors-shield]][contributors-url] 4 | [![Forks][forks-shield]][forks-url] 5 | [![Stargazers][stars-shield]][stars-url] 6 | [![Issues][issues-shield]][issues-url] 7 | 8 | 9 | 10 |
11 |

12 | 13 | Logo 14 | 15 | 16 | Logo 17 | 18 |

Mantained By

19 | 20 |

21 | This repository contains the implmentation of some of the most basic and important data structures and algorithms implemented in C++. A quick sneak peek into this repo before an interview may help! 22 |
23 |
24 | · 25 | Report Bug 26 | · 27 | Request Feature 28 |

29 |

30 | 31 |

32 |

33 | Data Structures and Algorithms 34 |

35 |

36 | 37 | 38 | ## Table of Contents 39 | 40 | * [Getting Started](#getting-started) 41 | * [Built With](#built-with) 42 | * [Data Structures](#data-structures-implementation) 43 | * [Algorithms](#algorithm-list) 44 | * [Contributing](#contributing) 45 | 46 | 47 | ## Getting Started 48 | 49 | The programs are contributed and mantained in a sequential order, anyone who wishes to go through the programs can easily find them in the [documentation](https://github.com/Manvityagi/Data-Structures-and-Algorithms/blob/master/DOCUMENTATION.md). 50 | 51 | None of the programs require any speacial library so can be run on any standard IDE local or online. 52 | 53 | 54 | ## Built With 55 | 56 | * [C++](https://isocpp.org/) - Programing Language 57 | 58 | ## Data Structures Implementation 59 | 60 | 1. [Priority Queue](./DS%20implementations/PRIORITY_QUEUES/) 61 | 2. [Hashmaps](./DS%20implementations/HASHMAPS/) 62 | 3. [Trees](./DS%20implementations/TREES) 63 | 4. [Graphs](./DS%20implementations/GRAPHS/) 64 | 5. [Tries](./DS%20implementations/TRIES/) 65 | 6. [Segment Trees](./DS%20implementations/Segment%20TREES/) 66 | 7. [Fenwick Trees](./DS%20implementations/FENWICK%20TREES) 67 | 8. [Stacks](./DS%20implementations/STACKS) 68 | 9. [Queues](./DS%20implementations/QUEUES) 69 | 10. [Linked List](./DS%20implementations/Linked%20List) 70 | 11. [Queues with linked list](./DS%20implementations/QUEUES/queues_linkedlist) 71 | 12. [Stacks with linked list](./DS%20implementations/STACKS/Stack_linked_list) 72 | 13. [Double Linked List](./DS%20implementations/Linked%20List/Double_linked_list) 73 | 14. [Circular Linked List](./DS%20implementations/Linked%20List/circular_linked_list) 74 | 75 | ## Algorithm List 76 | 77 | [View All](./DOCUMENTATION.md/) 78 | 79 | 1. [Sorting Algos](./DOCUMENTATION.md/DOCU#Sorting-Algos) 80 | 2. [Backtracking](./DOCUMENTATION.md/#BackTracking) 81 | 3. [Dynamic Programming](./DOCUMENTATION.md/#Dynamic-Programming) 82 | 4. [Graphs](./DOCUMENTATION.md/#Graphs) 83 | 5. [String-Matching](./DOCUMENTATION.md/#String-Matching) 84 | 6. [Tree Algorithms](./DOCUMENTATION.md/#Tree-Algorithms) 85 | 7. [Searching Algorithms](./DOCUMENTATION.md/#Searching-Algorithms) 86 | 8. [Others](./DOCUMENTATION.md/#Other-Algorithms) 87 | 88 | ## Contributing 89 | 90 | We want contributing to be enjoyable and educational for everyone. We would love to have your contributions. 91 | To get started have a look at our [documentation on contributing](https://github.com/Manvityagi/Data-Structures-and-Algorithms/blob/master/CONTRIBUTING.md). 92 | 93 | ### 1. Make Bug Reports 94 | A bug is a _demonstrable problem_ that is caused by the code in the repository. 95 | Good bug reports are extremely helpful, so thanks! 96 | 97 | ### 2. Adding a new DS or Algo ? 98 | Any important new algortihm or Data Structure not already present in the list is welcome. 99 | Do create an issue first for the same and then make the PR. 100 | 101 | You can follow the following steps for contributing. 102 | 103 | ```bash 104 | # clone the repository to your local machine 105 | $ git clone https://github.com//Data-Structures-and-Algorithms.git 106 | 107 | # navigate to the project's directory and install all the relevant dev-dependencies 108 | $ cd Data-Structures-and-Algorithms 109 | 110 | # add upstream 111 | $ git remote add upstream https://github.com/Manvityagi/Data-Structures-and-Algorithms 112 | 113 | # include all the latest changes from the remote repository 114 | $ git fetch upstream 115 | $ git merge upstream/develop 116 | ``` 117 | 118 | - Once you have made your changes, run the following command: 119 | 120 | ```bash 121 | # add your changes 122 | $ git add . 123 | 124 | # make your commit 125 | $ git commit -m "" 126 | The commit message should be in the format - `Added 'DS/ALGO NAME'` 127 | 128 | #push your changes 129 | git push -u origin master 130 | ``` 131 | 132 | ### 3. Make Pull Requests 133 | 134 | 135 | ## Authors 136 | 137 | 1. Manvi Tyagi - Initial Work - [View Profile](https://github.com/Manvityagi/) 138 | 139 | 140 | 141 | [contributors-shield]: https://img.shields.io/github/contributors/Manvityagi/Data-Structures-and-Algorithms.svg?style=flat-square 142 | [contributors-url]: https://github.com/Manvityagi/Data-Structures-and-Algorithms/graphs/contributors 143 | [forks-shield]: https://img.shields.io/github/forks/Manvityagi/Data-Structures-and-Algorithms.svg?style=flat-square 144 | [forks-url]: https://github.com/Manvityagi/Data-Structures-and-Algorithms/network/members 145 | [stars-shield]: https://img.shields.io/github/stars/Manvityagi/Data-Structures-and-Algorithms.svg?style=flat-square 146 | [stars-url]: https://github.com/Manvityagi/Data-Structures-and-Algorithms/stargazers 147 | [issues-shield]: https://img.shields.io/github/issues/Manvityagi/Data-Structures-and-Algorithms.svg?style=flat-square 148 | [issues-url]: https://github.com/Manvityagi/Data-Structures-and-Algorithms/issues -------------------------------------------------------------------------------- /assets/ds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manvityagi/Data-Structures-and-Algorithms/86233e8db025399ade44679da8c075619f91f5b6/assets/ds.png --------------------------------------------------------------------------------