├── .gitignore ├── Chap02 ├── 2.1.cpp ├── 2.1.h ├── 2.2.cpp ├── 2.2.h ├── 2.3.cpp ├── 2.3.h ├── Makefile └── Problems │ ├── 2-2.cpp │ ├── 2-2.h │ ├── 2-4.cpp │ └── 2-4.h ├── Chap04 ├── 4.1.cpp ├── 4.1.h ├── 4.2.cpp ├── 4.2.h ├── Makefile ├── Matrix.cpp └── Matrix.h ├── Chap05 ├── 5.1.cpp ├── 5.1.h └── Makefile ├── Chap06 ├── 6.1.h ├── 6.2.cpp ├── 6.2.h ├── 6.3.cpp ├── 6.3.h ├── 6.4.cpp ├── 6.4.h ├── 6.5.cpp ├── 6.5.h ├── Heap.h └── Makefile ├── Chap07 ├── 7.1.cpp ├── 7.1.h ├── 7.3.cpp ├── 7.3.h ├── Makefile └── Problems │ ├── 7-1.cpp │ ├── 7-1.h │ ├── 7-2.cpp │ ├── 7-2.h │ ├── 7-4.cpp │ ├── 7-4.h │ ├── 7-6.cpp │ └── 7-6.h ├── Chap08 ├── 8.2.cpp ├── 8.2.h ├── 8.3.cpp ├── 8.3.h └── Makefile ├── Chap10 ├── 10.1-4 │ ├── 10.1-4.cpp │ └── 10.1-4.h ├── 10.1.cpp ├── 10.1.h ├── 10.2.cpp ├── 10.2.h ├── List.h ├── Makefile ├── Queue.h └── Stack.h ├── Chap12 ├── 12.1.cpp ├── 12.1.h ├── 12.2.h ├── 12.3-5 │ ├── 12.3-5.cpp │ ├── 12.3-5.h │ ├── BST.h │ ├── TreeNode.h │ └── helper.h ├── 12.3.cpp ├── 12.3.h ├── BST.h ├── Makefile └── TreeNode.h ├── Chap22 ├── 22.1.cpp ├── 22.1.h ├── 22.2.cpp ├── 22.2.h ├── 22.3-10 │ ├── 22.3-10.cpp │ └── 22.3-10.h ├── 22.3-12 │ ├── 22.3-12.cpp │ └── 22.3-12.h ├── 22.3-7 │ ├── 22.3-7.cpp │ └── 22.3-7.h ├── 22.3.cpp ├── 22.3.h ├── Graph.h └── Makefile ├── README.md └── print.h /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.out 3 | .vscode 4 | *.sh -------------------------------------------------------------------------------- /Chap02/2.1.cpp: -------------------------------------------------------------------------------- 1 | #include "2.1.h" 2 | 3 | using namespace CLRS::CH2; 4 | 5 | int main() { 6 | print(string("Chapter 2.1 Insertion sort")); 7 | 8 | cout << "Initialize an array A as Figure 2.2\n"; 9 | vector A = {5, 2, 4, 6, 1, 3}; 10 | print(A); 11 | 12 | cout << "\nPerform INSERTION-SORT(A)\n"; 13 | insertionSort(A); 14 | 15 | cout << "\nPerform NONINCREASING-INSERTION-SORT(A)\n"; 16 | nonincreasingInsertionSort(A); 17 | } -------------------------------------------------------------------------------- /Chap02/2.1.h: -------------------------------------------------------------------------------- 1 | #ifndef ch2_1_h 2 | #define ch2_1_h 3 | 4 | #include "../print.h" 5 | 6 | using std::vector; 7 | 8 | // [Page 18] 9 | // INSERTION-SORT(A) 10 | // - Time: O(n^2) 11 | // 12 | // [Page 22] 13 | // NONINCREASING-INSERTION-SORT(A) 14 | // - Time: O(n^2) 15 | // 16 | // LINEAR-SEARCH(A) 17 | // - Time: O(n) 18 | 19 | namespace CLRS { 20 | namespace CH2 { 21 | template 22 | void insertionSort(vector& A) { 23 | for (int j = 1; j < A.size(); j++) { 24 | int key = A[j]; 25 | // Insert A[j] into the sorted sequence A[1..j - 1]. 26 | int i = j - 1; 27 | while (i >= 0 && A[i] > key) { 28 | A[i + 1] = A[i]; 29 | i = i - 1; 30 | } 31 | A[i + 1] = key; 32 | print(A); 33 | } 34 | } 35 | 36 | template 37 | void nonincreasingInsertionSort(vector& A) { 38 | for (int j = 1; j < A.size(); j++) { 39 | int key = A[j]; 40 | // Insert A[j] into the sorted sequence A[1..j - 1]. 41 | int i = j - 1; 42 | while (i >= 0 && A[i] < key) { 43 | A[i + 1] = A[i]; 44 | i = i - 1; 45 | } 46 | A[i + 1] = key; 47 | print(A); 48 | } 49 | } 50 | 51 | template 52 | int linearSearch(vector& A, int v) { 53 | for (int i = 0; i < A.size(); i++) 54 | if (A[i] == v) 55 | return i; 56 | return -1; 57 | } 58 | } // namespace CH2 59 | } // namespace CLRS 60 | 61 | #endif -------------------------------------------------------------------------------- /Chap02/2.2.cpp: -------------------------------------------------------------------------------- 1 | #include "2.2.h" 2 | 3 | using namespace CLRS::CH2; 4 | 5 | int main() { 6 | print(string("Chapter 2.2 Designing algorithms")); 7 | 8 | cout << "Initialize an array A as Figure 2.2\n"; 9 | vector A = {5, 2, 4, 6, 1, 3}; 10 | print(A); 11 | 12 | cout << "\nPerform SELECTION-SORT(A)\n"; 13 | selectionSort(A); 14 | } -------------------------------------------------------------------------------- /Chap02/2.2.h: -------------------------------------------------------------------------------- 1 | #ifndef ch2_2_h 2 | #define ch2_2_h 3 | 4 | #include "../print.h" 5 | 6 | using std::vector; 7 | 8 | // [Page 29][2.2-2] 9 | // SELECTION-SORT(A) 10 | // - Time: O(n^2) 11 | 12 | namespace CLRS { 13 | namespace CH2 { 14 | template 15 | void selectionSort(vector& A) { 16 | int n = A.size(); 17 | for (int i = 0; i < n - 1; i++) { 18 | int minIndex = i; 19 | for (int j = i + 1; j < n; j++) 20 | if (A[j] < A[minIndex]) 21 | minIndex = j; 22 | swap(A[i], A[minIndex]); 23 | print(A); 24 | } 25 | } 26 | } // namespace CH2 27 | } // namespace CLRS 28 | 29 | #endif -------------------------------------------------------------------------------- /Chap02/2.3.cpp: -------------------------------------------------------------------------------- 1 | #include "2.3.h" 2 | 3 | using namespace CLRS::CH2; 4 | 5 | int main() { 6 | print(string("Chapter 2.3 Designing algorithms")); 7 | 8 | cout << "Initialize an array A as Figure 2.3\n"; 9 | vector A(20); 10 | A[9] = 2; 11 | A[10] = 4; 12 | A[11] = 5; 13 | A[12] = 7; 14 | A[13] = 1; 15 | A[14] = 2; 16 | A[15] = 3; 17 | A[16] = 6; 18 | print(A); 19 | 20 | cout << "\nPerform MERGE(A, 9, 12, 16)\n"; 21 | merge(A, 9, 12, 16); 22 | 23 | cout << "\nInitialize an array A as Figure 2.4\n"; 24 | A = {5, 2, 4, 7, 1, 3, 2, 6}; 25 | print(A); 26 | 27 | cout << "\nPerform MERGE-SORT(A, 0, 7)\n"; 28 | mergeSort(A, 0, 7); 29 | print(A); 30 | 31 | cout << "\nPerform ITERATIVE-BINARY-SEARCH(A, 6, 0, 7)\n" 32 | << "The index of 6 is " << iterativeBinarySearch(A, 6, 0, 7) << endl; 33 | 34 | cout << "\nPerform RECURSIVE-BINARY-SEARCH(A, 6, 0, 7)\n" 35 | << "The index of 6 is " << recursiveBinarySearch(A, 6, 0, 7) << endl; 36 | } -------------------------------------------------------------------------------- /Chap02/2.3.h: -------------------------------------------------------------------------------- 1 | #ifndef ch2_3_h 2 | #define ch2_3_h 3 | 4 | #include "../print.h" 5 | 6 | using std::vector; 7 | 8 | // [Page 32] 9 | // MERGE(A, p, q, r) 10 | // - Time: O(n) 11 | // 12 | // [Page 32] 13 | // MERGE-SORT(A, p, r) 14 | // - Time: O(n lg n) 15 | // 16 | // [Page 39] 17 | // MERGE-WITHOUT-SENTINELS(A, p, q, r) 18 | // - Time: O(n) 19 | // 20 | // [Page 39][2.3-5] 21 | // ITERATIVE-BINARY-SEARCH(A, v, low, high) 22 | // - Time: O(lg n) 23 | // 24 | // RECURSIVE-BINARY-SEARCH(A, v, low, high) 25 | // - Time: O(lg n) 26 | 27 | namespace CLRS { 28 | namespace CH2 { 29 | template 30 | void merge(vector& A, int p, int q, int r) { 31 | int n1 = q - p + 1; 32 | int n2 = r - q; 33 | vector L(n1 + 1), R(n2 + 1); 34 | // The indices here are different from the book because the index of C++ 35 | // starts from 0 instead of 1. 36 | for (int i = 0; i < n1; i++) 37 | L[i] = A[p + i]; 38 | for (int j = 0; j < n2; j++) 39 | R[j] = A[q + j + 1]; 40 | L[n1] = INT_MAX; 41 | R[n2] = INT_MAX; 42 | int i = 0; 43 | int j = 0; 44 | for (int k = p; k <= r; k++) { 45 | if (L[i] <= R[j]) { 46 | A[k] = L[i]; 47 | i = i + 1; 48 | } else { 49 | A[k] = R[j]; 50 | j = j + 1; 51 | } 52 | print(A); 53 | } 54 | } 55 | 56 | template 57 | void mergeWithoutSentinels(vector& A, int p, int q, int r) { 58 | int n1 = q - p + 1; 59 | int n2 = r - q; 60 | vector L(n1 + 1), R(n2 + 1); 61 | for (int i = 0; i < n1; i++) 62 | L[i] = A[p + i]; 63 | for (int j = 0; j < n2; j++) 64 | R[j] = A[q + j + 1]; 65 | int i = 0; 66 | int j = 0; 67 | for (int k = p; k <= r; k++) { 68 | if (i >= n1) { 69 | A[k] = R[j]; 70 | j = j + 1; 71 | } else if (j >= n2) { 72 | A[k] = L[i]; 73 | i = i + 1; 74 | } else if (L[i] <= R[j]) { 75 | A[k] = L[i]; 76 | i = i + 1; 77 | } else { 78 | A[k] = R[j]; 79 | j = j + 1; 80 | } 81 | print(A); 82 | } 83 | } 84 | 85 | template 86 | void mergeSort(vector& A, int p, int r) { 87 | if (p < r) { 88 | int q = (p + r) / 2; 89 | mergeSort(A, p, q); 90 | mergeSort(A, q + 1, r); 91 | mergeWithoutSentinels(A, p, q, r); 92 | } 93 | } 94 | 95 | int iterativeBinarySearch(vector& A, int v, int low, int high) { 96 | while (low <= high) { 97 | int mid = (low + high) / 2; 98 | if (v == A[mid]) 99 | return mid; 100 | else if (v > A[mid]) 101 | low = mid + 1; 102 | else 103 | high = mid - 1; 104 | } 105 | return -1; 106 | } 107 | 108 | int recursiveBinarySearch(vector& A, int v, int low, int high) { 109 | if (low > high) 110 | return -1; 111 | int mid = (low + high) / 2; 112 | if (v == A[mid]) 113 | return mid; 114 | else if (v > A[mid]) 115 | return recursiveBinarySearch(A, v, mid + 1, high); 116 | else 117 | return recursiveBinarySearch(A, v, low, mid - 1); 118 | } 119 | } // namespace CH2 120 | } // namespace CLRS 121 | 122 | #endif -------------------------------------------------------------------------------- /Chap02/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-Wall 3 | EXEC=run 4 | 5 | run: 6 | $(CXX) -std=c++2a $(CFLAGS) ./2.1.cpp -o 2.1.out 7 | $(CXX) -std=c++2a $(CFLAGS) ./2.2.cpp -o 2.2.out 8 | $(CXX) -std=c++2a $(CFLAGS) ./2.3.cpp -o 2.3.out 9 | $(CXX) -std=c++2a $(CFLAGS) ./Problems/2-2.cpp -o 2-2.out 10 | $(CXX) -std=c++2a $(CFLAGS) ./Problems/2-4.cpp -o 2-4.out 11 | clear 12 | 13 | clean: 14 | rm *.out -------------------------------------------------------------------------------- /Chap02/Problems/2-2.cpp: -------------------------------------------------------------------------------- 1 | #include "2-2.h" 2 | 3 | using namespace CLRS::CH2; 4 | 5 | int main() { 6 | print(string("Problem 2-2 Correctness of bubblesort")); 7 | 8 | cout << "Initialize an array A as Figure 2.2\n"; 9 | vector A = {5, 2, 4, 6, 1, 3}; 10 | print(A); 11 | 12 | cout << "\nPerform BUBBLE-SORT(A)\n"; 13 | bubbleSort(A); 14 | } -------------------------------------------------------------------------------- /Chap02/Problems/2-2.h: -------------------------------------------------------------------------------- 1 | #ifndef prob2_2_h 2 | #define prob2_2_h 3 | 4 | #include "../../print.h" 5 | 6 | using std::vector; 7 | 8 | // [Page 40] 9 | // BUBBLE-SORT(A) 10 | // - Time: O(n^2) 11 | 12 | namespace CLRS { 13 | namespace CH2 { 14 | template 15 | void bubbleSort(vector& A) { 16 | for (int i = 0; i < A.size() - 1; i++) 17 | for (int j = A.size() - 1; j >= i + 1; j--) 18 | if (A[j] < A[j - 1]) { 19 | swap(A[j], A[j - 1]); 20 | print(A); 21 | } 22 | } 23 | } // namespace CH2 24 | } // namespace CLRS 25 | 26 | #endif -------------------------------------------------------------------------------- /Chap02/Problems/2-4.cpp: -------------------------------------------------------------------------------- 1 | #include "2-4.h" 2 | 3 | using namespace CLRS::CH2; 4 | 5 | int main() { 6 | print(string("Problem 2-4 Inversions")); 7 | 8 | cout << "Initialize an array A as 2-4 (a)\n"; 9 | vector A = {2, 3, 8, 6, 1}; 10 | print(A); 11 | 12 | cout << "\nPerform COUNT-INVERSIONS(A, 0, 4)\n" 13 | << "The inversions of A is " << countInversions(A, 0, 4) << endl; 14 | } -------------------------------------------------------------------------------- /Chap02/Problems/2-4.h: -------------------------------------------------------------------------------- 1 | #ifndef prob2_4_h 2 | #define prob2_4_h 3 | 4 | #include "../../print.h" 5 | 6 | using std::vector; 7 | 8 | // [Page 41] 9 | // MERGE-INVERSIONS(A, p, q, r) 10 | // - Time: O(n) 11 | // 12 | // COUNT-INVERSIONS(A) 13 | // - Time: O(n lg n) 14 | 15 | namespace CLRS { 16 | namespace CH2 { 17 | template 18 | int mergeInversions(vector& A, int p, int q, int r) { 19 | int n1 = q - p + 1; 20 | int n2 = r - q; 21 | vector L(n1 + 1), R(n2 + 1); 22 | for (int i = 0; i < n1; i++) 23 | L[i] = A[p + i]; 24 | for (int j = 0; j < n2; j++) 25 | R[j] = A[q + j + 1]; 26 | L[n1] = INT_MAX; 27 | R[n2] = INT_MAX; 28 | int i = 0; 29 | int j = 0; 30 | int inversions = 0; 31 | for (int k = p; k <= r; k++) { 32 | if (L[i] <= R[j]) { 33 | A[k] = L[i]; 34 | i = i + 1; 35 | } else { 36 | inversions = inversions + n1 - i; 37 | A[k] = R[j]; 38 | j = j + 1; 39 | } 40 | } 41 | return inversions; 42 | } 43 | 44 | template 45 | int countInversions(vector& A, int p, int r) { 46 | if (p < r) { 47 | int q = (p + r) / 2; 48 | int left = countInversions(A, p, q); 49 | int right = countInversions(A, q + 1, r); 50 | return mergeInversions(A, p, q, r) + left + right; 51 | } 52 | return 0; 53 | } 54 | } // namespace CH2 55 | } // namespace CLRS 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /Chap04/4.1.cpp: -------------------------------------------------------------------------------- 1 | #include "4.1.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH4; 6 | 7 | int main() { 8 | print(string("Chapter 4.1 The maximum-subarray problem")); 9 | 10 | cout << "Initialize an array A as Figure 4.3\n"; 11 | vector A = {13, -3, -25, 20, -3, -16, -23, 18, 12 | 20, -7, 12, -5, -22, 15, -4, 7}; 13 | print(A); 14 | 15 | Ans ans = findMaximumSubarray(A, 0, 15); 16 | cout << "\nPerform FIND-MAXIMUM-SUBARRAY(A, 0, 15)\n" 17 | << "The (low, high, sum) of the maximum subarray of A are (" << ans.low 18 | << ", " << ans.high << ", " << ans.sum << ")\n"; 19 | 20 | ans = bruteForceFindMaximumSubarray(A); 21 | cout << "\nPerform FIND-MAXIMUM-SUBARRAY-BRUTE-FORCE(A)\n" 22 | << "The (low, high, sum) of the maximum subarray of A are (" << ans.low 23 | << ", " << ans.high << ", " << ans.sum << ")\n"; 24 | 25 | ans = iterativeFindMaximumSubarray(A); 26 | cout << "\nPerform FIND-MAXIMUM-SUBARRAY-LINEAR(A)\n" 27 | << "The (low, high, sum) of the maximum subarray of A are (" << ans.low 28 | << ", " << ans.high << ", " << ans.sum << ")\n"; 29 | } -------------------------------------------------------------------------------- /Chap04/4.1.h: -------------------------------------------------------------------------------- 1 | #ifndef ch4_1_h 2 | #define ch4_1_h 3 | 4 | #include 5 | 6 | using std::vector; 7 | 8 | // [Page 71] 9 | // FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high) 10 | // - Time: O(n) 11 | // 12 | // [Page 72] 13 | // FIND-MAXIMUM-SUBARRAY(A, low, high) 14 | // - Time: O(n lg n) 15 | // 16 | // [Page 74][4.1-2] 17 | // BRUTE-FORCE-FIND-MAXIMUM-SUBARRAY(A) 18 | // - Time: O(n^2) 19 | // 20 | // [Page 75][4.1-5] 21 | // ITERATIVE-FIND-MAXIMUM-SUBARRAY(A) 22 | // - Time: O(n) 23 | 24 | namespace CLRS { 25 | namespace CH4 { 26 | template 27 | struct Ans { 28 | int low; 29 | int high; 30 | T sum; 31 | }; 32 | 33 | template 34 | Ans findMaxCrossingSubarray(const vector& A, int low, int mid, int high) { 35 | int maxLeft = 0; 36 | T leftSum = INT_MIN; 37 | T sum = 0; 38 | for (int i = mid; i >= low; --i) { 39 | sum = sum + A[i]; 40 | if (sum > leftSum) { 41 | leftSum = sum; 42 | maxLeft = i; 43 | } 44 | } 45 | int maxRight = 0; 46 | T rightSum = INT_MIN; 47 | sum = 0; 48 | for (int j = mid + 1; j <= high; ++j) { 49 | sum = sum + A[j]; 50 | if (sum > rightSum) { 51 | rightSum = sum; 52 | maxRight = j; 53 | } 54 | } 55 | return {maxLeft, maxRight, leftSum + rightSum}; 56 | } 57 | 58 | template 59 | Ans findMaximumSubarray(const vector& A, int low, int high) { 60 | if (high == low) { 61 | return {low, high, A[low]}; 62 | } else { 63 | const int mid = (low + high) / 2; 64 | Ans left = findMaximumSubarray(A, low, mid); 65 | Ans right = findMaximumSubarray(A, mid + 1, high); 66 | Ans cross = findMaxCrossingSubarray(A, low, mid, high); 67 | if (left.sum >= right.sum && left.sum >= cross.sum) 68 | return left; 69 | else if (right.sum >= left.sum && right.sum >= cross.sum) 70 | return right; 71 | else 72 | return cross; 73 | } 74 | } 75 | 76 | template 77 | Ans bruteForceFindMaximumSubarray(const vector& A) { 78 | int low = 0; 79 | int high = 0; 80 | T maxSum = INT_MIN; 81 | for (int i = 0; i < A.size(); ++i) { 82 | T sum = 0; 83 | for (int j = i; j < A.size(); ++j) { 84 | sum = sum + A[j]; 85 | if (sum > maxSum) { 86 | maxSum = sum; 87 | low = i; 88 | high = j; 89 | } 90 | } 91 | } 92 | return {low, high, maxSum}; 93 | } 94 | 95 | template 96 | Ans iterativeFindMaximumSubarray(vector& A) { 97 | int low = 0; 98 | int high = 0; 99 | T maxSum = INT_MIN; 100 | T sum = INT_MIN; 101 | for (int j = 0; j < A.size(); ++j) { 102 | int currentLow; 103 | int currentHigh = j; 104 | if (sum > 0) { 105 | sum = sum + A[j]; 106 | } else { 107 | currentLow = j; 108 | sum = A[j]; 109 | } 110 | if (sum > maxSum) { 111 | maxSum = sum; 112 | low = currentLow; 113 | high = currentHigh; 114 | } 115 | } 116 | return {low, high, maxSum}; 117 | } 118 | } // namespace CH4 119 | } // namespace CLRS 120 | 121 | #endif -------------------------------------------------------------------------------- /Chap04/4.2.cpp: -------------------------------------------------------------------------------- 1 | #include "4.2.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH4; 6 | 7 | int main() { 8 | print(string("Chapter 4.2 Strassen's algorithm for matrix multiplication")); 9 | 10 | cout << "Initialize two matrice as Exercise 4.2-1\n"; 11 | Matrix A({{1, 3}, {7, 5}}); 12 | Matrix B({{6, 8}, {4, 2}}); 13 | cout << "A = \n" << A << endl; 14 | cout << "B = \n" << B << endl; 15 | 16 | cout << "C = SQUARE-MATRIX-MULTIPLY(A, B) =\n"; 17 | Matrix C = squareMatrixMultiply(A, B); 18 | cout << C << endl; 19 | 20 | cout << "C = SQUARE-MATRIX-MULTIPLY-RECURSIVE(A, B) =\n"; 21 | C = squareMatrixMultiplyRecursive(A, B); 22 | cout << C << endl; 23 | 24 | cout << "C = STRASSEN(A, B) =\n"; 25 | C = strassen(A, B); 26 | cout << C << endl; 27 | } -------------------------------------------------------------------------------- /Chap04/4.2.h: -------------------------------------------------------------------------------- 1 | #ifndef ch4_2_h 2 | #define ch4_2_h 3 | 4 | #include 5 | 6 | #include "Matrix.cpp" 7 | 8 | using std::vector; 9 | 10 | // [Page 75] 11 | // SQUARE-MATRIX-MULTIPLY(A, B) 12 | // - Time: O(n^3) 13 | // 14 | // [Page 77] 15 | // SQUARE-MATRIX-MULTIPLY-RECURSIVE(A, B) 16 | // - Time: O(n^3) 17 | // 18 | // [Page 82][4.2-2] 19 | // STRASSEN(A, B) 20 | // - Time: O(n^(lg 7)) 21 | 22 | namespace CLRS { 23 | namespace CH4 { 24 | template 25 | Matrix squareMatrixMultiply(const Matrix& A, const Matrix& B) { 26 | return A * B; 27 | } 28 | 29 | template 30 | Matrix squareMatrixMultiplyRecursive(const Matrix& A, 31 | const Matrix& B) { 32 | const int m = A.getRows(); 33 | const int n = A.getCols(); 34 | 35 | Matrix C(m, n); 36 | 37 | if (n == 1) { 38 | C.getP()[0][0] = A.getP()[0][0] * B.getP()[0][0]; 39 | } else { 40 | Matrix C11 = squareMatrixMultiplyRecursive(A.get11(), B.get11()) + 41 | squareMatrixMultiplyRecursive(A.get12(), B.get21()); 42 | Matrix C12 = squareMatrixMultiplyRecursive(A.get11(), B.get12()) + 43 | squareMatrixMultiplyRecursive(A.get12(), B.get22()); 44 | Matrix C21 = squareMatrixMultiplyRecursive(A.get21(), B.get11()) + 45 | squareMatrixMultiplyRecursive(A.get22(), B.get21()); 46 | Matrix C22 = squareMatrixMultiplyRecursive(A.get21(), B.get12()) + 47 | squareMatrixMultiplyRecursive(A.get22(), B.get22()); 48 | C = combine(C11, C12, C21, C22); 49 | } 50 | 51 | return C; 52 | } 53 | 54 | template 55 | Matrix strassen(Matrix A, Matrix B) { 56 | const int m = A.getRows(); 57 | const int n = A.getCols(); 58 | 59 | if (n == 1) 60 | return Matrix({{A.getP()[0][0] * B.getP()[0][0]}}); 61 | 62 | Matrix C(m, n); 63 | Matrix A11 = A.get11(); 64 | Matrix A12 = A.get12(); 65 | Matrix A21 = A.get21(); 66 | Matrix A22 = A.get22(); 67 | Matrix B11 = B.get11(); 68 | Matrix B12 = B.get12(); 69 | Matrix B21 = B.get21(); 70 | Matrix B22 = B.get22(); 71 | 72 | Matrix S1 = B12 - B22; 73 | Matrix S2 = A11 + A12; 74 | Matrix S3 = A21 + A22; 75 | Matrix S4 = B21 - B11; 76 | Matrix S5 = A11 + A22; 77 | Matrix S6 = B11 + B22; 78 | Matrix S7 = A12 - A22; 79 | Matrix S8 = B21 + B22; 80 | Matrix S9 = A11 - A21; 81 | Matrix S10 = B11 + B12; 82 | 83 | Matrix P1 = strassen(A11, S1); 84 | Matrix P2 = strassen(S2, B22); 85 | Matrix P3 = strassen(S3, B11); 86 | Matrix P4 = strassen(A22, S4); 87 | Matrix P5 = strassen(S5, S6); 88 | Matrix P6 = strassen(S7, S8); 89 | Matrix P7 = strassen(S9, S10); 90 | 91 | Matrix C11 = P5 + P4 - P2 + P6; 92 | Matrix C12 = P1 + P2; 93 | Matrix C21 = P3 + P4; 94 | Matrix C22 = P5 + P1 - P3 - P7; 95 | 96 | C = combine(C11, C12, C21, C22); 97 | 98 | return C; 99 | } 100 | } // namespace CH4 101 | } // namespace CLRS 102 | 103 | #endif -------------------------------------------------------------------------------- /Chap04/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-Wall 3 | EXEC=run 4 | 5 | run: 6 | $(CXX) -std=c++2a $(CFLAGS) ./4.1.cpp -o 4.1.out 7 | $(CXX) -std=c++2a $(CFLAGS) ./4.2.cpp -o 4.2.out 8 | clear 9 | 10 | clean: 11 | rm *.out -------------------------------------------------------------------------------- /Chap04/Matrix.cpp: -------------------------------------------------------------------------------- 1 | #include "Matrix.h" 2 | 3 | template 4 | Matrix::Matrix(int rows, int cols) : rows(rows), cols(cols) { 5 | allocateMemories(); 6 | } 7 | 8 | template 9 | Matrix::Matrix(const Matrix& matrix) 10 | : rows(matrix.rows), cols(matrix.cols) { 11 | allocateMemories(); 12 | for (int i = 0; i < rows; i++) { 13 | for (int j = 0; j < cols; j++) { 14 | p[i][j] = matrix.p[i][j]; 15 | } 16 | } 17 | } 18 | 19 | template 20 | Matrix::Matrix(const std::vector>& vec) 21 | : rows(vec.size()), cols(vec[0].size()) { 22 | allocateMemories(); 23 | for (int i = 0; i < rows; i++) { 24 | for (int j = 0; j < cols; j++) { 25 | p[i][j] = vec[i][j]; 26 | } 27 | } 28 | } 29 | 30 | template 31 | Matrix Matrix::get11() const { 32 | Matrix m(rows / 2, cols / 2); 33 | for (int i = 0; i < rows / 2; i++) { 34 | for (int j = 0; j < cols / 2; j++) { 35 | m.p[i][j] = p[i][j]; 36 | } 37 | } 38 | return m; 39 | } 40 | 41 | template 42 | Matrix Matrix::get12() const { 43 | Matrix m(rows / 2, cols - cols / 2); 44 | for (int i = 0; i < rows / 2; i++) { 45 | for (int j = 0; j < cols - cols / 2; j++) { 46 | m.p[i][j] = p[i][j + cols / 2]; 47 | } 48 | } 49 | return m; 50 | } 51 | 52 | template 53 | Matrix Matrix::get21() const { 54 | Matrix m(rows - rows / 2, cols / 2); 55 | for (int i = 0; i < rows - rows / 2; i++) { 56 | for (int j = 0; j < cols / 2; j++) { 57 | m.p[i][j] = p[i + rows / 2][j]; 58 | } 59 | } 60 | return m; 61 | } 62 | 63 | template 64 | Matrix Matrix::get22() const { 65 | Matrix m(rows - rows / 2, cols - cols / 2); 66 | for (int i = 0; i < rows - rows / 2; i++) { 67 | for (int j = 0; j < cols - cols / 2; j++) { 68 | m.p[i][j] = p[i + rows / 2][j + cols / 2]; 69 | } 70 | } 71 | return m; 72 | } 73 | 74 | template 75 | Matrix operator+(const Matrix& lhs, const Matrix& rhs) { 76 | Matrix res(lhs); 77 | for (int i = 0; i < res.rows; i++) { 78 | for (int j = 0; j < res.cols; j++) { 79 | res.p[i][j] += rhs.p[i][j]; 80 | } 81 | } 82 | return res; 83 | } 84 | 85 | template 86 | Matrix operator-(const Matrix& lhs, const Matrix& rhs) { 87 | Matrix res(lhs); 88 | for (int i = 0; i < res.rows; i++) { 89 | for (int j = 0; j < res.cols; j++) { 90 | res.p[i][j] -= rhs.p[i][j]; 91 | } 92 | } 93 | return res; 94 | } 95 | 96 | template 97 | Matrix operator*(const Matrix& lhs, const Matrix& rhs) { 98 | Matrix res(lhs.rows, rhs.cols); 99 | for (int i = 0; i < res.rows; i++) { 100 | for (int j = 0; j < res.cols; j++) { 101 | for (int k = 0; k < res.rows; k++) { 102 | res.p[i][j] += lhs.p[i][k] * rhs.p[k][j]; 103 | } 104 | } 105 | } 106 | return res; 107 | } 108 | 109 | template 110 | Matrix combine(const Matrix& m11, const Matrix& m12, 111 | const Matrix& m21, const Matrix& m22) { 112 | int m = m11.rows + m21.rows; 113 | int n = m11.cols + m12.cols; 114 | 115 | Matrix matrix(m, n); 116 | 117 | int y = m / 2; 118 | int x = n / 2; 119 | for (int i = 0; i < y; i++) { 120 | for (int j = 0; j < x; j++) 121 | matrix.p[i][j] = m11.p[i][j]; 122 | for (int j = 0; j < n - x; j++) 123 | matrix.p[i][j + x] = m12.p[i][j]; 124 | } 125 | 126 | for (int i = 0; i < m - y; i++) { 127 | for (int j = 0; j < x; j++) 128 | matrix.p[i + y][j] = m21.p[i][j]; 129 | for (int j = 0; j < x; j++) 130 | matrix.p[i + y][j + x] = m22.p[i][j]; 131 | } 132 | 133 | return matrix; 134 | } 135 | 136 | template 137 | void Matrix::allocateMemories() { 138 | p = new T*[rows]; 139 | for (int i = 0; i < rows; i++) { 140 | p[i] = new T[cols]; 141 | for (int j = 0; j < cols; ++j) 142 | p[i][j] = 0; 143 | } 144 | } -------------------------------------------------------------------------------- /Chap04/Matrix.h: -------------------------------------------------------------------------------- 1 | #ifndef Matrix_h 2 | #define Matrix_h 3 | 4 | #include 5 | 6 | template 7 | class Matrix { 8 | T** p; 9 | int rows; 10 | int cols; 11 | void allocateMemories(); 12 | 13 | public: 14 | Matrix(int, int); 15 | Matrix(const Matrix&); 16 | Matrix(const std::vector>&); 17 | 18 | Matrix get11() const; 19 | Matrix get12() const; 20 | Matrix get21() const; 21 | Matrix get22() const; 22 | 23 | int getRows() const { 24 | return rows; 25 | } 26 | 27 | int getCols() const { 28 | return cols; 29 | } 30 | 31 | T** getP() const { 32 | return p; 33 | } 34 | 35 | inline T& operator()(int x, int y) { 36 | return p[x][y]; 37 | } 38 | 39 | template 40 | friend Matrix operator+(const Matrix& lhs, const Matrix& rhs); 41 | 42 | template 43 | friend Matrix operator-(const Matrix& lhs, const Matrix& rhs); 44 | 45 | template 46 | friend Matrix operator*(const Matrix& lhs, const Matrix& rhs); 47 | 48 | template 49 | friend Matrix combine(const Matrix& m11, const Matrix& m12, 50 | const Matrix& m21, const Matrix& m22); 51 | 52 | friend std::ostream& operator<<(std::ostream& os, const Matrix& matrix) { 53 | for (int i = 0; i < matrix.rows; i++) { 54 | for (int j = 0; j < matrix.cols; j++) { 55 | os << matrix.p[i][j] << " "; 56 | } 57 | os << std::endl; 58 | } 59 | return os; 60 | } 61 | }; 62 | 63 | #endif -------------------------------------------------------------------------------- /Chap05/5.1.cpp: -------------------------------------------------------------------------------- 1 | #include "5.1.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH5; 6 | 7 | int main() { 8 | print(string("Chapter 5.1 The hiring problem")); 9 | 10 | cout << "RANDOM(3, 7) = " << random(3, 7) << endl; 11 | } -------------------------------------------------------------------------------- /Chap05/5.1.h: -------------------------------------------------------------------------------- 1 | #ifndef ch5_1_h 2 | #define ch5_1_h 3 | 4 | #include 5 | 6 | // [Page 117] 7 | // RANDOM(a, b) 8 | // - Time: O(lg(a - b)) 9 | 10 | namespace CLRS { 11 | namespace CH5 { 12 | int RANDOM() { 13 | unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); 14 | std::mt19937_64 generator(seed); 15 | std::uniform_int_distribution distribution(0, 1); 16 | return distribution(generator); 17 | } 18 | 19 | int random(int a, int b) { 20 | if (a == b) 21 | return a; 22 | double mid = (a + b) / 2; 23 | int r = RANDOM(); 24 | if (r == 0) 25 | return random(a, (int)floor(mid)); 26 | else 27 | return random((int)ceil(mid), b); 28 | } 29 | } // namespace CH5 30 | } // namespace CLRS 31 | 32 | #endif -------------------------------------------------------------------------------- /Chap05/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-Wall 3 | EXEC=run 4 | 5 | run: 6 | $(CXX) -std=c++2a $(CFLAGS) ./5.1.cpp -o 5.1.out 7 | clear 8 | 9 | clean: 10 | rm *.out -------------------------------------------------------------------------------- /Chap06/6.1.h: -------------------------------------------------------------------------------- 1 | #ifndef ch6_1_h 2 | #define ch6_1_h 3 | 4 | // [Page 152] 5 | // PARENT(i) 6 | // - Time: O(1) 7 | // 8 | // [Page 152] 9 | // LEFT(i) 10 | // - Time: O(1) 11 | // 12 | // [Page 152] 13 | // RIGHT(i) 14 | // - Time: O(1) 15 | 16 | namespace CLRS { 17 | namespace CH6 { 18 | int parent(int i) { 19 | return (i - 1) / 2; 20 | } 21 | 22 | int left(int i) { 23 | return 2 * i + 1; 24 | } 25 | 26 | int right(int i) { 27 | return 2 * i + 2; 28 | } 29 | } // namespace CH6 30 | } // namespace CLRS 31 | 32 | #endif -------------------------------------------------------------------------------- /Chap06/6.2.cpp: -------------------------------------------------------------------------------- 1 | #include "6.2.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH6; 6 | 7 | int main() { 8 | print(string("Chapter 6.2 Maintaining the heap property")); 9 | 10 | cout << "Initialize a heap A as Figure 6.2\n"; 11 | Heap A = {16, 4, 10, 14, 7, 9, 3, 2, 8, 1}; 12 | A.setHeapsize(); 13 | print(A); 14 | 15 | cout << "\nPerform MAX-HEAPIFY(A, 1)\n"; 16 | maxHeapify(A, 1); 17 | print(A); 18 | 19 | A = {16, 4, 10, 14, 7, 9, 3, 2, 8, 1}; 20 | A.setHeapsize(); 21 | cout << "\nPerform ITERATIVE-MAX-HEAPIFY(A, 1)\n"; 22 | iterativeMaxHeapify(A, 1); 23 | print(A); 24 | } -------------------------------------------------------------------------------- /Chap06/6.2.h: -------------------------------------------------------------------------------- 1 | #ifndef ch6_2_h 2 | #define ch6_2_h 3 | 4 | #include "6.1.h" 5 | #include "Heap.h" 6 | 7 | using std::swap; 8 | 9 | // [Page 154] 10 | // MAX-HEAPIFY(A, i) 11 | // - Time: O(lg n) 12 | // 13 | // [Page 156] 14 | // MIN-HEAPIFY(A, i) 15 | // - Time: O(lg n) 16 | // 17 | // ITERATIVE-MAX-HEAPIFY(A, i) 18 | // - Time: O(lg n) 19 | 20 | namespace CLRS { 21 | namespace CH6 { 22 | template 23 | void maxHeapify(Heap& A, int i) { 24 | int l = left(i); 25 | int r = right(i); 26 | int largest; 27 | if (l <= A.heapsize - 1 && A[l] > A[i]) 28 | largest = l; 29 | else 30 | largest = i; 31 | if (r <= A.heapsize - 1 && A[r] > A[largest]) 32 | largest = r; 33 | if (largest != i) { 34 | swap(A[i], A[largest]); 35 | maxHeapify(A, largest); 36 | } 37 | } 38 | 39 | template 40 | void minHeapify(Heap& A, int i) { 41 | int l = left(i); 42 | int r = right(i); 43 | int smallest; 44 | if (l <= A.heapsize - 1 && A[l] < A[i]) 45 | smallest = l; 46 | else 47 | smallest = i; 48 | if (r <= A.heapsize - 1 && A[r] < A[smallest]) 49 | smallest = r; 50 | if (smallest != i) { 51 | swap(A[i], A[smallest]); 52 | minHeapify(A, smallest); 53 | } 54 | } 55 | 56 | template 57 | void iterativeMaxHeapify(Heap& A, int i) { 58 | while (true) { 59 | int l = left(i); 60 | int r = right(i); 61 | int largest; 62 | if (l <= A.heapsize - 1 && A[l] > A[i]) 63 | largest = l; 64 | else 65 | largest = i; 66 | if (r <= A.heapsize - 1 && A[r] > A[largest]) 67 | largest = r; 68 | if (largest == i) 69 | return; 70 | swap(A[i], A[largest]); 71 | i = largest; 72 | } 73 | } 74 | } // namespace CH6 75 | } // namespace CLRS 76 | 77 | #endif -------------------------------------------------------------------------------- /Chap06/6.3.cpp: -------------------------------------------------------------------------------- 1 | #include "6.3.h" 2 | 3 | using namespace CLRS::CH6; 4 | 5 | int main() { 6 | print(string("Chapter 6.3 Building a heap")); 7 | 8 | cout << "Initialize a heap A as Figure 6.3\n"; 9 | Heap A = {4, 1, 3, 2, 16, 9, 10, 14, 8, 7}; 10 | A.setHeapsize(); 11 | print(A); 12 | 13 | cout << "\nPerform BUILD-MAX-HEAP(A)\n"; 14 | buildMaxHeap(A); 15 | } -------------------------------------------------------------------------------- /Chap06/6.3.h: -------------------------------------------------------------------------------- 1 | #ifndef ch6_3_h 2 | #define ch6_3_h 3 | 4 | #include "../print.h" 5 | #include "6.2.h" 6 | #include "Heap.h" 7 | 8 | // [Page 157] 9 | // BUILD-MAX-HEAP(A) 10 | // - Time: O(n) 11 | 12 | namespace CLRS { 13 | namespace CH6 { 14 | template 15 | void buildMaxHeap(Heap& A) { 16 | for (int i = A.heapsize / 2; i >= 0; i--) { 17 | maxHeapify(A, i); 18 | print(A); 19 | } 20 | } 21 | } // namespace CH6 22 | } // namespace CLRS 23 | 24 | #endif -------------------------------------------------------------------------------- /Chap06/6.4.cpp: -------------------------------------------------------------------------------- 1 | #include "6.4.h" 2 | 3 | using namespace CLRS::CH6; 4 | 5 | int main() { 6 | print(string("Chapter 6.4 The heapsort algorithm")); 7 | 8 | cout << "Initialize a heap A as Figure 6.4\n"; 9 | Heap A = {16, 14, 10, 8, 7, 9, 3, 2, 4, 1}; 10 | A.setHeapsize(); 11 | print(A); 12 | 13 | cout << "\nPerform HEAPSORT(A)\n"; 14 | heapsort(A); 15 | } -------------------------------------------------------------------------------- /Chap06/6.4.h: -------------------------------------------------------------------------------- 1 | #ifndef ch6_4_h 2 | #define ch6_4_h 3 | 4 | #include "../print.h" 5 | #include "6.2.h" 6 | #include "6.3.h" 7 | #include "Heap.h" 8 | 9 | // [Page 160] 10 | // HEAPSORT(A) 11 | // - Time: O(n lg n) 12 | 13 | namespace CLRS { 14 | namespace CH6 { 15 | template 16 | void heapsort(Heap& A) { 17 | buildMaxHeap(A); 18 | for (int i = A.heapsize - 1; i >= 1; i--) { 19 | swap(A[0], A[i]); 20 | A.heapsize--; 21 | maxHeapify(A, 0); 22 | print(A); 23 | } 24 | } 25 | } // namespace CH6 26 | } // namespace CLRS 27 | 28 | #endif -------------------------------------------------------------------------------- /Chap06/6.5.cpp: -------------------------------------------------------------------------------- 1 | #include "6.5.h" 2 | 3 | using namespace CLRS::CH6; 4 | 5 | int main() { 6 | print(string("Chapter 6.5 Priority queues")); 7 | 8 | cout << "Initialize a heap A as Figure 6.5\n"; 9 | Heap A = {16, 14, 10, 8, 7, 9, 3, 2, 4, 1}; 10 | A.setHeapsize(); 11 | print(A); 12 | cout << "\nPerform HEAP-INCREASE-KEY(A, 8, 15)\n"; 13 | heapIncreaseKey(A, 8, 15); 14 | print(A); 15 | 16 | cout << "\nInitialize a heap A as Exercise 6.5-1\n"; 17 | A = {15, 13, 9, 5, 12, 8, 7, 4, 0, 6, 2, 1}; 18 | A.setHeapsize(); 19 | print(A); 20 | cout << "\nPerform HEAP-EXTRACT-MAX(A)\n"; 21 | heapExtractMax(A); 22 | print(A); 23 | 24 | cout << "\nInitialize a heap A as Exercise 6.5-2\n"; 25 | A = {15, 13, 9, 5, 12, 8, 7, 4, 0, 6, 2, 1}; 26 | A.setHeapsize(); 27 | print(A); 28 | cout << "\nPerform MAX-HEAP-INSERT(A, 10)\n"; 29 | maxHeapInsert(A, 10); 30 | print(A); 31 | } -------------------------------------------------------------------------------- /Chap06/6.5.h: -------------------------------------------------------------------------------- 1 | #ifndef ch6_5_h 2 | #define ch6_5_h 3 | 4 | #include "../print.h" 5 | #include "6.2.h" 6 | #include "6.3.h" 7 | #include "Heap.h" 8 | 9 | // [Page 163] 10 | // HEAP-MAXIMUM(A) 11 | // - Time: O(1) 12 | // 13 | // HEAP-EXTRACT-MAX(A) 14 | // - Time: O(lg n) 15 | // 16 | // [Page 164] 17 | // HEAP-INCREASE0KEY(A, i, key) 18 | // - Time: O(lg n) 19 | // 20 | // MAX-HEAP-INSERT(A, key) 21 | // - Time: O(lg n) 22 | 23 | namespace CLRS { 24 | namespace CH6 { 25 | template 26 | int heapMaximum(Heap& A) { 27 | return A[0]; 28 | } 29 | 30 | template 31 | T heapExtractMax(Heap& A) { 32 | if (A.heapsize < 1) 33 | throw("heap underflow"); 34 | T max = A[0]; 35 | A[0] = A[A.heapsize - 1]; 36 | A.heapsize--; 37 | maxHeapify(A, 0); 38 | return max; 39 | } 40 | 41 | template 42 | void heapIncreaseKey(Heap& A, int i, T key) { 43 | if (key < A[i]) 44 | throw("new key is smaller than current key"); 45 | A[i] = key; 46 | while (i > 0 && A[parent(i)] < A[i]) { 47 | swap(A[i], A[parent(i)]); 48 | i = parent(i); 49 | } 50 | } 51 | 52 | template 53 | void maxHeapInsert(Heap& A, T key) { 54 | A.heapsize++; 55 | A[A.heapsize - 1] = INT_MIN; 56 | heapIncreaseKey(A, A.heapsize - 1, key); 57 | } 58 | } // namespace CH6 59 | } // namespace CLRS 60 | 61 | #endif -------------------------------------------------------------------------------- /Chap06/Heap.h: -------------------------------------------------------------------------------- 1 | #ifndef Heap_h 2 | #define Heap_h 3 | 4 | #include 5 | 6 | using std::vector; 7 | 8 | template 9 | class Heap : private vector { 10 | public: 11 | using vector::vector; 12 | using vector::operator[]; 13 | using vector::size; 14 | 15 | int heapsize; 16 | void setHeapsize(); 17 | }; 18 | 19 | template 20 | void Heap::setHeapsize() { 21 | heapsize = this->size(); 22 | } 23 | 24 | #endif -------------------------------------------------------------------------------- /Chap06/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-Wall 3 | EXEC=run 4 | 5 | run: 6 | $(CXX) -std=c++2a $(CFLAGS) ./6.2.cpp -o 6.2.out 7 | $(CXX) -std=c++2a $(CFLAGS) ./6.3.cpp -o 6.3.out 8 | $(CXX) -std=c++2a $(CFLAGS) ./6.4.cpp -o 6.4.out 9 | $(CXX) -std=c++2a $(CFLAGS) ./6.5.cpp -o 6.5.out 10 | clear 11 | 12 | clean: 13 | rm *.out -------------------------------------------------------------------------------- /Chap07/7.1.cpp: -------------------------------------------------------------------------------- 1 | #include "7.1.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH7; 6 | 7 | int main() { 8 | print(string("Chapter 7.1 Description of quicksort")); 9 | 10 | cout << "Initialize an array A as Figure 7.1\n"; 11 | vector A = {2, 8, 7, 1, 3, 5, 6, 4}; 12 | print(A); 13 | 14 | cout << "\nPerform PARTITION(A, 0, 7)\n"; 15 | partition(A, 0, 7); 16 | print(A); 17 | 18 | cout << "\nPerform QUICKSORT(A, 0, 7)\n"; 19 | quicksort(A, 0, 7); 20 | print(A); 21 | } -------------------------------------------------------------------------------- /Chap07/7.1.h: -------------------------------------------------------------------------------- 1 | #ifndef ch7_1_h 2 | #define ch7_1_h 3 | 4 | #include 5 | 6 | #include "../print.h" 7 | 8 | using std::swap; 9 | using std::vector; 10 | 11 | // [Page 171] 12 | // QUICKSORT(A, p, r) 13 | // - Average time: O(n lg n) 14 | // - Worst time: O(n^2) 15 | // 16 | // PARTITION(A, p, r) 17 | // - Time: O(n) 18 | 19 | namespace CLRS { 20 | namespace CH7 { 21 | template 22 | int partition(vector& A, int p, int r); 23 | 24 | template 25 | void quicksort(vector& A, int p, int r) { 26 | if (p < r) { 27 | int q = partition(A, p, r); 28 | quicksort(A, p, q - 1); 29 | quicksort(A, q + 1, r); 30 | } 31 | } 32 | 33 | template 34 | int partition(vector& A, int p, int r) { 35 | T x = A[r]; 36 | int i = p - 1; 37 | for (int j = p; j <= r - 1; j++) { 38 | if (A[j] <= x) { 39 | i = i + 1; 40 | swap(A[i], A[j]); 41 | } 42 | print(A); 43 | } 44 | swap(A[i + 1], A[r]); 45 | return i + 1; 46 | } 47 | } // namespace CH7 48 | } // namespace CLRS 49 | 50 | #endif -------------------------------------------------------------------------------- /Chap07/7.3.cpp: -------------------------------------------------------------------------------- 1 | #include "7.3.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH7; 6 | 7 | int main() { 8 | print(string("Chapter 7.3 A randomized version of quicksort")); 9 | 10 | cout << "Initialize an array A as Figure 7.1\n"; 11 | vector A = {2, 8, 7, 1, 3, 5, 6, 4}; 12 | print(A); 13 | 14 | cout << "\nPerform RANDOMIZED-QUICKSORT(A, 0, 7)\n"; 15 | randomizedQuicksort(A, 0, 7); 16 | print(A); 17 | } -------------------------------------------------------------------------------- /Chap07/7.3.h: -------------------------------------------------------------------------------- 1 | #ifndef ch7_3_h 2 | #define ch7_3_h 3 | 4 | #include "../Chap05/5.1.h" 5 | #include "../print.h" 6 | #include "7.1.h" 7 | 8 | // [Page 179] 9 | // RANDOMIZED-PARTITION(A, p, r) 10 | // - Time: O(n) 11 | // 12 | // RANDOMIZED-QUICKSORT(A, p, r) 13 | // - Average time: O(n lg n) 14 | // - Worst time: O(n^2) 15 | 16 | namespace CLRS { 17 | namespace CH7 { 18 | template 19 | int randomizedPartition(vector& A, int p, int r) { 20 | int i = CH5::random(p, r); 21 | swap(A[r], A[i]); 22 | return partition(A, p, r); 23 | } 24 | 25 | template 26 | void randomizedQuicksort(vector& A, int p, int r) { 27 | if (p < r) { 28 | int q = randomizedPartition(A, p, r); 29 | randomizedQuicksort(A, p, q - 1); 30 | randomizedQuicksort(A, q + 1, r); 31 | } 32 | } 33 | } // namespace CH7 34 | } // namespace CLRS 35 | 36 | #endif -------------------------------------------------------------------------------- /Chap07/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-Wall 3 | EXEC=run 4 | 5 | run: 6 | $(CXX) -std=c++2a $(CFLAGS) ./7.1.cpp -o 7.1.out 7 | $(CXX) -std=c++2a $(CFLAGS) ./7.3.cpp -o 7.3.out 8 | $(CXX) -std=c++2a $(CFLAGS) ./Problems/7-1.cpp -o 7-1.out 9 | $(CXX) -std=c++2a $(CFLAGS) ./Problems/7-2.cpp -o 7-2.out 10 | $(CXX) -std=c++2a $(CFLAGS) ./Problems/7-4.cpp -o 7-4.out 11 | $(CXX) -std=c++2a $(CFLAGS) ./Problems/7-6.cpp -o 7-6.out 12 | clear 13 | 14 | clean: 15 | rm *.out -------------------------------------------------------------------------------- /Chap07/Problems/7-1.cpp: -------------------------------------------------------------------------------- 1 | #include "7-1.h" 2 | 3 | #include "../../print.h" 4 | 5 | using namespace CLRS::CH7; 6 | 7 | int main() { 8 | print(string("Problem 7-1 Hoare partition correctness")); 9 | 10 | cout << "Initialize an array A as 7-1 (a)\n"; 11 | vector A = {13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21}; 12 | print(A); 13 | 14 | cout << "\nPerform HOARE-QUICKSORT(A, 0, 11)\n"; 15 | hoareQuicksort(A, 0, 11); 16 | print(A); 17 | } -------------------------------------------------------------------------------- /Chap07/Problems/7-1.h: -------------------------------------------------------------------------------- 1 | #ifndef prob7_1_h 2 | #define prob7_1_h 3 | 4 | #include 5 | 6 | using std::swap; 7 | using std::vector; 8 | 9 | // [Page 185] 10 | // HOARE-PARTITION(A, p, r) 11 | // - Time: O(n) 12 | // 13 | // HOARE-QUICKSORT(A, p, r) 14 | // - Average time: O(n lg n) 15 | // - Worst time: O(n^2) 16 | 17 | namespace CLRS { 18 | namespace CH7 { 19 | template 20 | int hoarePartition(vector& A, int p, int r) { 21 | T x = A[p]; 22 | int i = p - 1; 23 | int j = r + 1; 24 | while (true) { 25 | do { 26 | j = j - 1; 27 | } while (A[j] > x); 28 | do { 29 | i = i + 1; 30 | } while (A[i] < x); 31 | if (i < j) 32 | swap(A[i], A[j]); 33 | else 34 | return j; 35 | } 36 | } 37 | 38 | template 39 | void hoareQuicksort(vector& A, int p, int r) { 40 | if (p < r) { 41 | int q = hoarePartition(A, p, r); 42 | hoareQuicksort(A, p, q - 1); 43 | hoareQuicksort(A, q + 1, r); 44 | } 45 | } 46 | } // namespace CH7 47 | } // namespace CLRS 48 | 49 | #endif -------------------------------------------------------------------------------- /Chap07/Problems/7-2.cpp: -------------------------------------------------------------------------------- 1 | #include "7-2.h" 2 | 3 | #include "../../print.h" 4 | 5 | using namespace CLRS::CH7; 6 | 7 | int main() { 8 | print(string("Problem 7-2 Hoare partition correctness")); 9 | 10 | cout << "Initialize an array A as 7-1 (a)\n"; 11 | vector A = {13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21}; 12 | print(A); 13 | 14 | cout << "\nPerform QUICKSORT'(A, 0, 11)\n"; 15 | quicksort_(A, 0, 11); 16 | print(A); 17 | } -------------------------------------------------------------------------------- /Chap07/Problems/7-2.h: -------------------------------------------------------------------------------- 1 | #ifndef prob7_2_h 2 | #define prob7_2_h 3 | 4 | #include 5 | 6 | using std::swap; 7 | using std::vector; 8 | 9 | // [Page 186] 10 | // PARTITION'(A, p, r) 11 | // - Time: O(n) 12 | // 13 | // QUICKSORT'(A, p, r) 14 | // - Average time: O(n lg n) 15 | // - Worst time: O(n^2) 16 | 17 | namespace CLRS { 18 | namespace CH7 { 19 | template 20 | vector partition_(vector& A, int p, int r) { 21 | T x = A[p]; 22 | int low = p; 23 | int high = p; 24 | for (int j = p + 1; j <= r; j++) { 25 | if (A[j] < x) { 26 | int y = A[j]; 27 | A[j] = A[high + 1]; 28 | A[high + 1] = A[low]; 29 | A[low] = y; 30 | low++; 31 | high++; 32 | } else if (A[j] == x) { 33 | swap(A[high + 1], A[j]); 34 | high++; 35 | } 36 | } 37 | return {low, high}; 38 | } 39 | 40 | template 41 | void quicksort_(vector& A, int p, int r) { 42 | if (p < r) { 43 | vector bound = partition_(A, p, r); 44 | quicksort_(A, p, bound[0] - 1); 45 | quicksort_(A, bound[1] + 1, r); 46 | } 47 | } 48 | } // namespace CH7 49 | } // namespace CLRS 50 | 51 | #endif -------------------------------------------------------------------------------- /Chap07/Problems/7-4.cpp: -------------------------------------------------------------------------------- 1 | #include "7-4.h" 2 | 3 | #include "../../print.h" 4 | 5 | using namespace CLRS::CH7; 6 | 7 | int main() { 8 | print(string("Problem 7-4 Stack depth for quicksort")); 9 | 10 | cout << "Initialize an array A as 7-1 (a)\n"; 11 | vector A = {13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21}; 12 | print(A); 13 | 14 | cout << "\nPerform TAIL-RECURSIVE-QUICKSORT(A, 0, 11)\n"; 15 | tailRecursiveQuicksort(A, 0, 11); 16 | 17 | A = {13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21}; 18 | cout << "\nPerform MODIFIED-TAIL-RECURSIVE-QUICKSORT(A, 0, 11)\n"; 19 | modifiedTailRecursiveQuicksort(A, 0, 11); 20 | print(A); 21 | } -------------------------------------------------------------------------------- /Chap07/Problems/7-4.h: -------------------------------------------------------------------------------- 1 | #ifndef prob7_4_h 2 | #define prob7_4_h 3 | 4 | #include 5 | 6 | #include "../7.1.h" 7 | 8 | using std::swap; 9 | using std::vector; 10 | 11 | // [Page 188] 12 | // TAIL-RECURSIVE-QUICKSORT(A, p, r) 13 | // - Average time: O(n lg n) 14 | // - Worst time: O(n^2) 15 | // 16 | // MODIFIED-TAIL-RECURSIVE-QUICKSORT(A, p, r) 17 | // - Average time: O(n lg n) 18 | // - Worst time: O(n^2) 19 | 20 | namespace CLRS { 21 | namespace CH7 { 22 | template 23 | void tailRecursiveQuicksort(vector& A, int p, int r) { 24 | while (p < r) { 25 | int q = partition(A, p, r); 26 | tailRecursiveQuicksort(A, p, q - 1); 27 | p = q + 1; 28 | } 29 | } 30 | 31 | template 32 | void modifiedTailRecursiveQuicksort(vector& A, int p, int r) { 33 | while (p < r) { 34 | int q = partition(A, p, r); 35 | if (q < (p + r) / 2) { 36 | modifiedTailRecursiveQuicksort(A, p, q - 1); 37 | p = q + 1; 38 | } else { 39 | modifiedTailRecursiveQuicksort(A, q + 1, r); 40 | r = q - 1; 41 | } 42 | } 43 | } 44 | } // namespace CH7 45 | } // namespace CLRS 46 | 47 | #endif -------------------------------------------------------------------------------- /Chap07/Problems/7-6.cpp: -------------------------------------------------------------------------------- 1 | #include "7-6.h" 2 | 3 | using namespace CLRS::CH7; 4 | 5 | void printIntervals(vector& A) { 6 | for (int i = 0; i < A.size(); i++) { 7 | cout << "(" << A[i].a << ", " << A[i].b << ")" << endl; 8 | } 9 | } 10 | 11 | int main() { 12 | print(string("Problem 7-6 Fuzzy sorting of intervals")); 13 | 14 | cout << "Initialize an array of interval A\n"; 15 | vector A = {{2, 3}, {0, 2}, {6, 8}, {7, 8}, {2, 4}, 16 | {0, 1}, {4, 6}, {1, 2}, {9, 10}, {5, 6}}; 17 | printIntervals(A); 18 | 19 | cout << "\nPerform FUZZY-SORT(A, 0, 9)\n"; 20 | fuzzySort(A, 0, 14); 21 | printIntervals(A); 22 | } -------------------------------------------------------------------------------- /Chap07/Problems/7-6.h: -------------------------------------------------------------------------------- 1 | #ifndef prob7_6_h 2 | #define prob7_6_h 3 | 4 | #include 5 | 6 | #include "../../Chap05/5.1.h" 7 | #include "../7.1.h" 8 | 9 | using std::swap; 10 | using std::vector; 11 | 12 | typedef struct { 13 | int a; 14 | int b; 15 | } Interval; 16 | 17 | // [Page 189] 18 | // FIND-INTERSECTION(A, p, r) 19 | // - Time: O(n) 20 | // 21 | // PARTITION-RIGHT(A, a, p, r) 22 | // - Time: O(n) 23 | // 24 | // PARTITION-LEFT(A, b, p, t) 25 | // - Time: O(n) 26 | // 27 | // FUZZY-SORT(A, p, r) 28 | // - Time: O(n log n) 29 | // - Best time: O(n) (when all of the intervals overlap) 30 | 31 | namespace CLRS { 32 | namespace CH7 { 33 | Interval findIntersection(vector& A, int p, int r) { 34 | int rand = CH5::random(p, r); 35 | swap(A[rand], A[r]); 36 | int a = A[r].a; 37 | int b = A[r].b; 38 | for (int i = p; i <= r - 1; i++) { 39 | if (A[i].a <= b && A[i].b >= a) { 40 | if (A[i].a > a) 41 | a = A[i].a; 42 | if (A[i].b < b) 43 | b = A[i].b; 44 | } 45 | } 46 | return {a, b}; 47 | } 48 | 49 | int partitionRight(vector& A, int a, int p, int r) { 50 | int i = p - 1; 51 | for (int j = p; j <= r - 1; j++) { 52 | if (A[j].a <= a) { 53 | i++; 54 | swap(A[i], A[j]); 55 | } 56 | } 57 | swap(A[i + 1], A[r]); 58 | return i + 1; 59 | } 60 | 61 | int partitionLeft(vector& A, int b, int p, int t) { 62 | int i = p - 1; 63 | for (int j = p; j <= t - 1; j++) { 64 | if (A[j].b < b) { 65 | i++; 66 | swap(A[i], A[j]); 67 | } 68 | } 69 | swap(A[i + 1], A[t]); 70 | return i + 1; 71 | } 72 | 73 | void fuzzySort(vector& A, int p, int r) { 74 | if (p < r) { 75 | Interval interval = findIntersection(A, p, r); 76 | int t = partitionRight(A, interval.a, p, r); 77 | int q = partitionLeft(A, interval.b, p, t); 78 | fuzzySort(A, p, q - 1); 79 | fuzzySort(A, t + 1, r); 80 | } 81 | } 82 | } // namespace CH7 83 | } // namespace CLRS 84 | 85 | #endif -------------------------------------------------------------------------------- /Chap08/8.2.cpp: -------------------------------------------------------------------------------- 1 | #include "8.2.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH8; 6 | 7 | int main() { 8 | print(string("Chapter 8.2 Counting sort")); 9 | 10 | cout << "Initialize an array A as Figure 8.2\n"; 11 | vector A = {2, 5, 3, 0, 2, 3, 0, 3}; 12 | print(A); 13 | 14 | cout << "\nInitialize an empty array B as Figure 8.2\n"; 15 | vector B(A.size(), 0); 16 | print(B); 17 | 18 | cout << "\nPerform COUNTING-SORT(A, B, 5)\n"; 19 | countingSort(A, B, 5); 20 | print(B); 21 | } -------------------------------------------------------------------------------- /Chap08/8.2.h: -------------------------------------------------------------------------------- 1 | #ifndef ch8_2_h 2 | #define ch8_2_h 3 | 4 | #include 5 | 6 | using std::vector; 7 | 8 | // [Page 195] 9 | // COUNTING-SORT(A, B, k) 10 | // - Time: O(n) 11 | 12 | namespace CLRS { 13 | namespace CH8 { 14 | void countingSort(vector& A, vector& B, int k) { 15 | vector C(k + 1, 0); 16 | for (int i = 0; i <= k; i++) { 17 | C[i] = 0; 18 | } 19 | for (int j = 0; j < A.size(); j++) { 20 | C[A[j]]++; 21 | } 22 | // C[i] now contains the number of elements equal to i. 23 | for (int i = 1; i <= k; i++) { 24 | C[i] += C[i - 1]; 25 | } 26 | // C[i] now contains the number of elements less than or equal to i. 27 | for (int j = A.size() - 1; j >= 0; j--) { 28 | B[C[A[j]] - 1] = A[j]; 29 | C[A[j]]--; 30 | } 31 | } 32 | } // namespace CH8 33 | } // namespace CLRS 34 | 35 | #endif -------------------------------------------------------------------------------- /Chap08/8.3.cpp: -------------------------------------------------------------------------------- 1 | #include "8.3.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH8; 6 | 7 | int main() { 8 | print(string("8.3 Radix sort")); 9 | 10 | cout << "Initialize an array of 3-digit numbers as Figure 8.3\n"; 11 | vector A = {329, 457, 657, 839, 436, 720, 355}; 12 | print(A); 13 | 14 | cout << "\nPerform RADIX-SORT(A, 3)\n"; 15 | radixSort(A, 3); 16 | } -------------------------------------------------------------------------------- /Chap08/8.3.h: -------------------------------------------------------------------------------- 1 | #ifndef ch8_3_h 2 | #define ch8_3_h 3 | 4 | #include 5 | #include 6 | 7 | #include "../print.h" 8 | 9 | using std::pow; 10 | using std::vector; 11 | 12 | // [Page 198] 13 | // COUNTING-SORT(A, B, digits, k) 14 | // - Time: O(n) 15 | // 16 | // RADIX-SORT(A, d) 17 | // - Time: O(n + k) 18 | 19 | namespace CLRS { 20 | namespace CH8 { 21 | void countingSort(vector& A, vector& B, vector& digits, int k) { 22 | vector C(k + 1, 0); 23 | for (int j = 0; j < A.size(); j++) { 24 | C[digits[j]]++; 25 | } 26 | for (int i = 1; i <= k; i++) { 27 | C[i] += C[i - 1]; 28 | } 29 | for (int j = A.size() - 1; j >= 0; j--) { 30 | B[C[digits[j]] - 1] = A[j]; 31 | C[digits[j]]--; 32 | } 33 | } 34 | 35 | void radixSort(vector& A, int d, int k = 9) { 36 | for (int i = 1; i <= d; i++) { 37 | // use a stable sort to sort array A on digit i 38 | vector B(A.size(), 0); 39 | vector digits(A.size(), 0); 40 | for (int j = 0; j < A.size(); j++) { 41 | digits[j] = A[j] / (int)(pow(10, i - 1)) % 10; 42 | } 43 | countingSort(A, B, digits, 9); 44 | A = B; 45 | print(A); 46 | } 47 | } 48 | } // namespace CH8 49 | } // namespace CLRS 50 | 51 | #endif -------------------------------------------------------------------------------- /Chap08/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-Wall 3 | EXEC=run 4 | 5 | run: 6 | $(CXX) -std=c++2a $(CFLAGS) ./8.2.cpp -o 8.2.out 7 | $(CXX) -std=c++2a $(CFLAGS) ./8.3.cpp -o 8.3.out 8 | clear 9 | 10 | clean: 11 | rm *.out -------------------------------------------------------------------------------- /Chap10/10.1-4/10.1-4.cpp: -------------------------------------------------------------------------------- 1 | #include "10.1-4.h" 2 | 3 | #include "../../print.h" 4 | 5 | using namespace CLRS::CH10; 6 | 7 | void printQueue(Queue& Q) { 8 | print(Q); 9 | cout << "Q.head = " << Q.head << endl; 10 | cout << "Q.tail = " << Q.tail << endl; 11 | } 12 | 13 | int main() { 14 | print(string("10.1-4")); 15 | 16 | cout << "Initialize a queue Q[1..5]\n"; 17 | Queue Q = {0, 0, 0, 1, 0}; 18 | Q.setHead(); 19 | Q.setTail(); 20 | printQueue(Q); 21 | 22 | cout << "\nPerform ENQUEUE(Q, 1)\n"; 23 | enqueue(Q, 1); 24 | printQueue(Q); 25 | 26 | cout << "\nPerform ENQUEUE(Q, 2)\n"; 27 | enqueue(Q, 2); 28 | printQueue(Q); 29 | 30 | cout << "\nPerform ENQUEUE(Q, 5)\n"; 31 | enqueue(Q, 5); 32 | printQueue(Q); 33 | 34 | cout << "\nPerform DEQUEUE(Q)\n"; 35 | dequeue(Q); 36 | printQueue(Q); 37 | 38 | cout << "\nPerform DEQUEUE(Q)\n"; 39 | dequeue(Q); 40 | printQueue(Q); 41 | 42 | cout << "\nPerform DEQUEUE(Q)\n"; 43 | dequeue(Q); 44 | printQueue(Q); 45 | } 46 | -------------------------------------------------------------------------------- /Chap10/10.1-4/10.1-4.h: -------------------------------------------------------------------------------- 1 | #include "../Queue.h" 2 | 3 | // [Page 235][10.1-4] 4 | // QUEUE-EMPTY(Q) 5 | // - Time: O(1) 6 | // 7 | // QUEUE-FULL(Q) 8 | // - Time: O(1) 9 | // 10 | // ENQUEUE(Q, x) 11 | // - Time: O(1) 12 | // 13 | // DEQUEUE(Q) 14 | // - Time: O(1) 15 | 16 | namespace CLRS { 17 | namespace CH10 { 18 | template 19 | bool queueEmpty(Queue& Q) { 20 | if (Q.head == Q.tail) 21 | return true; 22 | else 23 | return false; 24 | } 25 | 26 | template 27 | bool queueFull(Queue& Q) { 28 | if (Q.head == Q.tail + 1 or (Q.head == 0 and Q.tail == Q.size() - 1)) 29 | return true; 30 | else 31 | return false; 32 | } 33 | 34 | template 35 | void enqueue(Queue& Q, T x) { 36 | if (queueFull(Q)) { 37 | throw "overflow"; 38 | } else { 39 | Q[Q.tail] = x; 40 | Q.tail = (Q.tail + 1) % Q.size(); 41 | } 42 | } 43 | 44 | template 45 | T dequeue(Queue& Q) { 46 | if (queueEmpty(Q)) { 47 | throw "underflow"; 48 | } else { 49 | T x = Q[Q.head]; 50 | Q.head = (Q.head + 1) % Q.size(); 51 | return x; 52 | } 53 | } 54 | } // namespace CH10 55 | } // namespace CLRS 56 | -------------------------------------------------------------------------------- /Chap10/10.1.cpp: -------------------------------------------------------------------------------- 1 | #include "10.1.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH10; 6 | 7 | int main() { 8 | print(string("Chapter 10.1 Stacks and queues")); 9 | 10 | cout << "Initialize a stack S as Figure 10.1\n"; 11 | Stack S = {15, 6, 2, 9}; 12 | S.setTop(); 13 | print(S); 14 | 15 | cout << "\nPerform PUSH(S, 17) and PUSH(S, 3)\n"; 16 | push(S, 17); 17 | push(S, 3); 18 | print(S); 19 | 20 | cout << "\nPerform POP(S)\n"; 21 | cout << pop(S) << endl; 22 | 23 | cout << "\nInitialize a queue Q[1..12] as Figure 10.2\n"; 24 | Queue Q = {0, 0, 0, 0, 0, 0, 15, 6, 9, 8, 4, 0}; 25 | Q.setHead(); 26 | Q.setTail(); 27 | print(Q); 28 | 29 | cout << "\nPerform ENQUEUE(Q, 17)\n"; 30 | enqueue(Q, 17); 31 | print(Q); 32 | 33 | cout << "\nPerform ENQUEUE(Q, 3)\n"; 34 | enqueue(Q, 3); 35 | print(Q); 36 | 37 | cout << "\nPerform ENQUEUE(Q, 5)\n"; 38 | enqueue(Q, 5); 39 | print(Q); 40 | 41 | cout << "\nPerform DEQUEUE(Q)\n"; 42 | dequeue(Q); 43 | cout << "Q.head = " << Q.head << endl; 44 | cout << "Q.tail = " << Q.tail << endl; 45 | } 46 | -------------------------------------------------------------------------------- /Chap10/10.1.h: -------------------------------------------------------------------------------- 1 | #ifndef ch10_1_h 2 | #define ch10_1_h 3 | 4 | #include "Queue.h" 5 | #include "Stack.h" 6 | 7 | // [Page 233] 8 | // STACK-EMPTY(S) 9 | // - Time: O(1) 10 | // 11 | // PUSH(S, x) 12 | // - Time: O(1) 13 | // 14 | // POP(S) 15 | // - Time: O(1) 16 | // 17 | // [Page 235] 18 | // ENQUEUE(Q, x) 19 | // - Time: O(1) 20 | // 21 | // DEQUEUE(Q) 22 | // - Time: O(1) 23 | 24 | namespace CLRS { 25 | namespace CH10 { 26 | template 27 | bool stackEmpty(Stack& S) { 28 | if (S.top == 0) 29 | return true; 30 | else 31 | return false; 32 | } 33 | 34 | template 35 | void push(Stack& S, T x) { 36 | S.top++; 37 | S[S.top] = x; 38 | } 39 | 40 | template 41 | T pop(Stack& S) { 42 | if (stackEmpty(S)) { 43 | throw("underflow"); 44 | } else { 45 | S.top--; 46 | return S[S.top + 1]; 47 | } 48 | } 49 | 50 | template 51 | void enqueue(Queue& Q, T x) { 52 | Q[Q.tail] = x; 53 | if (Q.tail == Q.size() - 1) 54 | Q.tail = 0; 55 | else 56 | Q.tail++; 57 | } 58 | 59 | template 60 | T dequeue(Queue& Q) { 61 | int x = Q[Q.head]; 62 | if (Q.head == Q.size() - 1) 63 | Q.head = 1; 64 | else 65 | Q.head++; 66 | return x; 67 | } 68 | } // namespace CH10 69 | } // namespace CLRS 70 | 71 | #endif -------------------------------------------------------------------------------- /Chap10/10.2.cpp: -------------------------------------------------------------------------------- 1 | #include "10.2.h" 2 | 3 | #include "../print.h" 4 | #include "List.h" 5 | 6 | using namespace CLRS::CH10; 7 | 8 | int main() { 9 | print(string("Chapter 10.2 Linked lists")); 10 | 11 | cout << "Initialize a doubly linked list L as Figure 10.3 (a)\n"; 12 | List L; 13 | ListNode* nodeToBeDeleted = new ListNode(4); 14 | listInsert(L, new ListNode(1)); 15 | listInsert(L, nodeToBeDeleted); 16 | listInsert(L, new ListNode(16)); 17 | listInsert(L, new ListNode(9)); 18 | print(L); 19 | 20 | cout << "\nPerform LIST-INSERT(L, 25)\n"; 21 | listInsert(L, new ListNode(25)); 22 | print(L); 23 | 24 | cout << "\nPerform LIST-DELETE(L, 4)\n"; 25 | listDelete(L, nodeToBeDeleted); 26 | print(L); 27 | 28 | cout << "\nPerform LIST-SEARCH(L, 9)\n"; 29 | ListNode* searchedListNode = listSearch(L, 9); 30 | cout << "The searched node is " << searchedListNode->key << endl; 31 | 32 | cout << "\nInitialize a doubly linked list L as Figure 10.4 (b)\n"; 33 | List_ L2; 34 | nodeToBeDeleted = new ListNode(1); 35 | listInsert_(L2, nodeToBeDeleted); 36 | listInsert_(L2, new ListNode(4)); 37 | listInsert_(L2, new ListNode(16)); 38 | listInsert_(L2, new ListNode(9)); 39 | print(L2); 40 | 41 | cout << "\nPerform LIST-INSERT'(L, 25)\n"; 42 | listInsert_(L2, new ListNode(25)); 43 | print(L2); 44 | 45 | cout << "\nPerform LIST-DELETE'(L, 1)\n"; 46 | listDelete_(L2, nodeToBeDeleted); 47 | print(L2); 48 | 49 | cout << "\nPerform LIST-SEARCH'(L, 25)\n"; 50 | searchedListNode = listSearch_(L2, 25); 51 | cout << "The searched node is " << searchedListNode->key << endl; 52 | } 53 | -------------------------------------------------------------------------------- /Chap10/10.2.h: -------------------------------------------------------------------------------- 1 | #ifndef ch10_2_h 2 | #define ch10_2_h 3 | 4 | #include "../print.h" 5 | #include "List.h" 6 | 7 | // [Page 237] 8 | // LIST-SEARCH(L, k) 9 | // - Time: O(n) 10 | // 11 | // [Page 238] 12 | // LIST-INSERT(L, x) 13 | // - Time: O(1) 14 | // 15 | // LIST-DELETE(L, x) 16 | // - Time: O(1) 17 | // 18 | // LIST-DELETE'(L, x) 19 | // - Time: O(1) 20 | // 21 | // [Page 239] 22 | // LIST-SEARCH'(L, x) 23 | // - Time: O(1) 24 | // 25 | // [Page 240] 26 | // LIST-INSERT'(L, x) 27 | // - Time: O(1) 28 | 29 | namespace CLRS { 30 | namespace CH10 { 31 | template 32 | ListNode* listSearch(List& L, T k) { 33 | ListNode* x = L.head; 34 | while (x != nullptr and x->key != k) { 35 | x = x->next; 36 | } 37 | return x; 38 | } 39 | 40 | template 41 | void listInsert(List& L, ListNode* x) { 42 | x->next = L.head; 43 | if (L.head != nullptr) { 44 | L.head->prev = x; 45 | } 46 | L.head = x; 47 | x->prev = nullptr; 48 | } 49 | 50 | template 51 | void listDelete(List& L, ListNode* x) { 52 | if (x->prev != nullptr) 53 | x->prev->next = x->next; 54 | else 55 | L.head = x->next; 56 | if (x->next != nullptr) { 57 | x->next->prev = x->prev; 58 | } 59 | } 60 | 61 | template 62 | ListNode* listSearch_(List_& L, T k) { 63 | ListNode* x = L.nil->next; 64 | while (x != L.nil and x->key != k) { 65 | x = x->next; 66 | } 67 | return x; 68 | } 69 | 70 | template 71 | void listInsert_(List_& L, ListNode* x) { 72 | x->next = L.nil->next; 73 | L.nil->next->prev = x; 74 | L.nil->next = x; 75 | x->prev = L.nil; 76 | } 77 | 78 | template 79 | void listDelete_(List_& L, ListNode* x) { 80 | x->prev->next = x->next; 81 | x->next->prev = x->prev; 82 | } 83 | } // namespace CH10 84 | } // namespace CLRS 85 | 86 | #endif -------------------------------------------------------------------------------- /Chap10/List.h: -------------------------------------------------------------------------------- 1 | #ifndef List_h 2 | #define List_h 3 | 4 | template 5 | class ListNode { 6 | public: 7 | ListNode(const T); 8 | 9 | T key; 10 | ListNode* prev; 11 | ListNode* next; 12 | }; 13 | 14 | template 15 | ListNode::ListNode(const T key) { 16 | this->key = key; 17 | prev = nullptr; 18 | next = nullptr; 19 | } 20 | 21 | template 22 | class List { 23 | public: 24 | ListNode* head; 25 | }; 26 | 27 | template 28 | class List_ { 29 | public: 30 | List_(); 31 | 32 | ListNode* nil = new ListNode(0); 33 | }; 34 | 35 | template 36 | List_::List_() { 37 | nil->next = nil; 38 | nil->prev = nil; 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /Chap10/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-Wall 3 | EXEC=run 4 | 5 | run: 6 | $(CXX) -std=c++2a $(CFLAGS) ./10.1.cpp -o 10.1.out 7 | $(CXX) -std=c++2a $(CFLAGS) ./10.2.cpp -o 10.2.out 8 | $(CXX) -std=c++2a $(CFLAGS) ./10.1-4/10.1-4.cpp -o 10.1-4.out 9 | clear 10 | 11 | clean: 12 | rm *.out -------------------------------------------------------------------------------- /Chap10/Queue.h: -------------------------------------------------------------------------------- 1 | #ifndef Queue_h 2 | #define Queue_h 3 | 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | template 10 | class Queue : private vector { 11 | public: 12 | using vector::vector; 13 | using vector::operator[]; 14 | using vector::size; 15 | 16 | int head; 17 | int tail; 18 | void setHead(); 19 | void setTail(); 20 | }; 21 | 22 | template 23 | void Queue::setHead() { 24 | for (int i = 0; i < this->size(); i++) { 25 | if ((*this)[i] != 0) { 26 | this->head = i; 27 | break; 28 | } 29 | } 30 | } 31 | 32 | template 33 | void Queue::setTail() { 34 | for (int i = this->size() - 1; i >= 0; i--) { 35 | if ((*this)[i - 1] != 0) { 36 | this->tail = i; 37 | break; 38 | } 39 | } 40 | } 41 | 42 | #endif -------------------------------------------------------------------------------- /Chap10/Stack.h: -------------------------------------------------------------------------------- 1 | #ifndef Stack_h 2 | #define Stack_h 3 | 4 | #include 5 | 6 | using namespace std; 7 | 8 | template 9 | class Stack : private vector { 10 | public: 11 | using vector::vector; 12 | using vector::operator[]; 13 | using vector::size; 14 | using vector::resize; 15 | 16 | int top; 17 | void setTop(); 18 | }; 19 | 20 | template 21 | void Stack::setTop() { 22 | this->top = this->size() - 1; 23 | this->resize(7); 24 | } 25 | 26 | #endif -------------------------------------------------------------------------------- /Chap12/12.1.cpp: -------------------------------------------------------------------------------- 1 | #include "12.1.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH12; 6 | 7 | int main() { 8 | print(string("Chapter 12.1 What is a binary search tree?")); 9 | 10 | cout << "Initialize a binary search tree (root) as Figure 12.1 (a)\n"; 11 | // Initialize the BST 12 | TreeNode* root = new TreeNode(6); 13 | root->left = new TreeNode(5); 14 | root->left->left = new TreeNode(2); 15 | root->left->right = new TreeNode(5); 16 | root->right = new TreeNode(7); 17 | root->right->right = new TreeNode(8); 18 | 19 | // Connect the parent pointers 20 | root->left->p = root; 21 | root->left->left->p = root->left; 22 | root->left->right->p = root->left; 23 | root->right->p = root; 24 | root->right->right->p = root->right; 25 | cout << " 6" << endl 26 | << " / \\" << endl 27 | << " 5 7" << endl 28 | << " / \\ \\" << endl 29 | << " 2 5 8"; 30 | 31 | cout << "\n\nRECURSIVE-INORDER-TREE-WALK(root)\n"; 32 | inorderTreeWalk(root); 33 | 34 | cout << "\n\nITERATIVE-INORDER-TREE-WALK-WITH-STACK(root)\n"; 35 | iterativeInorderTreeWalkWithStack(root); 36 | 37 | cout << "\n\nITERATIVE-INORDER-TREE-WALK-WITHOUT-STACK(root)\n"; 38 | iterativeInorderTreeWalkWithoutStack(root); 39 | 40 | cout << "\n\nRECURSIVE-PREORDER-TREE-WALK(root)\n"; 41 | preorderTreeWalk(root); 42 | 43 | cout << "\n\nRECURSIVE-POSTORDER-TREE-WALK(root)\n"; 44 | postorderTreeWalk(root); 45 | } -------------------------------------------------------------------------------- /Chap12/12.1.h: -------------------------------------------------------------------------------- 1 | #ifndef ch12_1_h 2 | #define ch12_1_h 3 | 4 | #include 5 | 6 | #include "../print.h" 7 | #include "TreeNode.h" 8 | 9 | using std::stack; 10 | 11 | // [Page 288] 12 | // INORDER-TREE-WALK(x) 13 | // - Time : O(n) 14 | // 15 | // [Page 289][12.1-3] 16 | // ITERATIVE-INORDER-TREE-WALK-WITH-STACK(x) 17 | // - Time : O(n) 18 | // - Space : O(n) 19 | // 20 | // ITERATIVE-INORDER-TREE-WALK-WITHOUT-STACK(x) 21 | // - Time : O(n) 22 | // - Space complextiy: O(1) 23 | // 24 | // [Page 289][12.1-4] 25 | // PREORDER-TREE-WALK 26 | // - Time : O(n) 27 | // 28 | // POSTORDER-TREE-WALK 29 | // - Time : O(n) 30 | 31 | namespace CLRS { 32 | namespace CH12 { 33 | void inorderTreeWalk(TreeNode* x) { 34 | if (x != nullptr) { 35 | inorderTreeWalk(x->left); 36 | print(x->key); 37 | inorderTreeWalk(x->right); 38 | } 39 | } 40 | 41 | void iterativeInorderTreeWalkWithStack(TreeNode* x) { 42 | stack stack; 43 | TreeNode* curr = x; 44 | while (curr || !stack.empty()) { 45 | while (curr) { 46 | stack.push(curr); 47 | curr = curr->left; 48 | } 49 | curr = stack.top(); 50 | stack.pop(); 51 | print(curr->key); 52 | curr = curr->right; 53 | } 54 | } 55 | 56 | void iterativeInorderTreeWalkWithoutStack(TreeNode* x) { 57 | if (x == nullptr) 58 | return; 59 | 60 | TreeNode* curr = x; 61 | while (curr) { 62 | if (!curr->left) { 63 | print(curr->key); 64 | curr = curr->right; 65 | } else { 66 | // Be careful that we couldn't use 67 | // "TreeNode* pred = treePredecessor(curr);" to find our predecessor, 68 | // because some nodes' right pointers have been modified. Therefore, the 69 | // "TreeNode* treeMaximum(TreeNode* x)" is broken now. 70 | TreeNode* pred = curr->left; 71 | while (pred->right && pred->right != curr) 72 | pred = pred->right; 73 | if (pred->right) { 74 | pred->right = nullptr; 75 | print(curr->key); 76 | curr = curr->right; 77 | } else { 78 | pred->right = curr; 79 | curr = curr->left; 80 | } 81 | } 82 | } 83 | } 84 | 85 | void preorderTreeWalk(TreeNode* x) { 86 | if (x != nullptr) { 87 | print(x->key); 88 | preorderTreeWalk(x->left); 89 | preorderTreeWalk(x->right); 90 | } 91 | } 92 | 93 | void postorderTreeWalk(TreeNode* x) { 94 | if (x != nullptr) { 95 | postorderTreeWalk(x->left); 96 | postorderTreeWalk(x->right); 97 | print(x->key); 98 | } 99 | } 100 | } // namespace CH12 101 | } // namespace CLRS 102 | 103 | #endif -------------------------------------------------------------------------------- /Chap12/12.2.h: -------------------------------------------------------------------------------- 1 | #include "TreeNode.h" 2 | 3 | // [Page 290] 4 | // TREE-SEARCH(x, k) 5 | // - Time: O(lg n) 6 | // 7 | // [Page 291] 8 | // ITERATIVE-TREE-SEARCH(x, k) 9 | // - Time: O(lg n) 10 | // 11 | // TREE-MINIMUM(x) 12 | // - Time: O(lg n) 13 | // 14 | // TREE-MAXIMUM(x) 15 | // - Time: O(lg n) 16 | // 17 | // [Page 292] 18 | // TREE-SUCCESSOR(x) 19 | // - Time: O(lg n) 20 | // 21 | // [Page 293][12.2-2] 22 | // RECURSIVE-TREE-MIMIMUM(x) 23 | // - Time: O(lg n) 24 | // 25 | // RECURSIVE-TREE-MAXIMUM(x) 26 | // - Time: O(lg n) 27 | // 28 | // [Page 293][12.2-3] 29 | // TREE-PREDECESSOR(x) 30 | // - Time: O(lg n) 31 | 32 | namespace CLRS { 33 | namespace CH12 { 34 | TreeNode* treeSearch(TreeNode* x, int k) { 35 | if (x == nullptr || k == x->key) 36 | return x; 37 | if (k < x->key) 38 | return treeSearch(x->left, k); 39 | else 40 | return treeSearch(x->right, k); 41 | } 42 | 43 | TreeNode* iterateTreeSearch(TreeNode* x, int k) { 44 | while (x != nullptr && k != x->key) { 45 | if (k < x->key) 46 | x = x->left; 47 | else 48 | x = x->right; 49 | } 50 | return x; 51 | } 52 | 53 | TreeNode* treeMinimum(TreeNode* x) { 54 | while (x->left != nullptr) 55 | x = x->left; 56 | return x; 57 | } 58 | 59 | TreeNode* treeMaximum(TreeNode* x) { 60 | while (x->right != nullptr) 61 | x = x->right; 62 | return x; 63 | } 64 | 65 | TreeNode* treeSuccessor(TreeNode* x) { 66 | if (x->right != nullptr) 67 | return treeMinimum(x->right); 68 | TreeNode* y = x->p; 69 | while (y != nullptr && x == y->right) { 70 | x = y; 71 | y = y->p; 72 | } 73 | return y; 74 | } 75 | 76 | TreeNode* recursiveTreeMinimum(TreeNode* x) { 77 | if (x->left != nullptr) 78 | return recursiveTreeMinimum(x->left); 79 | else 80 | return x; 81 | } 82 | 83 | TreeNode* recursiveTreeMaximum(TreeNode* x) { 84 | if (x->right != nullptr) 85 | return recursiveTreeMaximum(x->right); 86 | else 87 | return x; 88 | } 89 | 90 | TreeNode* treePredecessor(TreeNode* x) { 91 | if (x->left != nullptr) 92 | return treeMaximum(x->left); 93 | TreeNode* y = x->p; 94 | while (y != nullptr && x == y->left) { 95 | x = y; 96 | y = y->p; 97 | } 98 | return y; 99 | } 100 | } // namespace CH12 101 | } // namespace CLRS 102 | -------------------------------------------------------------------------------- /Chap12/12.3-5/12.3-5.cpp: -------------------------------------------------------------------------------- 1 | #include "12.3-5.h" 2 | 3 | using namespace CLRS::CH12; 4 | 5 | void traversal(BST& T) { 6 | cout << "\nINORDER-TREE-WALK(T.root): "; 7 | inorderTreeWalk(T.root); 8 | cout << "\nPREORDER-TREE-WALK(T.root): "; 9 | preorderTreeWalk(T.root); 10 | cout << "\nPOSTORDER-TREE-WALK(T.root): "; 11 | postorderTreeWalk(T.root); 12 | } 13 | 14 | int main() { 15 | print(string("12.3-5")); 16 | 17 | cout << "Initialize a binary search tree T\n"; 18 | BST T; 19 | T.root = new TreeNode(15); 20 | treeInsert(T, new TreeNode(6)); 21 | treeInsert(T, new TreeNode(18)); 22 | treeInsert(T, new TreeNode(3)); 23 | treeInsert(T, new TreeNode(7)); 24 | treeInsert(T, new TreeNode(17)); 25 | treeInsert(T, new TreeNode(20)); 26 | treeInsert(T, new TreeNode(2)); 27 | treeInsert(T, new TreeNode(4)); 28 | treeInsert(T, new TreeNode(13)); 29 | treeInsert(T, new TreeNode(9)); 30 | traversal(T); 31 | 32 | TreeNode* six = T.root->left; 33 | TreeNode* three = six->left; 34 | TreeNode* seven = six->right; 35 | TreeNode* four = three->right; 36 | TreeNode* thirteen = seven->right; 37 | TreeNode* nine = thirteen->left; 38 | TreeNode* eighteen = T.root->right; 39 | TreeNode* seventeen = eighteen->left; 40 | TreeNode* twenty = eighteen->right; 41 | 42 | cout << "\n\nPrint predecessors of each node\n"; 43 | cout << "3's pred = " << treePredecessor(T, three)->key << endl; 44 | cout << "4's pred = " << treePredecessor(T, four)->key << endl; 45 | cout << "6's pred = " << treePredecessor(T, six)->key << endl; 46 | cout << "7's pred = " << treePredecessor(T, seven)->key << endl; 47 | cout << "9's pred = " << treePredecessor(T, nine)->key << endl; 48 | cout << "13's pred = " << treePredecessor(T, thirteen)->key << endl; 49 | cout << "15 (root)'s pred = " << treePredecessor(T, T.root)->key << endl; 50 | cout << "17's pred = " << treePredecessor(T, seventeen)->key << endl; 51 | cout << "18's pred = " << treePredecessor(T, eighteen)->key << endl; 52 | cout << "20's pred = " << treePredecessor(T, twenty)->key; 53 | 54 | cout << "\n\nRemoving an item with key 15"; 55 | treeDelete(T, T.root); 56 | traversal(T); 57 | 58 | cout << "\n\nRemoving an item with key 6"; 59 | treeDelete(T, T.root->left); 60 | traversal(T); 61 | } 62 | -------------------------------------------------------------------------------- /Chap12/12.3-5/12.3-5.h: -------------------------------------------------------------------------------- 1 | #include "BST.h" 2 | #include "helper.h" 3 | 4 | // [Page 299][12.3-5] 5 | // PARENT(T, x) 6 | // - Time: O(lg n) 7 | // 8 | // TREE-INSERT(T, z) 9 | // - Time: O(lg n) 10 | // 11 | // TRANSPLANT(T, u, v) 12 | // - Time: O(lg n) 13 | // 14 | // TREE-PREDECESSOR(T, x) 15 | // - Time: O(lg n) 16 | // 17 | // TREE-DELETE(T, z) 18 | // - Time: O(lg n) 19 | 20 | namespace CLRS { 21 | namespace CH12 { 22 | TreeNode* parent(BST& T, TreeNode* x) { 23 | if (x == T.root) 24 | return nullptr; 25 | TreeNode* y = treeMaximum(x)->succ; 26 | if (y == nullptr) { 27 | y = T.root; 28 | } else { 29 | if (y->left == x) 30 | return y; 31 | y = y->left; 32 | } 33 | while (y->right != x) 34 | y = y->right; 35 | return y; 36 | } 37 | 38 | void treeInsert(BST& T, TreeNode* z) { 39 | TreeNode* y = new TreeNode(0); 40 | TreeNode* x = T.root; 41 | TreeNode* pred = new TreeNode(0); 42 | while (x != nullptr) { 43 | y = x; 44 | if (z->key < x->key) { 45 | x = x->left; 46 | } else { 47 | pred = x; 48 | x = x->right; 49 | } 50 | } 51 | if (y == nullptr) { 52 | T.root = z; 53 | z->succ = nullptr; 54 | } else if (z->key < y->key) { 55 | y->left = z; 56 | z->succ = y; 57 | if (pred != nullptr) 58 | pred->succ = z; 59 | } else { 60 | y->right = z; 61 | z->succ = y->succ; 62 | y->succ = z; 63 | } 64 | } 65 | 66 | void transplant(BST& T, TreeNode* u, TreeNode* v) { 67 | TreeNode* p = parent(T, u); 68 | if (p == nullptr) 69 | T.root = v; 70 | else if (u == p->left) 71 | p->left = v; 72 | else 73 | p->right = v; 74 | } 75 | 76 | TreeNode* treePredecessor(BST& T, TreeNode* x) { 77 | if (x->left != nullptr) 78 | return treeMaximum(x->left); 79 | TreeNode* y = T.root; 80 | TreeNode* pred = nullptr; 81 | while (y != nullptr) { 82 | if (y->key == x->key) 83 | break; 84 | if (y->key < x->key) { 85 | pred = y; 86 | y = y->right; 87 | } else { 88 | y = y->left; 89 | } 90 | } 91 | return pred; 92 | } 93 | 94 | void treeDelete(BST& T, TreeNode* z) { 95 | // Find the node, whose succ is z, then replace that node's succ with z.succ 96 | TreeNode* pred = treePredecessor(T, z); 97 | pred->succ = z->succ; 98 | if (z->left == nullptr) 99 | transplant(T, z, z->right); 100 | else if (z->right == nullptr) 101 | transplant(T, z, z->left); 102 | else { 103 | TreeNode* y = treeMinimum(z->right); 104 | if (parent(T, y) != z) { 105 | transplant(T, y, y->right); 106 | y->right = z->right; 107 | } 108 | transplant(T, z, y); 109 | y->left = z->left; 110 | } 111 | } 112 | } // namespace CH12 113 | } // namespace CLRS 114 | -------------------------------------------------------------------------------- /Chap12/12.3-5/BST.h: -------------------------------------------------------------------------------- 1 | #ifndef BST_h 2 | #define BST_h 3 | 4 | #include "TreeNode.h" 5 | 6 | struct BST { 7 | TreeNode* root; 8 | }; 9 | 10 | #endif -------------------------------------------------------------------------------- /Chap12/12.3-5/TreeNode.h: -------------------------------------------------------------------------------- 1 | #ifndef TreeNode_h 2 | #define TreeNode_h 3 | 4 | struct TreeNode { 5 | int key; 6 | TreeNode* left; 7 | TreeNode* right; 8 | TreeNode* succ; 9 | TreeNode(int x) : key(x), left(nullptr), right(nullptr), succ(nullptr){}; 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /Chap12/12.3-5/helper.h: -------------------------------------------------------------------------------- 1 | #ifndef helper_h 2 | #define helper_h 3 | 4 | #include "../../print.h" 5 | 6 | TreeNode* treeSearch(TreeNode* x, int k) { 7 | if (x == nullptr || k == x->key) 8 | return x; 9 | if (k < x->key) 10 | return treeSearch(x->left, k); 11 | else 12 | return treeSearch(x->right, k); 13 | } 14 | 15 | TreeNode* treeMinimum(TreeNode* x) { 16 | while (x->left != nullptr) 17 | x = x->left; 18 | return x; 19 | } 20 | 21 | TreeNode* treeMaximum(TreeNode* x) { 22 | while (x->right != nullptr) 23 | x = x->right; 24 | return x; 25 | } 26 | 27 | void inorderTreeWalk(TreeNode*& x) { 28 | if (x != nullptr) { 29 | inorderTreeWalk(x->left); 30 | print(x->key); 31 | inorderTreeWalk(x->right); 32 | } 33 | } 34 | 35 | void preorderTreeWalk(TreeNode*& x) { 36 | if (x != nullptr) { 37 | print(x->key); 38 | preorderTreeWalk(x->left); 39 | preorderTreeWalk(x->right); 40 | } 41 | } 42 | 43 | void postorderTreeWalk(TreeNode*& x) { 44 | if (x != nullptr) { 45 | postorderTreeWalk(x->left); 46 | postorderTreeWalk(x->right); 47 | print(x->key); 48 | } 49 | } 50 | 51 | #endif -------------------------------------------------------------------------------- /Chap12/12.3.cpp: -------------------------------------------------------------------------------- 1 | #include "12.3.h" 2 | 3 | #include "12.1.h" 4 | 5 | using namespace CLRS::CH12; 6 | 7 | int main() { 8 | print(string("Chapter 12.3 Insertion and deletion")); 9 | 10 | cout << "Initialize a binary search tree T as Figure 12.3\n"; 11 | BST T; 12 | T.root = new TreeNode(12); 13 | recursiveTreeInsert(T.root, new TreeNode(5)); 14 | recursiveTreeInsert(T.root, new TreeNode(18)); 15 | recursiveTreeInsert(T.root, new TreeNode(2)); 16 | recursiveTreeInsert(T.root, new TreeNode(9)); 17 | recursiveTreeInsert(T.root, new TreeNode(15)); 18 | recursiveTreeInsert(T.root, new TreeNode(19)); 19 | recursiveTreeInsert(T.root, new TreeNode(17)); 20 | cout << "RECURSIVE-INORDER-TREE-WALK(T.root)\n"; 21 | inorderTreeWalk(T.root); 22 | cout << "\n\n" 23 | << " 12" << endl 24 | << " / \\" << endl 25 | << " 5 18" << endl 26 | << " / \\ / \\" << endl 27 | << " 2 9 15 19" << endl 28 | << " \\" << endl 29 | << " 17" << endl; 30 | 31 | cout << "\nInserting an item with key 13\n"; 32 | treeInsert(T, new TreeNode(13)); 33 | cout << "RECURSIVE-INORDER-TREE-WALK(T.root)\n"; 34 | inorderTreeWalk(T.root); 35 | cout << "\n\n" 36 | << " 12" << endl 37 | << " / \\" << endl 38 | << " 5 18" << endl 39 | << " / \\ / \\" << endl 40 | << " 2 9 15 19" << endl 41 | << " / \\" << endl 42 | << " 13 17" << endl; 43 | 44 | cout << "\nRemoving an item with key 18\n"; 45 | treeDelete(T, T.root->right); 46 | cout << "RECURSIVE-INORDER-TREE-WALK(T.root)\n"; 47 | inorderTreeWalk(T.root); 48 | cout << "\n\n" 49 | << " 12" << endl 50 | << " / \\" << endl 51 | << " 5 19" << endl 52 | << " / \\ /" << endl 53 | << " 2 9 15" << endl 54 | << " / \\" << endl 55 | << " 13 17" << endl; 56 | 57 | cout << "\nRemoving an item with key 15\n"; 58 | treeDelete(T, T.root->right->left); 59 | cout << "RECURSIVE-INORDER-TREE-WALK(T.root)\n"; 60 | inorderTreeWalk(T.root); 61 | cout << "\n\n" 62 | << " 12" << endl 63 | << " / \\" << endl 64 | << " 5 19" << endl 65 | << " / \\ /" << endl 66 | << " 2 9 13" << endl 67 | << " \\" << endl 68 | << " 17" << endl; 69 | } 70 | -------------------------------------------------------------------------------- /Chap12/12.3.h: -------------------------------------------------------------------------------- 1 | #include "12.2.h" 2 | #include "BST.h" 3 | 4 | // [Page 294] 5 | // TREE-INSERT(T, z) 6 | // - Time : O(lg n) 7 | // 8 | // [Page 296] 9 | // TRANSPLANT(T, u, v) 10 | // - Time : O(1) 11 | // 12 | // [Page 298] 13 | // TREE-DELETE(T, z) 14 | // - Time : O(lg n) 15 | // 16 | // [Page 299][12.3-1] 17 | // RECURSIVE-TREE-INSERT(T, z) 18 | // - Time: O(lg n) 19 | 20 | namespace CLRS { 21 | namespace CH12 { 22 | void treeInsert(BST& T, TreeNode* z) { 23 | TreeNode* y = new TreeNode(0); 24 | TreeNode* x = T.root; 25 | while (x != nullptr) { 26 | y = x; 27 | if (z->key < x->key) 28 | x = x->left; 29 | else 30 | x = x->right; 31 | } 32 | z->p = y; 33 | if (y == nullptr) 34 | T.root = z; // tree T was empty 35 | else if (z->key < y->key) 36 | y->left = z; 37 | else 38 | y->right = z; 39 | } 40 | 41 | void transplant(BST& T, TreeNode* u, TreeNode* v) { 42 | if (u->p == nullptr) 43 | T.root = v; 44 | else if (u == u->p->left) 45 | u->p->left = v; 46 | else 47 | u->p->right = v; 48 | if (v != nullptr) 49 | v->p = u->p; 50 | } 51 | 52 | void treeDelete(BST& T, TreeNode* z) { 53 | if (z->left == nullptr) 54 | transplant(T, z, z->right); 55 | else if (z->right == nullptr) 56 | transplant(T, z, z->left); 57 | else { 58 | TreeNode* y = treeMinimum(z->right); 59 | if (y->p != z) { 60 | transplant(T, y, y->right); 61 | y->right = z->right; 62 | y->right->p = y; 63 | } 64 | transplant(T, z, y); 65 | y->left = z->left; 66 | y->left->p = y; 67 | } 68 | } 69 | 70 | void recursiveTreeInsert(TreeNode*& root, TreeNode* z) { 71 | if (root == nullptr) { 72 | root = z; 73 | return; 74 | } 75 | z->p = root; 76 | if (z->key < root->key) 77 | recursiveTreeInsert(root->left, z); 78 | else 79 | recursiveTreeInsert(root->right, z); 80 | } 81 | } // namespace CH12 82 | } // namespace CLRS 83 | -------------------------------------------------------------------------------- /Chap12/BST.h: -------------------------------------------------------------------------------- 1 | #ifndef BST_h 2 | #define BST_h 3 | 4 | #include "TreeNode.h" 5 | 6 | struct BST { 7 | TreeNode* root; 8 | }; 9 | 10 | #endif -------------------------------------------------------------------------------- /Chap12/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-Wall 3 | EXEC=run 4 | 5 | run: 6 | $(CXX) -std=c++2a $(CFLAGS) ./12.1.cpp -o 12.1.out 7 | $(CXX) -std=c++2a $(CFLAGS) ./12.3.cpp -o 12.3.out 8 | $(CXX) -std=c++2a $(CFLAGS) ./12.3-5/12.3-5.cpp -o 12.3-5.out 9 | clear 10 | 11 | clean: 12 | rm *.out -------------------------------------------------------------------------------- /Chap12/TreeNode.h: -------------------------------------------------------------------------------- 1 | #ifndef TreeNode_h 2 | #define TreeNode_h 3 | 4 | struct TreeNode { 5 | int key; 6 | TreeNode* left; 7 | TreeNode* right; 8 | TreeNode* p; 9 | TreeNode(int x) : key(x), left(nullptr), right(nullptr), p(nullptr){}; 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /Chap22/22.1.cpp: -------------------------------------------------------------------------------- 1 | #include "22.1.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH22; 6 | 7 | void print(vector>& adj) { 8 | for (int i = 0; i < adj.size(); ++i) { 9 | cout << i << " "; 10 | print(adj[i]); 11 | } 12 | } 13 | 14 | int main() { 15 | print(string("22.1 Representations of graphs")); 16 | 17 | cout << "Initialize an adjacency list as Figure 22.2\n"; 18 | cout << "(Note that the indices are all -1)\n"; 19 | vector> adj(6); 20 | listInsert(adj[0], new ListNode(3)); 21 | listInsert(adj[0], new ListNode(1)); 22 | listInsert(adj[1], new ListNode(4)); 23 | listInsert(adj[2], new ListNode(4)); 24 | listInsert(adj[2], new ListNode(5)); 25 | listInsert(adj[3], new ListNode(1)); 26 | listInsert(adj[4], new ListNode(3)); 27 | listInsert(adj[5], new ListNode(5)); 28 | print(adj); 29 | 30 | print(string("22.1-3")); 31 | 32 | vector> adj_ = transpose(adj); 33 | print(adj_); 34 | 35 | print(string("22.1-4")); 36 | 37 | adj_ = equivalentUndirectedGraph(adj); 38 | print(adj_); 39 | } -------------------------------------------------------------------------------- /Chap22/22.1.h: -------------------------------------------------------------------------------- 1 | #ifndef ch22_1_h 2 | #define ch22_1_h 3 | 4 | #include "../Chap10/10.2.h" 5 | #include "../print.h" 6 | 7 | using namespace CLRS::CH10; 8 | 9 | // [Page 592][22.1-3] 10 | // TRANSPOSE(Adj) 11 | // - Time: O(|V| + |E|) 12 | // 13 | // [Page 593][22.1-4] 14 | // EQUIVALENT-UNDIRECTED-GRAPH(Adj) 15 | // - Time: O(|V| + |E|) 16 | 17 | namespace CLRS { 18 | namespace CH22 { 19 | template 20 | vector> transpose(vector>& adj) { 21 | vector> adj_(adj.size()); 22 | 23 | for (int u = 0; u < adj.size(); ++u) 24 | for (ListNode* v = adj[u].head; v; v = v->next) 25 | listInsert(adj_[v->key], new ListNode(u)); 26 | 27 | return adj_; 28 | } 29 | 30 | template 31 | vector> equivalentUndirectedGraph(vector>& adj) { 32 | const int n = adj.size(); 33 | 34 | vector> adj_(n); 35 | vector> M(n, vector(n)); 36 | 37 | for (int u = 0; u < n; ++u) 38 | for (ListNode* v = adj[u].head; v; v = v->next) 39 | if (!M[u][v->key] && u != v->key) { 40 | M[u][v->key] = true; 41 | listInsert(adj_[u], new ListNode(v->key)); 42 | } 43 | 44 | return adj_; 45 | } 46 | } // namespace CH22 47 | } // namespace CLRS 48 | 49 | #endif -------------------------------------------------------------------------------- /Chap22/22.2.cpp: -------------------------------------------------------------------------------- 1 | #include "22.2.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH22; 6 | 7 | int main() { 8 | print(string("22.2 Breadth-first search")); 9 | 10 | cout << "Initialize an undirected graph as Figure 22.3\n"; 11 | 12 | Graph G; 13 | Vertex* r = new Vertex("r"); 14 | Vertex* s = new Vertex("s"); 15 | Vertex* t = new Vertex("t"); 16 | Vertex* u = new Vertex("u"); 17 | Vertex* v = new Vertex("v"); 18 | Vertex* w = new Vertex("w"); 19 | Vertex* x = new Vertex("x"); 20 | Vertex* y = new Vertex("y"); 21 | G.V.push_back(r); 22 | G.V.push_back(s); 23 | G.V.push_back(t); 24 | G.V.push_back(u); 25 | G.V.push_back(v); 26 | G.V.push_back(w); 27 | G.V.push_back(x); 28 | G.V.push_back(y); 29 | 30 | G.Adj[r].push_back(v); 31 | G.Adj[r].push_back(s); 32 | 33 | G.Adj[s].push_back(w); 34 | G.Adj[s].push_back(r); 35 | 36 | G.Adj[t].push_back(x); 37 | G.Adj[t].push_back(w); 38 | G.Adj[t].push_back(u); 39 | 40 | G.Adj[u].push_back(y); 41 | G.Adj[u].push_back(x); 42 | G.Adj[u].push_back(t); 43 | 44 | G.Adj[v].push_back(r); 45 | 46 | G.Adj[w].push_back(t); 47 | G.Adj[w].push_back(x); 48 | G.Adj[w].push_back(s); 49 | 50 | G.Adj[x].push_back(y); 51 | G.Adj[x].push_back(w); 52 | G.Adj[x].push_back(u); 53 | G.Adj[x].push_back(t); 54 | 55 | G.Adj[y].push_back(x); 56 | G.Adj[y].push_back(u); 57 | 58 | cout << "\nPerform BFS(G, s)\n"; 59 | bfs(G, s); 60 | printGraph(G); 61 | 62 | cout << "\nPerform PRINT-PATH(G, s, y)\n"; 63 | printPath(G, s, y); 64 | 65 | cout << "\n\nPerform PRINT-PATH(G, s, t)\n"; 66 | printPath(G, s, t); 67 | } -------------------------------------------------------------------------------- /Chap22/22.2.h: -------------------------------------------------------------------------------- 1 | #ifndef ch22_2_h 2 | #define ch22_2_h 3 | 4 | #include "../Chap10/10.1-4/10.1-4.h" 5 | #include "../print.h" 6 | #include "Graph.h" 7 | 8 | using namespace CLRS::CH10; 9 | 10 | // [Page 595] 11 | // BFS(G, s) 12 | // - Time: O(V + E) 13 | // 14 | // [Page 601] 15 | // PRINT-PATH(G, s, v) 16 | // - Time: O(# of vertices in the path) 17 | 18 | namespace CLRS { 19 | namespace CH22 { 20 | int iterationCounter = -1; 21 | 22 | void printGraph(Graph& G) { 23 | iterationCounter++; 24 | if (iterationCounter == 0) 25 | cout << "(a) "; 26 | else if (iterationCounter == 1) 27 | cout << "(b) "; 28 | else if (iterationCounter == 2) 29 | cout << "(c) "; 30 | else if (iterationCounter == 3) 31 | cout << "(d) "; 32 | else if (iterationCounter == 4) 33 | cout << "(e) "; 34 | else if (iterationCounter == 5) 35 | cout << "(f) "; 36 | else if (iterationCounter == 6) 37 | cout << "(g) "; 38 | else if (iterationCounter == 7) 39 | cout << "(h) "; 40 | else 41 | cout << "(i) "; 42 | 43 | for (int i = 0; i < G.V.size(); ++i) { 44 | if (i == 4) 45 | cout << endl << " "; 46 | cout << setw(5) << getString(G.V[i]->color) << " "; 47 | 48 | if (G.V[i]->d == INT_MAX) 49 | cout << "∞"; 50 | else 51 | cout << G.V[i]->d; 52 | cout << " "; 53 | 54 | if (G.V[i]->PI == nullptr) 55 | cout << "N"; 56 | else 57 | cout << G.V[i]->PI->name; 58 | cout << " "; 59 | } 60 | } 61 | 62 | void printQueue(Queue& Q) { 63 | cout << " Q "; 64 | for (int i = Q.head; i != Q.tail; i = (i + 1) % Q.size()) { 65 | cout << Q[i]->d << " "; 66 | } 67 | cout << endl << endl; 68 | } 69 | 70 | void bfs(Graph& G, Vertex* s) { 71 | for (Vertex* u : G.V) { 72 | if (u == s) 73 | continue; 74 | u->color = WHITE; 75 | u->d = INT_MAX; 76 | u->PI = nullptr; 77 | } 78 | s->color = GRAY; 79 | s->d = 0; 80 | s->PI = nullptr; 81 | Queue Q(4); 82 | Q.head = Q.tail = 0; 83 | enqueue(Q, s); 84 | while (!queueEmpty(Q)) { 85 | printGraph(G); 86 | printQueue(Q); 87 | Vertex* u = dequeue(Q); 88 | for (Vertex* v : G.Adj[u]) { 89 | if (v->color == WHITE) { 90 | v->color = GRAY; 91 | v->d = u->d + 1; 92 | v->PI = u; 93 | enqueue(Q, v); 94 | } 95 | } 96 | u->color = BLACK; 97 | } 98 | } 99 | 100 | void printPath(Graph& G, Vertex* s, Vertex* v) { 101 | if (v == s) { 102 | cout << s->name << " "; 103 | } else if (v->PI == nullptr) { 104 | cout << "no path from " << s->name << " to " << v->name << " exists" 105 | << endl; 106 | } else { 107 | printPath(G, s, v->PI); 108 | cout << v->name << " "; 109 | } 110 | } 111 | } // namespace CH22 112 | } // namespace CLRS 113 | 114 | #endif -------------------------------------------------------------------------------- /Chap22/22.3-10/22.3-10.cpp: -------------------------------------------------------------------------------- 1 | #include "22.3-10.h" 2 | 3 | #include "../../print.h" 4 | 5 | using namespace CLRS::CH22; 6 | 7 | int main() { 8 | { 9 | print(string("22.3-10 Demo 1")); 10 | 11 | cout << "Initialize a directed graph as Figure 22.4\n"; 12 | Graph G; 13 | Vertex* u = new Vertex("u"); 14 | Vertex* v = new Vertex("v"); 15 | Vertex* w = new Vertex("w"); 16 | Vertex* x = new Vertex("x"); 17 | Vertex* y = new Vertex("y"); 18 | Vertex* z = new Vertex("z"); 19 | G.V.push_back(u); 20 | G.V.push_back(v); 21 | G.V.push_back(w); 22 | G.V.push_back(x); 23 | G.V.push_back(y); 24 | G.V.push_back(z); 25 | 26 | G.Adj[u].push_back(v); 27 | G.Adj[u].push_back(x); 28 | 29 | G.Adj[v].push_back(y); 30 | 31 | G.Adj[w].push_back(y); 32 | G.Adj[w].push_back(z); 33 | 34 | G.Adj[x].push_back(v); 35 | 36 | G.Adj[y].push_back(x); 37 | 38 | G.Adj[z].push_back(z); 39 | 40 | cout << "\nPerform DFS(G)\n"; 41 | dfs(G); 42 | } 43 | 44 | { 45 | print(string("22.3-10 Demo 2")); 46 | 47 | cout << "Initialize a directed graph as Figure 22.5\n"; 48 | 49 | Graph G; 50 | Vertex* s = new Vertex("s"); 51 | Vertex* y = new Vertex("y"); 52 | Vertex* z = new Vertex("z"); 53 | Vertex* t = new Vertex("t"); 54 | Vertex* x = new Vertex("x"); 55 | Vertex* w = new Vertex("w"); 56 | Vertex* v = new Vertex("v"); 57 | Vertex* u = new Vertex("u"); 58 | G.V.push_back(s); 59 | G.V.push_back(y); 60 | G.V.push_back(z); 61 | G.V.push_back(t); 62 | G.V.push_back(x); 63 | G.V.push_back(w); 64 | G.V.push_back(v); 65 | G.V.push_back(u); 66 | 67 | G.Adj[s].push_back(z); 68 | G.Adj[s].push_back(w); 69 | 70 | G.Adj[y].push_back(x); 71 | 72 | G.Adj[z].push_back(y); 73 | G.Adj[z].push_back(w); 74 | 75 | G.Adj[t].push_back(v); 76 | G.Adj[t].push_back(u); 77 | 78 | G.Adj[x].push_back(z); 79 | 80 | G.Adj[w].push_back(x); 81 | 82 | G.Adj[v].push_back(s); 83 | G.Adj[v].push_back(w); 84 | 85 | G.Adj[u].push_back(t); 86 | G.Adj[u].push_back(v); 87 | 88 | cout << "\nPerform DFS(G)\n"; 89 | dfs(G); 90 | } 91 | 92 | { 93 | print(string("22.3-10 Demo 3")); 94 | 95 | cout << "Initialize a directed graph as Figure 22.6\n"; 96 | 97 | Graph G; 98 | Vertex* q = new Vertex("q"); 99 | Vertex* r = new Vertex("r"); 100 | Vertex* s = new Vertex("s"); 101 | Vertex* t = new Vertex("t"); 102 | Vertex* u = new Vertex("u"); 103 | Vertex* v = new Vertex("v"); 104 | Vertex* w = new Vertex("w"); 105 | Vertex* x = new Vertex("x"); 106 | Vertex* y = new Vertex("y"); 107 | Vertex* z = new Vertex("z"); 108 | G.V.push_back(q); 109 | G.V.push_back(r); 110 | G.V.push_back(s); 111 | G.V.push_back(t); 112 | G.V.push_back(u); 113 | G.V.push_back(v); 114 | G.V.push_back(w); 115 | G.V.push_back(x); 116 | G.V.push_back(y); 117 | G.V.push_back(z); 118 | 119 | G.Adj[q].push_back(s); 120 | G.Adj[q].push_back(t); 121 | G.Adj[q].push_back(w); 122 | 123 | G.Adj[r].push_back(u); 124 | G.Adj[r].push_back(y); 125 | 126 | G.Adj[s].push_back(v); 127 | 128 | G.Adj[t].push_back(x); 129 | G.Adj[t].push_back(y); 130 | 131 | G.Adj[u].push_back(y); 132 | 133 | G.Adj[v].push_back(w); 134 | 135 | G.Adj[w].push_back(s); 136 | 137 | G.Adj[x].push_back(z); 138 | 139 | G.Adj[y].push_back(q); 140 | 141 | G.Adj[z].push_back(x); 142 | 143 | cout << "\nPerform DFS(G)\n"; 144 | dfs(G); 145 | } 146 | } -------------------------------------------------------------------------------- /Chap22/22.3-10/22.3-10.h: -------------------------------------------------------------------------------- 1 | #ifndef ch22_3_10_h 2 | #define ch22_3_10_h 3 | 4 | #include 5 | 6 | #include "../Graph.h" 7 | 8 | // [Page 612] 9 | // DFS-STACK-PRINT(G, v) 10 | // - Time: O(V + E) 11 | 12 | namespace CLRS { 13 | namespace CH22 { 14 | int time; 15 | 16 | void dfsVisitPrint(Graph& G, Vertex* u) { 17 | time++; 18 | u->d = time; 19 | u->color = GRAY; 20 | for (Vertex* v : G.Adj[u]) { 21 | if (v->color == WHITE) { 22 | cout << "(" << u->name << ", " << v->name << ") is a tree edge." << endl; 23 | v->PI = u; 24 | dfsVisitPrint(G, v); 25 | } else if (v->color == GRAY) { 26 | cout << "(" << u->name << ", " << v->name << ") is a back edge." << endl; 27 | } else if (v->d > u->d) { 28 | cout << "(" << u->name << ", " << v->name << ") is a forward edge." 29 | << endl; 30 | } else { 31 | cout << "(" << u->name << ", " << v->name << ") is a cross edge." << endl; 32 | } 33 | } 34 | u->color = BLACK; 35 | time++; 36 | u->f = time; 37 | } 38 | 39 | void dfs(Graph& G) { 40 | for (Vertex* u : G.V) { 41 | u->color = WHITE; 42 | u->PI = nullptr; 43 | } 44 | time = 0; 45 | for (Vertex* u : G.V) 46 | if (u->color == WHITE) 47 | dfsVisitPrint(G, u); 48 | } 49 | } // namespace CH22 50 | } // namespace CLRS 51 | 52 | #endif -------------------------------------------------------------------------------- /Chap22/22.3-12/22.3-12.cpp: -------------------------------------------------------------------------------- 1 | #include "22.3-12.h" 2 | 3 | #include "../../print.h" 4 | 5 | using namespace CLRS::CH22; 6 | 7 | int main() { 8 | { 9 | print(string("22.3-12 Demo 1")); 10 | 11 | cout << "Initialize a directed graph as Figure 22.4\n"; 12 | Graph G; 13 | Vertex* u = new Vertex("u"); 14 | Vertex* v = new Vertex("v"); 15 | Vertex* w = new Vertex("w"); 16 | Vertex* x = new Vertex("x"); 17 | Vertex* y = new Vertex("y"); 18 | Vertex* z = new Vertex("z"); 19 | G.V.push_back(u); 20 | G.V.push_back(v); 21 | G.V.push_back(w); 22 | G.V.push_back(x); 23 | G.V.push_back(y); 24 | G.V.push_back(z); 25 | 26 | G.Adj[u].push_back(v); 27 | G.Adj[u].push_back(x); 28 | 29 | G.Adj[v].push_back(y); 30 | 31 | G.Adj[w].push_back(y); 32 | G.Adj[w].push_back(z); 33 | 34 | G.Adj[x].push_back(v); 35 | 36 | G.Adj[y].push_back(x); 37 | 38 | G.Adj[z].push_back(z); 39 | 40 | cout << "\nPerform DFS(G)\n"; 41 | dfsCC(G); 42 | 43 | cout << "\nPrint CC of G's vertex\n"; 44 | printCC(G); 45 | } 46 | 47 | { 48 | print(string("22.3-12 Demo 2")); 49 | 50 | cout << "Initialize a directed graph as Figure 22.5\n"; 51 | 52 | Graph G; 53 | Vertex* s = new Vertex("s"); 54 | Vertex* y = new Vertex("y"); 55 | Vertex* z = new Vertex("z"); 56 | Vertex* t = new Vertex("t"); 57 | Vertex* x = new Vertex("x"); 58 | Vertex* w = new Vertex("w"); 59 | Vertex* v = new Vertex("v"); 60 | Vertex* u = new Vertex("u"); 61 | G.V.push_back(s); 62 | G.V.push_back(y); 63 | G.V.push_back(z); 64 | G.V.push_back(t); 65 | G.V.push_back(x); 66 | G.V.push_back(w); 67 | G.V.push_back(v); 68 | G.V.push_back(u); 69 | 70 | G.Adj[s].push_back(z); 71 | G.Adj[s].push_back(w); 72 | 73 | G.Adj[y].push_back(x); 74 | 75 | G.Adj[z].push_back(y); 76 | G.Adj[z].push_back(w); 77 | 78 | G.Adj[t].push_back(v); 79 | G.Adj[t].push_back(u); 80 | 81 | G.Adj[x].push_back(z); 82 | 83 | G.Adj[w].push_back(x); 84 | 85 | G.Adj[v].push_back(s); 86 | G.Adj[v].push_back(w); 87 | 88 | G.Adj[u].push_back(t); 89 | G.Adj[u].push_back(v); 90 | 91 | cout << "\nPerform DFS(G)\n"; 92 | dfsCC(G); 93 | 94 | cout << "\nPrint CC of G's vertex\n"; 95 | printCC(G); 96 | } 97 | 98 | { 99 | print(string("22.3-12 Demo 3")); 100 | 101 | cout << "Initialize a directed graph as Figure 22.6\n"; 102 | 103 | Graph G; 104 | Vertex* q = new Vertex("q"); 105 | Vertex* r = new Vertex("r"); 106 | Vertex* s = new Vertex("s"); 107 | Vertex* t = new Vertex("t"); 108 | Vertex* u = new Vertex("u"); 109 | Vertex* v = new Vertex("v"); 110 | Vertex* w = new Vertex("w"); 111 | Vertex* x = new Vertex("x"); 112 | Vertex* y = new Vertex("y"); 113 | Vertex* z = new Vertex("z"); 114 | G.V.push_back(q); 115 | G.V.push_back(r); 116 | G.V.push_back(s); 117 | G.V.push_back(t); 118 | G.V.push_back(u); 119 | G.V.push_back(v); 120 | G.V.push_back(w); 121 | G.V.push_back(x); 122 | G.V.push_back(y); 123 | G.V.push_back(z); 124 | 125 | G.Adj[q].push_back(s); 126 | G.Adj[q].push_back(t); 127 | G.Adj[q].push_back(w); 128 | 129 | G.Adj[r].push_back(u); 130 | G.Adj[r].push_back(y); 131 | 132 | G.Adj[s].push_back(v); 133 | 134 | G.Adj[t].push_back(x); 135 | G.Adj[t].push_back(y); 136 | 137 | G.Adj[u].push_back(y); 138 | 139 | G.Adj[v].push_back(w); 140 | 141 | G.Adj[w].push_back(s); 142 | 143 | G.Adj[x].push_back(z); 144 | 145 | G.Adj[y].push_back(q); 146 | 147 | G.Adj[z].push_back(x); 148 | 149 | cout << "\nPerform DFS(G)\n"; 150 | dfsCC(G); 151 | 152 | cout << "\nPrint CC of G's vertex\n"; 153 | printCC(G); 154 | } 155 | } -------------------------------------------------------------------------------- /Chap22/22.3-12/22.3-12.h: -------------------------------------------------------------------------------- 1 | #ifndef ch22_3_12_h 2 | #define ch22_3_12_h 3 | 4 | #include 5 | 6 | #include "../Graph.h" 7 | 8 | // [Page 612] 9 | // DFS-CC(G) 10 | // - Time: O(V + E) 11 | // 12 | // DFS-VISIT-CC(G, u) 13 | // - Time: O(E) 14 | 15 | namespace CLRS { 16 | namespace CH22 { 17 | int time; 18 | 19 | void printCC(Graph& G) { 20 | for (Vertex* u : G.V) { 21 | cout << u->name << ".cc = " << u->cc << endl; 22 | } 23 | } 24 | 25 | void dfsVisitCC(Graph& G, Vertex* u) { 26 | time++; 27 | u->d = time; 28 | u->color = GRAY; 29 | for (Vertex* v : G.Adj[u]) { 30 | if (v->color == WHITE) { 31 | v->cc = u->cc; 32 | v->PI = u; 33 | dfsVisitCC(G, v); 34 | } 35 | } 36 | u->color = BLACK; 37 | time++; 38 | u->f = time; 39 | } 40 | 41 | void dfsCC(Graph& G) { 42 | for (Vertex* u : G.V) { 43 | u->color = WHITE; 44 | u->PI = nullptr; 45 | } 46 | time = 0; 47 | int cc = 1; 48 | for (Vertex* u : G.V) 49 | if (u->color == WHITE) { 50 | u->cc = cc; 51 | cc++; 52 | dfsVisitCC(G, u); 53 | } 54 | } 55 | } // namespace CH22 56 | } // namespace CLRS 57 | 58 | #endif -------------------------------------------------------------------------------- /Chap22/22.3-7/22.3-7.cpp: -------------------------------------------------------------------------------- 1 | #include "22.3-7.h" 2 | 3 | #include "../../print.h" 4 | 5 | using namespace CLRS::CH22; 6 | 7 | int main() { 8 | { 9 | print(string("22.3-7 Demo 1")); 10 | 11 | cout << "Initialize a directed graph as Figure 22.4\n"; 12 | Graph G; 13 | Vertex* u = new Vertex("u"); 14 | Vertex* v = new Vertex("v"); 15 | Vertex* w = new Vertex("w"); 16 | Vertex* x = new Vertex("x"); 17 | Vertex* y = new Vertex("y"); 18 | Vertex* z = new Vertex("z"); 19 | G.V.push_back(u); 20 | G.V.push_back(v); 21 | G.V.push_back(w); 22 | G.V.push_back(x); 23 | G.V.push_back(y); 24 | G.V.push_back(z); 25 | 26 | G.Adj[u].push_back(v); 27 | G.Adj[u].push_back(x); 28 | 29 | G.Adj[v].push_back(y); 30 | 31 | G.Adj[w].push_back(y); 32 | G.Adj[w].push_back(z); 33 | 34 | G.Adj[x].push_back(v); 35 | 36 | G.Adj[y].push_back(x); 37 | 38 | G.Adj[z].push_back(z); 39 | 40 | cout << "\nPerform DFS-STACK(G)\n"; 41 | dfsStack(G); 42 | } 43 | 44 | { 45 | print(string("22.3-7 Demo 2")); 46 | 47 | cout << "Initialize a directed graph as Figure 22.6\n"; 48 | 49 | Graph G; 50 | Vertex* q = new Vertex("q"); 51 | Vertex* r = new Vertex("r"); 52 | Vertex* s = new Vertex("s"); 53 | Vertex* t = new Vertex("t"); 54 | Vertex* u = new Vertex("u"); 55 | Vertex* v = new Vertex("v"); 56 | Vertex* w = new Vertex("w"); 57 | Vertex* x = new Vertex("x"); 58 | Vertex* y = new Vertex("y"); 59 | Vertex* z = new Vertex("z"); 60 | G.V.push_back(q); 61 | G.V.push_back(r); 62 | G.V.push_back(s); 63 | G.V.push_back(t); 64 | G.V.push_back(u); 65 | G.V.push_back(v); 66 | G.V.push_back(w); 67 | G.V.push_back(x); 68 | G.V.push_back(y); 69 | G.V.push_back(z); 70 | 71 | G.Adj[q].push_back(s); 72 | G.Adj[q].push_back(t); 73 | G.Adj[q].push_back(w); 74 | 75 | G.Adj[r].push_back(u); 76 | G.Adj[r].push_back(y); 77 | 78 | G.Adj[s].push_back(v); 79 | 80 | G.Adj[t].push_back(x); 81 | G.Adj[t].push_back(y); 82 | 83 | G.Adj[u].push_back(y); 84 | 85 | G.Adj[v].push_back(w); 86 | 87 | G.Adj[w].push_back(s); 88 | 89 | G.Adj[x].push_back(z); 90 | 91 | G.Adj[y].push_back(q); 92 | 93 | G.Adj[z].push_back(x); 94 | 95 | cout << "\nPerform DFS-STACK(G)\n"; 96 | dfsStack(G); 97 | } 98 | } -------------------------------------------------------------------------------- /Chap22/22.3-7/22.3-7.h: -------------------------------------------------------------------------------- 1 | #ifndef ch22_3_7_h 2 | #define ch22_3_7_h 3 | 4 | #include 5 | 6 | #include "../Graph.h" 7 | 8 | // [Page 611] 9 | // DFS-STACK(G) 10 | // - Time: O(V + E) 11 | 12 | namespace CLRS { 13 | namespace CH22 { 14 | int time; 15 | 16 | void printGraph(const Graph& G) { 17 | for (int i = 0; i < G.V.size(); ++i) { 18 | if (i > 0 && i % 3 == 0) 19 | cout << endl; 20 | cout << setw(5) << getString(G.V[i]->color) << " "; 21 | cout << G.V[i]->name << " "; 22 | 23 | if (G.V[i]->d == 0) 24 | cout << setw(2) << " "; 25 | else 26 | cout << setw(2) << G.V[i]->d; 27 | 28 | if (G.V[i]->d == 0 && G.V[i]->f == 0) 29 | cout << " "; 30 | else 31 | cout << "/"; 32 | 33 | if (G.V[i]->f == 0) 34 | cout << setw(2) << " "; 35 | else 36 | cout << setw(2) << G.V[i]->f; 37 | cout << setw(2) << " "; 38 | if (i == G.V.size() - 1) 39 | cout << endl << endl; 40 | } 41 | } 42 | 43 | Vertex* firstWhiteNeighbor(const Graph& G, Vertex* u) { 44 | for (Vertex* v : G.Adj.at(u)) // explore edge (u, v) 45 | if (v->color == WHITE) 46 | return v; 47 | return nullptr; 48 | } 49 | 50 | void dfsVisitStack(const Graph& G, Vertex* u) { 51 | std::stack S{{u}}; // analogous to dfsVisit(G, u) 52 | u->d = ++time; // white vertex u has just been discovered 53 | u->color = GRAY; 54 | while (!S.empty()) { 55 | u = S.top(); 56 | Vertex* v = firstWhiteNeighbor(G, u); 57 | if (v == nullptr) { 58 | // u's adjacency list has been fully explored 59 | S.pop(); 60 | u->f = ++time; 61 | u->color = BLACK; // blacken u; it is finished 62 | } else { 63 | // u's adjacency list hasn't been fully explored 64 | v->PI = u; 65 | v->d = ++time; 66 | v->color = GRAY; 67 | S.push(v); 68 | } 69 | } 70 | 71 | cout << "After exploring vertex " << u->name << "'s forest:\n\n"; 72 | printGraph(G); 73 | } 74 | 75 | void dfsStack(const Graph& G) { 76 | for (Vertex* u : G.V) { 77 | u->color = WHITE; 78 | u->PI = nullptr; 79 | } 80 | time = 0; 81 | for (Vertex* u : G.V) 82 | if (u->color == WHITE) 83 | dfsVisitStack(G, u); 84 | } 85 | } // namespace CH22 86 | } // namespace CLRS 87 | 88 | #endif -------------------------------------------------------------------------------- /Chap22/22.3.cpp: -------------------------------------------------------------------------------- 1 | #include "22.3.h" 2 | 3 | #include "../print.h" 4 | 5 | using namespace CLRS::CH22; 6 | 7 | int main() { 8 | { 9 | print(string("22.3 Depthfirst search")); 10 | 11 | cout << "Initialize a directed graph as Figure 22.4\n"; 12 | Graph G; 13 | Vertex* u = new Vertex("u"); 14 | Vertex* v = new Vertex("v"); 15 | Vertex* w = new Vertex("w"); 16 | Vertex* x = new Vertex("x"); 17 | Vertex* y = new Vertex("y"); 18 | Vertex* z = new Vertex("z"); 19 | G.V.push_back(u); 20 | G.V.push_back(v); 21 | G.V.push_back(w); 22 | G.V.push_back(x); 23 | G.V.push_back(y); 24 | G.V.push_back(z); 25 | 26 | G.Adj[u].push_back(v); 27 | G.Adj[u].push_back(x); 28 | 29 | G.Adj[v].push_back(y); 30 | 31 | G.Adj[w].push_back(y); 32 | G.Adj[w].push_back(z); 33 | 34 | G.Adj[x].push_back(v); 35 | 36 | G.Adj[y].push_back(x); 37 | 38 | G.Adj[z].push_back(z); 39 | 40 | cout << "\nPerform DFS(G)\n"; 41 | dfs(G); 42 | } 43 | 44 | { 45 | print(string("22.3-2")); 46 | 47 | cout << "Initialize a directed graph as Figure 22.6\n"; 48 | 49 | Graph G; 50 | Vertex* q = new Vertex("q"); 51 | Vertex* r = new Vertex("r"); 52 | Vertex* s = new Vertex("s"); 53 | Vertex* t = new Vertex("t"); 54 | Vertex* u = new Vertex("u"); 55 | Vertex* v = new Vertex("v"); 56 | Vertex* w = new Vertex("w"); 57 | Vertex* x = new Vertex("x"); 58 | Vertex* y = new Vertex("y"); 59 | Vertex* z = new Vertex("z"); 60 | G.V.push_back(q); 61 | G.V.push_back(r); 62 | G.V.push_back(s); 63 | G.V.push_back(t); 64 | G.V.push_back(u); 65 | G.V.push_back(v); 66 | G.V.push_back(w); 67 | G.V.push_back(x); 68 | G.V.push_back(y); 69 | G.V.push_back(z); 70 | 71 | G.Adj[q].push_back(s); 72 | G.Adj[q].push_back(t); 73 | G.Adj[q].push_back(w); 74 | 75 | G.Adj[r].push_back(u); 76 | G.Adj[r].push_back(y); 77 | 78 | G.Adj[s].push_back(v); 79 | 80 | G.Adj[t].push_back(x); 81 | G.Adj[t].push_back(y); 82 | 83 | G.Adj[u].push_back(y); 84 | 85 | G.Adj[v].push_back(w); 86 | 87 | G.Adj[w].push_back(s); 88 | 89 | G.Adj[x].push_back(z); 90 | 91 | G.Adj[y].push_back(q); 92 | 93 | G.Adj[z].push_back(x); 94 | 95 | cout << "\nPerform DFS(G)\n"; 96 | dfs(G); 97 | } 98 | } -------------------------------------------------------------------------------- /Chap22/22.3.h: -------------------------------------------------------------------------------- 1 | #ifndef ch22_3_h 2 | #define ch22_3_h 3 | 4 | #include "../print.h" 5 | #include "Graph.h" 6 | 7 | // [Page 604] 8 | // DFS(G) 9 | // - Time: O(V + E) 10 | // 11 | // DFS-VISIT(G, u) 12 | // - Time: O(E) 13 | 14 | namespace CLRS { 15 | namespace CH22 { 16 | int time; 17 | int iterationCounter = 0; 18 | 19 | void printGraph(const Graph& G) { 20 | ++iterationCounter; 21 | if (iterationCounter == 1) 22 | cout << "(a) "; 23 | else if (iterationCounter == 2) 24 | cout << "(b) "; 25 | else if (iterationCounter == 3) 26 | cout << "(c) "; 27 | else if (iterationCounter == 4) 28 | cout << "(d) "; 29 | else if (iterationCounter == 5) 30 | cout << "(e) "; 31 | else if (iterationCounter == 6) 32 | cout << "(f) "; 33 | else if (iterationCounter == 7) 34 | cout << "(g) "; 35 | else if (iterationCounter == 8) 36 | cout << "(h) "; 37 | else if (iterationCounter == 9) 38 | cout << "(i) "; 39 | else if (iterationCounter == 10) 40 | cout << "(j) "; 41 | else if (iterationCounter == 11) 42 | cout << "(k) "; 43 | else if (iterationCounter == 12) 44 | cout << "(l) "; 45 | else if (iterationCounter == 13) 46 | cout << "(m) "; 47 | else if (iterationCounter == 14) 48 | cout << "(n) "; 49 | else if (iterationCounter == 15) 50 | cout << "(o) "; 51 | else if (iterationCounter == 16) 52 | cout << "(p) "; 53 | 54 | for (int i = 0; i < G.V.size(); ++i) { 55 | if (iterationCounter > 16 && i == 0) 56 | cout << " "; 57 | if (i > 0 && i % 3 == 0) 58 | cout << endl << " "; 59 | cout << setw(5) << getString(G.V[i]->color) << " "; 60 | cout << G.V[i]->name << " "; 61 | 62 | if (G.V[i]->d == 0) 63 | cout << setw(2) << " "; 64 | else 65 | cout << setw(2) << G.V[i]->d; 66 | 67 | if (G.V[i]->d == 0 && G.V[i]->f == 0) 68 | cout << " "; 69 | else 70 | cout << "/"; 71 | 72 | if (G.V[i]->f == 0) 73 | cout << setw(2) << " "; 74 | else 75 | cout << setw(2) << G.V[i]->f; 76 | cout << setw(2) << " "; 77 | if (i == G.V.size() - 1) 78 | cout << endl << endl; 79 | } 80 | } 81 | 82 | void dfsVisit(const Graph& G, Vertex* u) { 83 | u->d = ++time; // white vertex u has just been discovered 84 | u->color = GRAY; 85 | printGraph(G); 86 | for (Vertex* v : G.Adj.at(u)) { // explore edge (u, v) 87 | if (v->color == WHITE) { 88 | v->PI = u; 89 | dfsVisit(G, v); 90 | } else { 91 | printGraph(G); 92 | } 93 | } 94 | u->f = ++time; 95 | u->color = BLACK; // blacken u; it is finished 96 | printGraph(G); 97 | } 98 | 99 | void dfs(const Graph& G) { 100 | for (Vertex* u : G.V) { 101 | u->color = WHITE; 102 | u->PI = nullptr; 103 | } 104 | time = 0; 105 | for (Vertex* u : G.V) 106 | if (u->color == WHITE) 107 | dfsVisit(G, u); 108 | } 109 | } // namespace CH22 110 | } // namespace CLRS 111 | 112 | #endif -------------------------------------------------------------------------------- /Chap22/Graph.h: -------------------------------------------------------------------------------- 1 | #ifndef Graph_h 2 | #define Graph_h 3 | 4 | #include 5 | using namespace std; 6 | 7 | enum Color { 8 | WHITE, 9 | GRAY, 10 | BLACK, 11 | }; 12 | 13 | string getString(Color color) { 14 | switch (color) { 15 | case WHITE: 16 | return "WHITE"; 17 | case GRAY: 18 | return "GRAY"; 19 | case BLACK: 20 | return "BLACK"; 21 | } 22 | throw; 23 | } 24 | 25 | class Vertex { 26 | public: 27 | const string name; 28 | Color color; 29 | int d = 0; 30 | int f = 0; 31 | int cc; 32 | Vertex* PI; 33 | Vertex() : color(WHITE), d(INT_MAX), PI(nullptr) { 34 | } 35 | Vertex(const string& name) : name(name) { 36 | } 37 | }; 38 | 39 | class Graph { 40 | public: 41 | vector V; 42 | map> Adj; 43 | }; 44 | 45 | #endif -------------------------------------------------------------------------------- /Chap22/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CFLAGS=-Wall 3 | EXEC=run 4 | 5 | run: 6 | $(CXX) -std=c++2a $(CFLAGS) ./22.1.cpp -o 22.1.out 7 | $(CXX) -std=c++2a $(CFLAGS) ./22.2.cpp -o 22.2.out 8 | $(CXX) -std=c++2a $(CFLAGS) ./22.3.cpp -o 22.3.out 9 | $(CXX) -std=c++2a $(CFLAGS) ./22.3-7/22.3-7.cpp -o 22.3-7.out 10 | $(CXX) -std=c++2a $(CFLAGS) ./22.3-10/22.3-10.cpp -o 22.3-10.out 11 | $(CXX) -std=c++2a $(CFLAGS) ./22.3-12/22.3-12.cpp -o 22.3-12.out 12 | clear 13 | 14 | clean: 15 | rm *.out -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CLRS in C++ 2 | 3 | > Work on implementing all pseudo code in CLRS Third Edition. 4 | 5 | ## Coding Style 6 | 7 | > I believe messy code is costing you. 8 | 9 | Therefore, in order to make everyone delighted, I format all the code. 10 | 11 | - **C++** codes are formatted by [clang-format](https://clang.llvm.org/docs/ClangFormat.html) following the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html#Spaces_vs._Tabs). You can see the configuration [here](https://github.com/google/leveldb/blob/master/.clang-format). 12 | 13 | ## General implementation 14 | 15 | Make all code as clean as possible and carefully organize each exercise and problem. 16 | -------------------------------------------------------------------------------- /print.h: -------------------------------------------------------------------------------- 1 | #ifndef print_h 2 | #define print_h 3 | 4 | #include 5 | #include 6 | 7 | #include "./Chap06/Heap.h" 8 | #include "./Chap10/List.h" 9 | #include "./Chap10/Queue.h" 10 | #include "./Chap10/Stack.h" 11 | 12 | using namespace std; 13 | 14 | void print(int val) { 15 | cout << val << " "; 16 | } 17 | 18 | void print(string str) { 19 | for (int i = 0; i < str.length() + 2; i++) 20 | cout << "-"; 21 | cout << "\n " << str << " \n"; 22 | for (int i = 0; i < str.length() + 2; i++) 23 | cout << "-"; 24 | cout << endl; 25 | } 26 | 27 | template 28 | void print(vector& vec) { 29 | for (int i = 0; i < vec.size(); i++) { 30 | cout << vec[i] << " "; 31 | } 32 | cout << endl; 33 | } 34 | 35 | template 36 | void print(Heap& A) { 37 | for (int i = 0; i < A.size(); i++) { 38 | cout << A[i] << " "; 39 | } 40 | cout << endl; 41 | } 42 | 43 | template 44 | void print(Queue& Q) { 45 | for (int i = 0; i < Q.size(); i++) { 46 | cout << Q[i] << " "; 47 | } 48 | cout << "\n"; 49 | } 50 | 51 | template 52 | void print(Stack& S) { 53 | for (int i = 0; i < S.size(); i++) { 54 | cout << S[i] << " "; 55 | } 56 | cout << "\n"; 57 | } 58 | 59 | template 60 | void print(List& L) { 61 | for (ListNode* curr = L.head; curr; curr = curr->next) { 62 | cout << curr->key << " "; 63 | } 64 | cout << "\n"; 65 | } 66 | 67 | template 68 | void print(List_& L) { 69 | for (ListNode* curr = L.nil->next; curr != L.nil; curr = curr->next) { 70 | cout << curr->key << " "; 71 | } 72 | cout << "\n"; 73 | } 74 | 75 | template 76 | void print(vector>& vec) { 77 | for (int i = 0; i < vec.size(); i++) { 78 | for (int j = 0; j < vec[0].size(); j++) { 79 | cout << vec[i][j] << " "; 80 | } 81 | cout << endl; 82 | } 83 | cout << endl; 84 | } 85 | 86 | #endif --------------------------------------------------------------------------------