diff --git a/.clang-tidy b/.clang-tidy index b797f75..40279ab 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -3,7 +3,7 @@ Checks: > WarningsAsErrors: '*' -HeaderFilterRegex: '(include/.*|source/.*)' +HeaderFilterRegex: '(include/.*|src/.*)' CheckOptions: # Private member variables @@ -12,9 +12,15 @@ CheckOptions: - key: readability-identifier-naming.PrivateMemberCase value: camelBack - # Member function (non-static, non-const, non-virtual) + # Private member methods + - key: readability-identifier-naming.PrivateMethodPrefix + value: _ + - key: readability-identifier-naming.PrivateMethodCase + value: camelBack + + # Public/Protected member methods - key: readability-identifier-naming.MethodCase - value: CamelCase + value: camelBack # Class names - key: readability-identifier-naming.ClassCase diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 47a55f5..bda1e63 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -60,10 +60,9 @@ jobs: clang-tidy --version $files = Get-ChildItem -Recurse -Path src -Include *.cpp,*.cc,*.cxx -File $failed = $false - # These source/.* files would be checked using .clang-tidy maintained at projectroot foreach ($file in $files) { Write-Host "Checking $($file.FullName)" - clang-tidy -p build "$($file.FullName)" --warnings-as-errors=* + clang-tidy -p build --header-filter=".*" "$($file.FullName)" --warnings-as-errors=* if ($LASTEXITCODE -ne 0) { $failed = $true } } if ($failed) { Write-Error "Clang-tidy failed."; exit 1 } diff --git a/CMakeLists.txt b/CMakeLists.txt index 159e956..bae14b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 3.10) project ("datastructures-algorithms") -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -19,9 +19,6 @@ if(CLANG_TIDY_EXE) ) endif() -include_directories(${CMAKE_SOURCE_DIR}/include) - -add_subdirectory(include) add_subdirectory(src) cmake_policy(SET CMP0135 NEW) diff --git a/include/0002_Tree/0001_BinarySearchTree.h b/include/0002_Tree/0001_BinarySearchTree.h deleted file mode 100644 index 1e9bcc2..0000000 --- a/include/0002_Tree/0001_BinarySearchTree.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include -using namespace std; - -namespace BinarySearchTree -{ - class Node - { - public: - int data; - Node* parent; - Node* left; - Node* right; - - Node(int data, Node* parent, Node* left, Node* right); - }; - - class BinarySearchTree - { - private: - Node* _root; - void InsertBinarySearchTreeNode(Node* node); - Node* FindBinarySearchTreeNode(int value); - Node* FindBinarySearchTreeMinimumValueNode(Node* node); - Node* FindBinarySearchTreeMaximumValueNode(Node* node); - Node* FindSuccessorBinarySearchTreeNode(Node* node); - Node* FindPredecessorBinarySearchTreeNode(Node* node); - void TransplantBinarySearchTreeNode(Node* nodeU, Node* nodeV); - void DeleteBinarySearchTreeNode(Node* node); - void RecursiveInorderTraversal(Node* node, vector& result); - void RecursivePreorderTraversal(Node* node, vector& result); - void RecursivePostorderTraversal(Node* node, vector& result); - void MorrisInorderTraversal(Node* node, vector& result); - void MorrisPreorderTraversal(Node* node, vector& result); - void MorrisPostorderTraversal(Node* node, vector& result); - public: - BinarySearchTree(); - void InsertNode(int value); - void DeleteNode(int value); - vector GetRecursiveInorderTravesalResult(); - vector GetRecursivePreorderTravesalResult(); - vector GetRecursivePostorderTravesalResult(); - vector GetMorrisInorderTraversalResult(); - vector GetMorrisPreorderTraversalResult(); - vector GetMorrisPostorderTraversalResult(); - }; -} \ No newline at end of file diff --git a/include/0003_Graph/0006_EulerianPathAndCircuit.h b/include/0003_Graph/0006_EulerianPathAndCircuit.h deleted file mode 100644 index 92d0d34..0000000 --- a/include/0003_Graph/0006_EulerianPathAndCircuit.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include -#include -using namespace std; - -namespace EulerianPathAndCircuit -{ - class Node - { - public: - int data; - int degree; - int inDegree; - int outDegree; - bool visited; - Node(int value); - }; - - class Graph - { - private: - bool _isEulerianPathPresent; - bool _isEulerianCircuitPresent; - map> _adjlist; - map _nodeMap; - vector _eulerianPath; - Node* MakeOrFindNode(int value); - void DepthFirstSearch(Node* node); - bool IsConnected(); - void EulerianPathHierholzerAlgorithm(Node* startingNode); - - public: - void PushUndirectedEdge(int valueU, int valueV); - void PushDirectedEdge(int valueU, int valueV); - void PushSingleNode(int valueU); - void FindEulerianPathAndCircuit(); - bool IsEulerianPathPresent(); - bool IsEulerianCircuitPresent(); - vector UndirectedGraphGetEulerianPath(); - }; -} \ No newline at end of file diff --git a/include/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h b/include/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h deleted file mode 100644 index 211e1b6..0000000 --- a/include/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -using namespace std; - -namespace AllPairsShortestPathsFloydWarshall -{ - class Graph - { - private: - int _noOfVertices; - vector> _adjMatrix; - vector> _shortestPathMatrixFloydWarshall; - vector> _predecessorMatrix; - void InitializeDistanceAndPredecessors(); - void GetShortestPath(int source, int destination, vector& path); - - public: - void CreateGraph(int noOfVertices); - void PushDirectedEdge(int valueU, int valueV, int weight); - void FindAllPairsShortestPathsFloydWarshallSolution(); - vector> GetFloydWarshallShortestPath(); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0001_FibonacciNumber.h b/include/0005_DynamicProgramming/0001_FibonacciNumber.h deleted file mode 100644 index 204aeba..0000000 --- a/include/0005_DynamicProgramming/0001_FibonacciNumber.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include -using namespace std; - -/* -Pattern 1 -Linear Recurrence - -Description -Print the n'th Fibonacci number. - -*/ - -namespace FibonacciNumber -{ - class DynamicProgramming - { - private: - public: - int RecursiveNthFibonacci(int n); - int DpNthFibonacci(int n); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0002_TribonacciNumber.h b/include/0005_DynamicProgramming/0002_TribonacciNumber.h deleted file mode 100644 index 31e805f..0000000 --- a/include/0005_DynamicProgramming/0002_TribonacciNumber.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include -using namespace std; - -/* -Pattern 1 -Linear Recurrence - -Description -Print the n'th Tribonacci number. - -*/ - -namespace TribonacciNumber -{ - class DynamicProgramming - { - private: - public: - int RecursiveNthTribonacci(int n); - int DpNthTribonacci(int n); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0003_ClimbingStairs.h b/include/0005_DynamicProgramming/0003_ClimbingStairs.h deleted file mode 100644 index e32b71a..0000000 --- a/include/0005_DynamicProgramming/0003_ClimbingStairs.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include -using namespace std; - -/* -Pattern 1 -Linear Recurrence - -Description -There are n stairs, and a person standing at the bottom wants to climb stairs to reach the top. -The person can climb either 1 stair or 2 stairs at a time, the task is to count the number of ways that a person can reach at the top. - -*/ - -namespace ClimbingStairs -{ - class DynamicProgramming - { - private: - public: - int RecursiveCountWays(int n); - int DpCountWays(int n); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h b/include/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h deleted file mode 100644 index 9ef1ec8..0000000 --- a/include/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include -using namespace std; - -/* -Pattern 1 -Linear Recurrence - -Description -Given an array of integers cost[] of length n, where cost[i] is the cost of the ith step on a staircase. Once the cost is paid, we can either climb 1 or 2 steps. -We can either start from the step with index 0, or the step with index 1. The task is to find the minimum cost to reach the top. - -*/ - -namespace MinimumCostClimbingStairs -{ - class DynamicProgramming - { - private: - int MinCostRecursive(size_t step, vector& cost); - public: - int RecursiveMinimumCostClimbingStairs(vector& cost); - int DpMinimumCostClimbingStairs(vector& cost); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0005_HouseRobber1.h b/include/0005_DynamicProgramming/0005_HouseRobber1.h deleted file mode 100644 index 231fbba..0000000 --- a/include/0005_DynamicProgramming/0005_HouseRobber1.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include -using namespace std; - -/* -Pattern 1 -Linear Recurrence - -Description -There are n houses built in a line, each of which contains some money in it. -A robber wants to steal money from these houses, but he can’t steal from two adjacent houses. The task is to find the maximum amount of money which can be stolen. - -*/ - -namespace HouseRobber1 -{ - class DynamicProgramming - { - private: - int MaxLootRecursive(size_t house, vector& houseValues); - public: - int RecursiveMaximumLoot(vector& houseValues); - int DpMaximumLoot(vector& houseValues); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0006_HouseRobber2.h b/include/0005_DynamicProgramming/0006_HouseRobber2.h deleted file mode 100644 index 74c3c93..0000000 --- a/include/0005_DynamicProgramming/0006_HouseRobber2.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include -using namespace std; - -/* -Pattern 1 -Linear Recurrence - -Description -You are given an array arr[] which represents houses arranged in a circle, where each house has a certain value. A thief aims to maximize the total stolen value without robbing two adjacent houses. -Determine the maximum amount the thief can steal. - -Note: Since the houses are in a circle, the first and last houses are also considered adjacent. - -*/ - -namespace HouseRobber2 -{ - class DynamicProgramming - { - private: - int MaxLootRecursive(size_t house, vector& houseValues); - int MaxLootDp(size_t firstHouse, size_t lastHouse, vector& houseValues); - public: - int RecursiveMaximumLoot(vector& houseValues); - int DpMaximumLoot(vector& houseValues); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0007_DecodeWays.h b/include/0005_DynamicProgramming/0007_DecodeWays.h deleted file mode 100644 index fe2b6ce..0000000 --- a/include/0005_DynamicProgramming/0007_DecodeWays.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include -using namespace std; - -/* -Pattern 1 -Linear Recurrence - -Description -Let 1 maps to 'A', 2 maps to 'B', ..., 26 to 'Z'.Given a digit sequence, count the number of possible decodings of the given digit sequence. - -Consider the input string "123".There are three valid ways to decode it : -"ABC" : The grouping is(1, 2, 3) -> 'A', 'B', 'C' -"AW" : The grouping is(1, 23) -> 'A', 'W' -"LC" : The grouping is(12, 3) -> 'L', 'C' -Note : Groupings that contain invalid codes(e.g., "0" by itself or numbers greater than "26") are not allowed. -For instance, the string "230" is invalid because "0" cannot stand alone, and "30" is greater than "26", so it cannot represent any letter.The task is to find the total number of valid ways to decode a given string. -*/ - -namespace DecodeWays -{ - class DynamicProgramming - { - private: - int CountWaysRecursiveHelper(string& digits, size_t index); - public: - int RecursiveCountWays(string digits); - int DpCountways(string digits); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h b/include/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h deleted file mode 100644 index 6851031..0000000 --- a/include/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -using namespace std; - -/* -Pattern 1 -Linear Recurrence - -Description -There are n stairs, and a person standing at the bottom wants to climb stairs to reach the top. -The person can climb either 1 stair or 2 stairs at a time, the task is to count the number of ways that a person can reach at the top. - -Note: This problem is similar to Count ways to reach Nth stair (Order does not matter) with the only difference that in this problem, -we count all distinct ways where different orderings of the steps are considered unique. - -Examples: - -Input: n = 1 -Output: 1 -Explanation: There is only one way to climb 1 stair. - -Input: n = 2 -Output: 2 -Explanation: There are two ways to reach 2th stair: {1, 1} and {2}. - -Input: n = 4 -Output: 5 -Explanation: There are five ways to reach 4th stair: {1, 1, 1, 1}, {1, 1, 2}, {2, 1, 1}, {1, 2, 1} and {2, 2}. -*/ - -namespace CountWaysToReachNthStairIncludeOrder -{ - class DynamicProgramming - { - private: - int RecursiveCountWaysToReachNthStairIncludeOrderHelper(int n); - public: - int RecursiveCountWaysToReachNthStairIncludeOrder(int n); - int DpCountWaysToReachNthStairIncludeOrder(int n); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h b/include/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h deleted file mode 100644 index 4d52930..0000000 --- a/include/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include -using namespace std; - -/* -Pattern 1 -Linear Recurrence - -Description -There are n stairs, and a person standing at the bottom wants to reach the top. The person can climb either 1 stair or 2 stairs at a time. Count the number of ways, the person can reach the top (order does not matter). - -Note: The problem is similar to Climbing Stairs - Count ways to reach Nth stair with the only difference that in this problem, we don't have to count those ways which only differ in ordering of the steps. - -Examples: - -Input: n = 1 -Output: 1 -Explanation: There is only one way to climb 1 stair. - -Input: n = 2 -Output: 2 -Explanation: There are two ways to climb 2 stairs: {1, 1} and {2}. - -Input: n = 4 -Output: 3 -Explanation: Three ways to reach 4th stair: {1, 1, 1, 1}, {1, 1, 2} and {2, 2}. - -Input: n = 5 -Output: 3 -Explanation: Three ways to reach 5th stair: {1, 1, 1, 1, 1}, {1, 1, 1, 2} and {1, 2, 2}. -*/ - -namespace CountWaysToReachNthStairExcludeOrder -{ - class DynamicProgramming - { - private: - int RecursiveCountWaysToReachNthStairExcludeOrderHelper(int n); - public: - int RecursiveCountWaysToReachNthStairExcludeOrder(int n); - int DpCountWaysToReachNthStairExcludeOrder(int n); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0013_KnapsackProblem.h b/include/0005_DynamicProgramming/0013_KnapsackProblem.h deleted file mode 100644 index b7c90aa..0000000 --- a/include/0005_DynamicProgramming/0013_KnapsackProblem.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -using namespace std; - -/* -Pattern 2 -Subset / 0-1 Knapsack - -Description -Given n items where each item has some weight and profit associated with it and also given a bag with capacity W, [i.e., the bag can hold at most W weight in it]. The task is to put the items into the bag such that the sum of profits associated with them is the maximum possible. - -Note: The constraint here is we can either put an item completely into the bag or cannot put it at all [It is not possible to put a part of an item into the bag]. - -Input: W = 4, profit[] = [1, 2, 3], weight[] = [4, 5, 1] -Output: 3 -Explanation: There are two items which have weight less than or equal to 4. If we select the item with weight 4, the possible profit is 1. And if we select the item with weight 1, the possible profit is 3. So the maximum possible profit is 3. Note that we cannot put both the items with weight 4 and 1 together as the capacity of the bag is 4. - -Input: W = 3, profit[] = [1, 2, 3], weight[] = [4, 5, 6] -Output: 0 -*/ - -namespace KnapsackProblem -{ - class DynamicProgramming - { - private: - int KnapsackRecursiveHelper(int capacity, vector& weight, vector& profit, int numberOfItems); - public: - int RecursiveKnapsack(int capacity, vector weight, vector profit); - int DpKnapsack(int capacity, vector weight, vector profit); - int DpKnapsackSpaceOptimized(int capacity, vector weight, vector profit); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0014_SubsetSumProblem.h b/include/0005_DynamicProgramming/0014_SubsetSumProblem.h deleted file mode 100644 index 399d328..0000000 --- a/include/0005_DynamicProgramming/0014_SubsetSumProblem.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -using namespace std; - -/* -Pattern 2 -Subset / 0-1 Knapsack - -Description -Given an array arr[] of non-negative integers and a value sum, the task is to check if there is a subset of the given array whose sum is equal to the given sum. - -Examples: - -Input: arr[] = [3, 34, 4, 12, 5, 2], sum = 9 -Output: True -Explanation: There is a subset (4, 5) with sum 9. - -Input: arr[] = [3, 34, 4, 12, 5, 2], sum = 30 -Output: False -Explanation: There is no subset that add up to 30. -*/ - -namespace SubsetSumProblem -{ - class DynamicProgramming - { - private: - bool SubsetSumRecursiveHelper(vector& nums, int sum, int numberOfElements); - public: - bool RecursiveSubsetSum(vector nums, int sum); - bool DpIsSubsetSum(vector nums, int sum); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0015_CountSubsetsForSum.h b/include/0005_DynamicProgramming/0015_CountSubsetsForSum.h deleted file mode 100644 index 4f55bbf..0000000 --- a/include/0005_DynamicProgramming/0015_CountSubsetsForSum.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -using namespace std; - -/* -Pattern 2 -Subset / 0-1 Knapsack - -Description -Given an array arr[] of length n and an integer target, the task is to find the number of subsets with a sum equal to target. - -Examples: - -Input: arr[] = [1, 2, 3, 3], target = 6 -Output: 3 -Explanation: All the possible subsets are [1, 2, 3], [1, 2, 3] and [3, 3] - -Input: arr[] = [1, 1, 1, 1], target = 1 -Output: 4 -Explanation: All the possible subsets are [1], [1], [1] and [1] -*/ - -namespace CountSubsetsForSum -{ - class DynamicProgramming - { - private: - int RecursiveCountSubsetsHelper(vector& nums, int targetSum, int currentSum, int index); - public: - int RecursiveCountSubsets(vector nums, int sum); - int DpCountSubsets(vector nums, int sum); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0016_PartitionEqualSubsetSum.h b/include/0005_DynamicProgramming/0016_PartitionEqualSubsetSum.h deleted file mode 100644 index bf3c261..0000000 --- a/include/0005_DynamicProgramming/0016_PartitionEqualSubsetSum.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include -using namespace std; - -/* -Pattern 2 -Subset / 0-1 Knapsack - -Description -Given an array arr[], check if it can be partitioned into two parts such that the sum of elements in both parts is the same. -Note: Each element is present in either the first subset or the second subset, but not in both. - -Examples: - -Input: arr[] = [1, 5, 11, 5] -Output: true -Explanation: The array can be partitioned as [1, 5, 5] and [11] and the sum of both the subsets are equal. - -Input: arr[] = [1, 5, 3] -Output: false -Explanation: The array cannot be partitioned into equal sum sets. -*/ - -namespace PartitionEqualSubsetSum -{ - class DynamicProgramming - { - private: - bool RecursivePartitionEqualSubsetsHelper(vector& nums, int targetSum, int numberOfElements); - public: - bool RecursivePartitionEqualSubsets(vector nums); - bool DpPartitionEqualSubsets(vector nums); - }; -} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0017_TargetSum.h b/include/0005_DynamicProgramming/0017_TargetSum.h deleted file mode 100644 index 1ee27ad..0000000 --- a/include/0005_DynamicProgramming/0017_TargetSum.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include -using namespace std; - -/* -Pattern 2 -Subset / 0-1 Knapsack - -Description -Given an array arr[] of length N and an integer target. -You want to build an expression out of arr[] by adding one of the symbols '+' and '-' before each integer in arr[] and then concatenate all the integers. -Return the number of different expressions that can be built, which evaluates to target. - -Example: - -Input : N = 5, arr[] = {1, 1, 1, 1, 1}, target = 3 -Output: 5 -Explanation: -There are 5 ways to assign symbols to -make the sum of array be target 3. - --1 + 1 + 1 + 1 + 1 = 3 -+1 - 1 + 1 + 1 + 1 = 3 -+1 + 1 - 1 + 1 + 1 = 3 -+1 + 1 + 1 - 1 + 1 = 3 -+1 + 1 + 1 + 1 - 1 = 3 - -Input: N = 1, arr[] = {1}, target = 1 -Output: 1 -*/ - -namespace TargetSum -{ - class DynamicProgramming - { - private: - int RecursiveFindTotalWaysHelper(vector& nums, int currentSum, int targetSum, int index); - int DpFindTotalWays(); - public: - int RecursiveFindTotalWays(vector nums, int target); - int DpFindTotalWays(vector nums, int target); - }; -} \ No newline at end of file diff --git a/include/0006_BitwiseAlgorithms/CMakeLists.txt b/include/0006_BitwiseAlgorithms/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt deleted file mode 100644 index 65d79e1..0000000 --- a/include/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_subdirectory(0001_Basics) -add_subdirectory(0002_Tree) -add_subdirectory(0003_Graph) -add_subdirectory(0004_GreedyAlgorithms) -add_subdirectory(0005_DynamicProgramming) -add_subdirectory(0006_BitwiseAlgorithms) \ No newline at end of file diff --git a/src/0001_Basics/CMakeLists.txt b/src/0001_Basics/CMakeLists.txt deleted file mode 100644 index 199222f..0000000 --- a/src/0001_Basics/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Specify the source files -set(0001BASICS_SOURCES - Node.cc -) - -# Create a library target -add_library(0001BASICS ${0001BASICS_SOURCES}) \ No newline at end of file diff --git a/src/0001_Basics/Node.cc b/src/0001_Basics/Node.cc deleted file mode 100644 index 6a377d5..0000000 --- a/src/0001_Basics/Node.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include <0001_Basics/Node.h> - -Node::Node() -{ - value = 8; -} \ No newline at end of file diff --git a/src/0001_basics/CMakeLists.txt b/src/0001_basics/CMakeLists.txt new file mode 100644 index 0000000..b7ca5b3 --- /dev/null +++ b/src/0001_basics/CMakeLists.txt @@ -0,0 +1,11 @@ +# Specify the source files +set(0001BASICS_SOURCES + Node.cc +) + +# Create a library target +add_library(0001_Basics ${0001BASICS_SOURCES}) + +target_include_directories(0001_Basics PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/headers +) \ No newline at end of file diff --git a/include/0001_Basics/Node.h b/src/0001_basics/headers/node.h similarity index 100% rename from include/0001_Basics/Node.h rename to src/0001_basics/headers/node.h diff --git a/src/0001_basics/node.cc b/src/0001_basics/node.cc new file mode 100644 index 0000000..47482bc --- /dev/null +++ b/src/0001_basics/node.cc @@ -0,0 +1,6 @@ +#include "node.h" + +Node::Node() +{ + value = 8; +} \ No newline at end of file diff --git a/src/0002_Tree/CMakeLists.txt b/src/0002_Tree/CMakeLists.txt deleted file mode 100644 index cc7027a..0000000 --- a/src/0002_Tree/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Specify the source files -set(0002TREE_SOURCES - 0001_BinarySearchTree.cc -) - -# Create a library target -add_library(0002TREE ${0002TREE_SOURCES}) \ No newline at end of file diff --git a/src/0002_Tree/0001_BinarySearchTree.cc b/src/0002_tree/0001_binary_search_tree.cc similarity index 59% rename from src/0002_Tree/0001_BinarySearchTree.cc rename to src/0002_tree/0001_binary_search_tree.cc index 36e3489..3a9e2fc 100644 --- a/src/0002_Tree/0001_BinarySearchTree.cc +++ b/src/0002_tree/0001_binary_search_tree.cc @@ -1,9 +1,9 @@ -#include <0002_Tree/0001_BinarySearchTree.h> +#include "0001_binary_search_tree.h" #include #include using namespace std; -namespace BinarySearchTree +namespace dsa::binary_search_tree { Node::Node(int data, Node* parent, Node* left, Node* right) { @@ -19,7 +19,7 @@ namespace BinarySearchTree } - void BinarySearchTree::InsertBinarySearchTreeNode(Node* node) + void BinarySearchTree::_insert(Node* node) { Node* nodeY = nullptr; Node* nodeX = this->_root; @@ -50,7 +50,7 @@ namespace BinarySearchTree } } - Node* BinarySearchTree::FindBinarySearchTreeNode(int value) + Node* BinarySearchTree::_findNodeByValue(int value) { Node* node = this->_root; while (node != nullptr) @@ -71,7 +71,7 @@ namespace BinarySearchTree return node; } - Node* BinarySearchTree::FindBinarySearchTreeMinimumValueNode(Node* node) + Node* BinarySearchTree::_findMinimumValueNode(Node* node) { while (node->left != nullptr) { @@ -80,7 +80,7 @@ namespace BinarySearchTree return node; } - Node* BinarySearchTree::FindBinarySearchTreeMaximumValueNode(Node* node) + Node* BinarySearchTree::_findMaximumValueNode(Node* node) { while (node->right != nullptr) { @@ -89,11 +89,11 @@ namespace BinarySearchTree return node; } - Node* BinarySearchTree::FindSuccessorBinarySearchTreeNode(Node* node) + Node* BinarySearchTree::_findSuccessor(Node* node) { if (node->right != nullptr) { - return this->FindBinarySearchTreeMinimumValueNode(node->right); + return this->_findMinimumValueNode(node->right); } Node* nodeY = node->parent; while (nodeY != nullptr && node == nodeY->right) @@ -104,11 +104,11 @@ namespace BinarySearchTree return nodeY; } - Node* BinarySearchTree::FindPredecessorBinarySearchTreeNode(Node* node) + Node* BinarySearchTree::_findPredecessor(Node* node) { if (node->left != nullptr) { - return this->FindBinarySearchTreeMaximumValueNode(node->left); + return this->_findMaximumValueNode(node->left); } Node* nodeY = node->parent; while (nodeY != nullptr && node == nodeY->left) @@ -119,7 +119,7 @@ namespace BinarySearchTree return nodeY; } - void BinarySearchTree::TransplantBinarySearchTreeNode(Node* nodeU, Node* nodeV) + void BinarySearchTree::_transplant(Node* nodeU, Node* nodeV) { if (nodeU->parent == nullptr) { @@ -140,66 +140,66 @@ namespace BinarySearchTree } } - void BinarySearchTree::DeleteBinarySearchTreeNode(Node* node) + void BinarySearchTree::_delete(Node* node) { if (node->left == nullptr) { - this->TransplantBinarySearchTreeNode(node, node->right); + this->_transplant(node, node->right); } else if (node->right == nullptr) { - this->TransplantBinarySearchTreeNode(node, node->left); + this->_transplant(node, node->left); } else { - Node* nodeY = this->FindBinarySearchTreeMinimumValueNode(node->right); + Node* nodeY = this->_findMinimumValueNode(node->right); if (nodeY->parent != node) { - this->TransplantBinarySearchTreeNode(nodeY, nodeY->right); + this->_transplant(nodeY, nodeY->right); nodeY->right = node->right; nodeY->right->parent = nodeY; } - this->TransplantBinarySearchTreeNode(node, nodeY); + this->_transplant(node, nodeY); nodeY->left = node->left; nodeY->left->parent = nodeY; delete node; } } - void BinarySearchTree::RecursiveInorderTraversal(Node* node, vector& result) + void BinarySearchTree::_recursiveInorder(Node* node, vector& result) { if (node == nullptr) { return; } - this->RecursiveInorderTraversal(node->left, result); + this->_recursiveInorder(node->left, result); result.push_back(node->data); - this->RecursiveInorderTraversal(node->right, result); + this->_recursiveInorder(node->right, result); } - void BinarySearchTree::RecursivePreorderTraversal(Node* node, vector& result) + void BinarySearchTree::_recursivePreorder(Node* node, vector& result) { if (node == nullptr) { return; } result.push_back(node->data); - this->RecursivePreorderTraversal(node->left, result); - this->RecursivePreorderTraversal(node->right, result); + this->_recursivePreorder(node->left, result); + this->_recursivePreorder(node->right, result); } - void BinarySearchTree::RecursivePostorderTraversal(Node* node, vector& result) + void BinarySearchTree::_recursivePostorder(Node* node, vector& result) { if (node == nullptr) { return; } - this->RecursivePostorderTraversal(node->left, result); - this->RecursivePostorderTraversal(node->right, result); + this->_recursivePostorder(node->left, result); + this->_recursivePostorder(node->right, result); result.push_back(node->data); } - void BinarySearchTree::MorrisInorderTraversal(Node* node, vector& result) + void BinarySearchTree::_morrisInorder(Node* node, vector& result) { while (node != nullptr) { @@ -230,7 +230,7 @@ namespace BinarySearchTree } } - void BinarySearchTree::MorrisPreorderTraversal(Node* node, vector& result) + void BinarySearchTree::_morrisPreorder(Node* node, vector& result) { while (node != nullptr) { @@ -261,7 +261,7 @@ namespace BinarySearchTree } } - void BinarySearchTree::MorrisPostorderTraversal(Node* node, vector& result) + void BinarySearchTree::_morrisPostorder(Node* node, vector& result) { while (node != nullptr) { @@ -293,57 +293,57 @@ namespace BinarySearchTree reverse(result.begin(), result.end()); } - void BinarySearchTree::InsertNode(int value) + void BinarySearchTree::insertNode(int value) { Node* node = new Node(value, nullptr, nullptr, nullptr); - this->InsertBinarySearchTreeNode(node); + this->_insert(node); } - void BinarySearchTree::DeleteNode(int value) + void BinarySearchTree::deleteNode(int value) { - Node* node = this->FindBinarySearchTreeNode(value); - this->DeleteBinarySearchTreeNode(node); + Node* node = this->_findNodeByValue(value); + this->_delete(node); } - vector BinarySearchTree::GetRecursiveInorderTravesalResult() + vector BinarySearchTree::recursiveInorderTraversal() { vector result; - this->RecursiveInorderTraversal(this->_root, result); + this->_recursiveInorder(this->_root, result); return result; } - vector BinarySearchTree::GetRecursivePreorderTravesalResult() + vector BinarySearchTree::recursivePreorderTravesal() { vector result; - this->RecursivePreorderTraversal(this->_root, result); + this->_recursivePreorder(this->_root, result); return result; } - vector BinarySearchTree::GetRecursivePostorderTravesalResult() + vector BinarySearchTree::recursivePostorderTravesal() { vector result; - this->RecursivePostorderTraversal(this->_root, result); + this->_recursivePostorder(this->_root, result); return result; } - vector BinarySearchTree::GetMorrisInorderTraversalResult() + vector BinarySearchTree::morrisInorderTraversal() { vector result; - this->MorrisInorderTraversal(this->_root, result); + this->_morrisInorder(this->_root, result); return result; } - vector BinarySearchTree::GetMorrisPreorderTraversalResult() + vector BinarySearchTree::morrisPreorderTraversal() { vector result; - this->MorrisPreorderTraversal(this->_root, result); + this->_morrisPreorder(this->_root, result); return result; } - vector BinarySearchTree::GetMorrisPostorderTraversalResult() + vector BinarySearchTree::morrisPostorderTraversal() { vector result; - this->MorrisPostorderTraversal(this->_root, result); + this->_morrisPostorder(this->_root, result); return result; } } \ No newline at end of file diff --git a/src/0002_tree/CMakeLists.txt b/src/0002_tree/CMakeLists.txt new file mode 100644 index 0000000..4db770b --- /dev/null +++ b/src/0002_tree/CMakeLists.txt @@ -0,0 +1,11 @@ +# Specify the source files +set(0002TREE_SOURCES + 0001_binary_search_tree.cc +) + +# Create a library target +add_library(0002_Tree ${0002TREE_SOURCES}) + +target_include_directories(0002_Tree PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/headers +) \ No newline at end of file diff --git a/src/0002_tree/headers/0001_binary_search_tree.h b/src/0002_tree/headers/0001_binary_search_tree.h new file mode 100644 index 0000000..abdd87b --- /dev/null +++ b/src/0002_tree/headers/0001_binary_search_tree.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +using namespace std; + +namespace dsa::binary_search_tree +{ + class Node + { + public: + int data; + Node* parent; + Node* left; + Node* right; + + Node(int data, Node* parent, Node* left, Node* right); + }; + + class BinarySearchTree + { + private: + Node* _root; + void _insert(Node* node); + Node* _findNodeByValue(int value); + Node* _findMinimumValueNode(Node* node); + Node* _findMaximumValueNode(Node* node); + Node* _findSuccessor(Node* node); + Node* _findPredecessor(Node* node); + void _transplant(Node* nodeU, Node* nodeV); + void _delete(Node* node); + void _recursiveInorder(Node* node, vector& result); + void _recursivePreorder(Node* node, vector& result); + void _recursivePostorder(Node* node, vector& result); + void _morrisInorder(Node* node, vector& result); + void _morrisPreorder(Node* node, vector& result); + void _morrisPostorder(Node* node, vector& result); + public: + BinarySearchTree(); + void insertNode(int value); + void deleteNode(int value); + vector recursiveInorderTraversal(); + vector recursivePreorderTravesal(); + vector recursivePostorderTravesal(); + vector morrisInorderTraversal(); + vector morrisPreorderTraversal(); + vector morrisPostorderTraversal(); + }; +} \ No newline at end of file diff --git a/src/0003_Graph/CMakeLists.txt b/src/0003_Graph/CMakeLists.txt deleted file mode 100644 index 0b9177d..0000000 --- a/src/0003_Graph/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -# Specify the source files -set(0003GRAPH_SOURCES - 0001_BreadthFirstSearch.cc - 0002_DepthFirstSearch.cc - 0003_TopologicalSort.cc - 0004_StronglyConnectedComponents.cc - 0005_HamiltonianPathAndCycle.cc - 0006_EulerianPathAndCircuit.cc - 0007_MinimumSpanningTreeKruskalAlgorithm.cc - 0008_MinimumSpanningTreePrimAlgorithm.cc - 0009_SingleSourceShortestPathBellmanFord.cc - 0010_DirectedAcyclicGraphShortestPath.cc - 0011_SingleSourceShortestPathDijkstra.cc - 0012_DifferenceConstraintsShortestPaths.cc - 0013_AllPairsShortestPathsFloydWarshall.cc - 0014_AllPairsShortestPathsJohnson.cc - 0015_MaximumFlowFordFulkerson.cc - 0016_MaximumFlowEdmondsKarp.cc - 0017_MaximumBipartiteMatching.cc - 0018_MaximumFlowGoldbergGenericPushRelabel.cc - 0019_MaximumFlowRelabelToFront.cc - -) - -# Create a library target -add_library(0003GRAPH ${0003GRAPH_SOURCES}) \ No newline at end of file diff --git a/src/0003_Graph/0001_BreadthFirstSearch.cc b/src/0003_graph/0001_breadth_first_search.cc similarity index 74% rename from src/0003_Graph/0001_BreadthFirstSearch.cc rename to src/0003_graph/0001_breadth_first_search.cc index d16271a..20b47ee 100644 --- a/src/0003_Graph/0001_BreadthFirstSearch.cc +++ b/src/0003_graph/0001_breadth_first_search.cc @@ -1,4 +1,4 @@ -#include <0003_Graph/0001_BreadthFirstSearch.h> +#include "0001_breadth_first_search.h" #include #include #include @@ -7,7 +7,7 @@ #include using namespace std; -namespace BreadthFirstSearch +namespace dsa::breadth_first_search { Node::Node(int value) { @@ -17,7 +17,7 @@ namespace BreadthFirstSearch this->parent = nullptr; } - Node* Graph::MakeOrFindNode(int value) + Node* Graph::_makeOrFindNode(int value) { Node* node = nullptr; if (this->_nodeMap.find(value) == this->_nodeMap.end()) @@ -32,7 +32,7 @@ namespace BreadthFirstSearch return node; } - void Graph::BreadthFirstSearch(Node* node) + void Graph::_breadthFirstSearch(Node* node) { node->color = WHITE; node->distance = 0; @@ -60,21 +60,21 @@ namespace BreadthFirstSearch } } - void Graph::PushUndirectedEdge(int valueU, int valueV) + void Graph::pushUndirectedEdge(int valueU, int valueV) { - Node* nodeU = this->MakeOrFindNode(valueU); - Node* nodeV = this->MakeOrFindNode(valueV); + Node* nodeU = this->_makeOrFindNode(valueU); + Node* nodeV = this->_makeOrFindNode(valueV); this->_adjlist[nodeU].push_back(nodeV); this->_adjlist[nodeV].push_back(nodeU); } - void Graph::BFS(int value) + void Graph::bfs(int value) { - this->BreadthFirstSearch(this->_nodeMap[value]); + this->_breadthFirstSearch(this->_nodeMap[value]); } - vector> Graph::ShowBFSResult() + vector> Graph::showBFSResult() { vector> result; for (auto& node : this->_nodeMap) diff --git a/src/0003_Graph/0002_DepthFirstSearch.cc b/src/0003_graph/0002_depth_first_search.cc similarity index 71% rename from src/0003_Graph/0002_DepthFirstSearch.cc rename to src/0003_graph/0002_depth_first_search.cc index 873fe65..b3f510d 100644 --- a/src/0003_Graph/0002_DepthFirstSearch.cc +++ b/src/0003_graph/0002_depth_first_search.cc @@ -1,10 +1,10 @@ -#include <0003_Graph/0002_DepthFirstSearch.h> +#include "0002_depth_first_search.h" #include #include #include using namespace std; -namespace DepthFirstSearch +namespace dsa::depth_first_search { Node::Node(int value) { @@ -15,7 +15,7 @@ namespace DepthFirstSearch this->parent = nullptr; } - Node* Graph::MakeOrFindNode(int value) + Node* Graph::_makeOrFindNode(int value) { Node* node = nullptr; if (this->_nodeMap.find(value) == this->_nodeMap.end()) @@ -30,7 +30,7 @@ namespace DepthFirstSearch return node; } - void Graph::DepthFirstSearch(Node* nodeU) + void Graph::_depthFirstSearch(Node* nodeU) { this->_time++; nodeU->discoveredTime = this->_time; @@ -40,7 +40,7 @@ namespace DepthFirstSearch if (nodeV->color == WHITE) { nodeV->parent = nodeU; - this->DepthFirstSearch(nodeV); + this->_depthFirstSearch(nodeV); } } nodeU->color = BLACK; @@ -48,27 +48,27 @@ namespace DepthFirstSearch nodeU->finishingTime = this->_time; } - void Graph::PushDirectedEdge(int valueU, int valueV) + void Graph::pushDirectedEdge(int valueU, int valueV) { - Node* nodeU = this->MakeOrFindNode(valueU); - Node* nodeV = this->MakeOrFindNode(valueV); + Node* nodeU = this->_makeOrFindNode(valueU); + Node* nodeV = this->_makeOrFindNode(valueV); this->_adjlist[nodeU].push_back(nodeV); } - void Graph::DFS() + void Graph::dfs() { this->_time = 0; for (auto& iterator : this->_nodeMap) { if (iterator.second->color == WHITE) { - this->DepthFirstSearch(iterator.second); + this->_depthFirstSearch(iterator.second); } } } - vector>> Graph::ShowDFSResult() + vector>> Graph::showDFSResult() { vector>> result; for (auto& node : this->_nodeMap) diff --git a/src/0003_Graph/0003_TopologicalSort.cc b/src/0003_graph/0003_topological_sort.cc similarity index 72% rename from src/0003_Graph/0003_TopologicalSort.cc rename to src/0003_graph/0003_topological_sort.cc index 5cf20c2..bade828 100644 --- a/src/0003_Graph/0003_TopologicalSort.cc +++ b/src/0003_graph/0003_topological_sort.cc @@ -1,4 +1,4 @@ -#include <0003_Graph/0003_TopologicalSort.h> +#include "0003_topological_sort.h" #include #include #include @@ -6,7 +6,7 @@ #include using namespace std; -namespace TopologicalSort +namespace dsa::topological_sort { Node::Node(int value) { @@ -18,7 +18,7 @@ namespace TopologicalSort this->parent = nullptr; } - Node* Graph::MakeOrFindNode(int value) + Node* Graph::_makeOrFindNode(int value) { Node* node = nullptr; if (this->_nodeMap.find(value) == this->_nodeMap.end()) @@ -33,7 +33,7 @@ namespace TopologicalSort return node; } - void Graph::DepthFirstSearch(Node* nodeU) + void Graph::_depthFirstSearch(Node* nodeU) { this->_time++; nodeU->discoveryTime = this->_time; @@ -43,7 +43,7 @@ namespace TopologicalSort if (nodeV->color == WHITE) { nodeV->parent = nodeU; - this->DepthFirstSearch(nodeV); + this->_depthFirstSearch(nodeV); } else if (nodeV->color == GRAY) { @@ -57,28 +57,28 @@ namespace TopologicalSort this->_topologicalSortedNodeList.push_front(nodeU); } - void Graph::PushDirectedEdge(int valueU, int valueV) + void Graph::pushDirectedEdge(int valueU, int valueV) { - Node* nodeU = this->MakeOrFindNode(valueU); - Node* nodeV = this->MakeOrFindNode(valueV); + Node* nodeU = this->_makeOrFindNode(valueU); + Node* nodeV = this->_makeOrFindNode(valueV); this->_adjlist[nodeU].push_back(nodeV); nodeV->inDegree++; } - void Graph::PushSingleNode(int valueU) + void Graph::pushSingleNode(int valueU) { - this->MakeOrFindNode(valueU); + this->_makeOrFindNode(valueU); } - void Graph::TopologicalSort() + void Graph::topologicalSort() { this->_time = 0; for (auto& iterator : this->_nodeMap) { if (iterator.second->color == WHITE) { - this->DepthFirstSearch(iterator.second); + this->_depthFirstSearch(iterator.second); if (this->_hasCycle == true) { break; @@ -87,14 +87,14 @@ namespace TopologicalSort } } - void Graph::KahnTopologicalSort() + void Graph::kahnTopologicalSort() { - // Step-1 Compute in-degree of each vertices - // This is already done while creating the graph + // step-1 compute in-degree of each vertices + // this is already done while creating the graph this->_time = 0; queue nodeQueue; - // Step-2 Enqueue vertices with in-degree 0 + // step-2 enqueue vertices with in-degree 0 for (auto& node : this->_nodeMap) { if (node.second->inDegree == 0) @@ -105,7 +105,7 @@ namespace TopologicalSort } } - // Step-3 Process vertices in queue + // step-3 process vertices in queue while (!nodeQueue.empty()) { Node* node = nodeQueue.front(); @@ -114,7 +114,7 @@ namespace TopologicalSort node->finishingTime = this->_time; this->_topologicalSortedNodeList.push_back(node); - // Step-4 Process all the neighbours of current node based on in-degree + // step-4 process all the neighbours of current node based on in-degree for (auto& neighbour : this->_adjlist[node]) { neighbour->inDegree--; @@ -127,14 +127,14 @@ namespace TopologicalSort } } - // Step-5 Check if a cycle exists + // step-5 check if a cycle exists if (this->_topologicalSortedNodeList.size() != this->_nodeMap.size()) { this->_hasCycle = true; } } - vector>> Graph::ShowTopologicalSortResult() + vector>> Graph::showTopologicalSortResult() { if (this->_hasCycle == true) { diff --git a/src/0003_Graph/0004_StronglyConnectedComponents.cc b/src/0003_graph/0004_strongly_connected_components.cc similarity index 62% rename from src/0003_Graph/0004_StronglyConnectedComponents.cc rename to src/0003_graph/0004_strongly_connected_components.cc index f3d8efe..bc45596 100644 --- a/src/0003_Graph/0004_StronglyConnectedComponents.cc +++ b/src/0003_graph/0004_strongly_connected_components.cc @@ -1,10 +1,10 @@ -#include <0003_Graph/0004_StronglyConnectedComponents.h> +#include "0004_strongly_connected_components.h" #include #include #include using namespace std; -namespace StronglyConnectedComponents +namespace dsa::strongly_connected_components { Node::Node(int value) { @@ -15,7 +15,7 @@ namespace StronglyConnectedComponents this->parent = nullptr; } - Node* Graph::MakeOrFindNode(int value) + Node* Graph::_makeOrFindNode(int value) { Node* node = nullptr; if (this->_nodeMap.find(value) == this->_nodeMap.end()) @@ -30,7 +30,7 @@ namespace StronglyConnectedComponents return node; } - void Graph::DepthFirstSearchOnGraphG(Node* nodeU) + void Graph::_depthFirstSearchOnGraphG(Node* nodeU) { this->_time++; nodeU->discoveryTime = this->_time; @@ -40,7 +40,7 @@ namespace StronglyConnectedComponents if (nodeV->color == WHITE) { nodeV->parent = nodeU; - this->DepthFirstSearchOnGraphG(nodeV); + this->_depthFirstSearchOnGraphG(nodeV); } } nodeU->color = BLACK; @@ -49,7 +49,7 @@ namespace StronglyConnectedComponents this->_nodesFinishingTimeOrder.push_front(nodeU); } - void Graph::DepthFirstSearchOnGraphT(Node* nodeU, vector& connectedComponents) + void Graph::_depthFirstSearchOnGraphT(Node* nodeU, vector& connectedComponents) { nodeU->color = GRAY; connectedComponents.push_back(nodeU->data); @@ -58,42 +58,42 @@ namespace StronglyConnectedComponents if (nodeV->color == WHITE) { nodeV->parent = nodeU; - this->DepthFirstSearchOnGraphT(nodeV, connectedComponents); + this->_depthFirstSearchOnGraphT(nodeV, connectedComponents); } } nodeU->color = BLACK; } - void Graph::PushDirectedEdge(int valueU, int valueV) + void Graph::pushDirectedEdge(int valueU, int valueV) { - Node* nodeU = this->MakeOrFindNode(valueU); - Node* nodeV = this->MakeOrFindNode(valueV); + Node* nodeU = this->_makeOrFindNode(valueU); + Node* nodeV = this->_makeOrFindNode(valueV); - // Creating the actual graph. + // creating the actual graph. this->_adjlistG[nodeU].push_back(nodeV); - // Creating the transpose of the actual graph. + // creating the transpose of the actual graph. this->_adjlistT[nodeV].push_back(nodeU); } - void Graph::PushSingleNode(int valueU) + void Graph::pushSingleNode(int valueU) { - this->MakeOrFindNode(valueU); + this->_makeOrFindNode(valueU); } - void Graph::DFSOnGraphG() + void Graph::dFSOnGraphG() { this->_time = 0; for (auto& iterator : this->_nodeMap) { if (iterator.second->color == WHITE) { - this->DepthFirstSearchOnGraphG(iterator.second); + this->_depthFirstSearchOnGraphG(iterator.second); } } } - void Graph::DFSOnGraphT() + void Graph::dFSOnGraphT() { for (auto& iterator : this->_nodeMap) { @@ -106,16 +106,16 @@ namespace StronglyConnectedComponents if (iterator->color == WHITE) { vector connectedComponents; - this->DepthFirstSearchOnGraphT(iterator, connectedComponents); + this->_depthFirstSearchOnGraphT(iterator, connectedComponents); this->_allConnectedComponents.push_back(connectedComponents); } } } - vector> Graph::FindAllStronglyConnectedComponents() + vector> Graph::findAllStronglyConnectedComponents() { - this->DFSOnGraphG(); - this->DFSOnGraphT(); + this->dFSOnGraphG(); + this->dFSOnGraphT(); return this->_allConnectedComponents; } } \ No newline at end of file diff --git a/src/0003_Graph/0005_HamiltonianPathAndCycle.cc b/src/0003_graph/0005_hamiltonian_path_and_cycle.cc similarity index 67% rename from src/0003_Graph/0005_HamiltonianPathAndCycle.cc rename to src/0003_graph/0005_hamiltonian_path_and_cycle.cc index 1466b2a..11eae5d 100644 --- a/src/0003_Graph/0005_HamiltonianPathAndCycle.cc +++ b/src/0003_graph/0005_hamiltonian_path_and_cycle.cc @@ -1,7 +1,7 @@ -#include <0003_Graph/0005_HamiltonianPathAndCycle.h> +#include "0005_hamiltonian_path_and_cycle.h" using namespace std; -namespace HamiltonianPathAndCycle +namespace dsa::hamiltonian_path_and_cycle { Node::Node(int value) { @@ -9,8 +9,8 @@ namespace HamiltonianPathAndCycle this->isVisited = false; } - // Graph Private Member Methods - Node* Graph::MakeOrFindNode(int value) + // Graph private member methods + Node* Graph::_makeOrFindNode(int value) { Node* node = nullptr; if (this->_nodeMap.find(value) == this->_nodeMap.end()) @@ -25,7 +25,7 @@ namespace HamiltonianPathAndCycle return node; } - bool Graph::IsSafe(Node* nodeU, Node* nodeV) + bool Graph::_isSafe(Node* nodeU, Node* nodeV) { if (this->_adjlist[nodeU].find(nodeV) == this->_adjlist[nodeU].end()) { @@ -38,7 +38,7 @@ namespace HamiltonianPathAndCycle return true; } - bool Graph::HamiltonianCycleAndPathUtil(Node* nodeU) + bool Graph::_hamiltonianCycleAndPathUtil(Node* nodeU) { if (this->_visitedNodeCount == this->_nodeMap.size()) { @@ -53,12 +53,12 @@ namespace HamiltonianPathAndCycle } for (auto& nodeV : this->_adjlist[nodeU]) { - if (this->IsSafe(nodeU, nodeV)) + if (this->_isSafe(nodeU, nodeV)) { this->_hamiltonianPath.push_back(nodeV->data); nodeV->isVisited = true; this->_visitedNodeCount++; - if (this->HamiltonianCycleAndPathUtil(nodeV)) + if (this->_hamiltonianCycleAndPathUtil(nodeV)) { return true; } @@ -70,22 +70,22 @@ namespace HamiltonianPathAndCycle return false; } - // Graph Public Member Methods - void Graph::PushUndirectedEdge(int valueU, int valueV) + // Graph public member methods + void Graph::pushUndirectedEdge(int valueU, int valueV) { - Node* nodeU = this->MakeOrFindNode(valueU); - Node* nodeV = this->MakeOrFindNode(valueV); + Node* nodeU = this->_makeOrFindNode(valueU); + Node* nodeV = this->_makeOrFindNode(valueV); this->_adjlist[nodeU].insert(nodeV); this->_adjlist[nodeV].insert(nodeU); } - void Graph::PushSingleNode(int valueU) + void Graph::pushSingleNode(int valueU) { - this->MakeOrFindNode(valueU); + this->_makeOrFindNode(valueU); } - void Graph::FindHamiltonianCycleAndPath() + void Graph::findHamiltonianCycleAndPath() { this->_isHamiltonianCyclePresent = false; this->_isHamiltonianPathPresent = false; @@ -94,20 +94,20 @@ namespace HamiltonianPathAndCycle this->_hamiltonianPath.push_back(this->_startingNode->data); this->_startingNode->isVisited = true; this->_visitedNodeCount = 1; - this->HamiltonianCycleAndPathUtil(this->_startingNode); + this->_hamiltonianCycleAndPathUtil(this->_startingNode); } - bool Graph::IsHamiltonianCyclePresent() + bool Graph::isHamiltonianCyclePresent() { return this->_isHamiltonianCyclePresent; } - bool Graph::IsHamiltonianPathPresent() + bool Graph::isHamiltonianPathPresent() { return this->_isHamiltonianPathPresent; } - vector Graph::GetHamiltonianPath() + vector Graph::getHamiltonianPath() { return this->_hamiltonianPath; } diff --git a/src/0003_Graph/0006_EulerianPathAndCircuit.cc b/src/0003_graph/0006_eulerian_path_and_circuit.cc similarity index 61% rename from src/0003_Graph/0006_EulerianPathAndCircuit.cc rename to src/0003_graph/0006_eulerian_path_and_circuit.cc index 88f4cd9..a08279a 100644 --- a/src/0003_Graph/0006_EulerianPathAndCircuit.cc +++ b/src/0003_graph/0006_eulerian_path_and_circuit.cc @@ -1,9 +1,9 @@ -#include <0003_Graph/0006_EulerianPathAndCircuit.h> +#include "0006_eulerian_path_and_circuit.h" #include #include using namespace std; -namespace EulerianPathAndCircuit +namespace dsa::eulerian_path_and_circuit { Node::Node(int value) { @@ -14,8 +14,8 @@ namespace EulerianPathAndCircuit this->visited = false; } - // Graph Private Member Methods - Node* Graph::MakeOrFindNode(int value) + // Graph private member methods + Node* Graph::_makeOrFindNode(int value) { Node* node = nullptr; if (this->_nodeMap.find(value) == this->_nodeMap.end()) @@ -30,23 +30,23 @@ namespace EulerianPathAndCircuit return node; } - void Graph::DepthFirstSearch(Node* nodeU) + void Graph::_depthFirstSearch(Node* nodeU) { nodeU->visited = true; for (auto& nodeV : this->_adjlist[nodeU]) { if (nodeV->visited == false) { - this->DepthFirstSearch(nodeV); + this->_depthFirstSearch(nodeV); } } } - bool Graph::IsConnected() + bool Graph::_isConnected() { - // Step-1 : Make the visited property of all nodes as false. It is already done in constructor. + // step-1 : make the visited property of all nodes as false. it is already done in constructor. - // Step-2 : Find a node which do not have 0 degree. + // step-2 : find a node which do not have 0 degree. Node* node = nullptr; for (auto& iterator : this->_nodeMap) { @@ -57,15 +57,15 @@ namespace EulerianPathAndCircuit } } - // Step-3 : If node is null, it means G.E is null, so G is connected, else call DFS to traverse the graph G. + // step-3 : if node is null, it means G.E is null, so G is connected, else call DFS to traverse the graph G. if (node == nullptr) { return true; } - this->DepthFirstSearch(node); + this->_depthFirstSearch(node); - // Step-4 : Checking if all the non-zero degree vertices have been visited or not. + // step-4 : checking if all the non-zero degree vertices have been visited or not. for (auto& iterator : this->_nodeMap) { if (iterator.second->visited == false && iterator.second->degree != 0) @@ -76,7 +76,7 @@ namespace EulerianPathAndCircuit return true; } - void Graph::EulerianPathHierholzerAlgorithm(Node* startingNode) + void Graph::_eulerianPathHierholzerAlgorithm(Node* startingNode) { stack currentPath; currentPath.push(startingNode); @@ -98,11 +98,11 @@ namespace EulerianPathAndCircuit } } - // Graph Public Member Methods - void Graph::PushUndirectedEdge(int valueU, int valueV) + // Graph public member methods + void Graph::pushUndirectedEdge(int valueU, int valueV) { - Node* nodeU = this->MakeOrFindNode(valueU); - Node* nodeV = this->MakeOrFindNode(valueV); + Node* nodeU = this->_makeOrFindNode(valueU); + Node* nodeV = this->_makeOrFindNode(valueV); this->_adjlist[nodeU].push_back(nodeV); nodeU->degree++; @@ -110,25 +110,25 @@ namespace EulerianPathAndCircuit nodeV->degree++; } - void Graph::PushDirectedEdge(int valueU, int valueV) + void Graph::pushDirectedEdge(int valueU, int valueV) { - Node* nodeU = this->MakeOrFindNode(valueU); - Node* nodeV = this->MakeOrFindNode(valueV); + Node* nodeU = this->_makeOrFindNode(valueU); + Node* nodeV = this->_makeOrFindNode(valueV); this->_adjlist[nodeU].push_back(nodeV); nodeU->outDegree++; nodeV->inDegree++; } - void Graph::PushSingleNode(int valueU) + void Graph::pushSingleNode(int valueU) { - this->MakeOrFindNode(valueU); + this->_makeOrFindNode(valueU); } - void Graph::FindEulerianPathAndCircuit() + void Graph::findEulerianPathAndCircuit() { - // If the graph is not connected then graph G is Not-Eulerian. - if (this->IsConnected() == false) + // if the graph is not connected then graph G is not-eulerian. + if (this->_isConnected() == false) { this->_isEulerianPathPresent = false; this->_isEulerianCircuitPresent = false; @@ -144,7 +144,7 @@ namespace EulerianPathAndCircuit } } - // Check-1 : When no vertex with odd degree is present, then graph G is Eulerian. + // check-1 : when no vertex with odd degree is present, then graph G is eulerian. if (oddDegreeVertexCount == 0) { this->_isEulerianPathPresent = true; @@ -152,7 +152,7 @@ namespace EulerianPathAndCircuit return; } - // Check-2 : When 2 vertices have odd degree, then graph G is Semi-Eulerian. + // check-2 : when 2 vertices have odd degree, then graph G is semi-eulerian. if (oddDegreeVertexCount == 2) { this->_isEulerianPathPresent = true; @@ -160,7 +160,7 @@ namespace EulerianPathAndCircuit return; } - // Check-3 : When more than 2 vertices have odd degree, then graph G is Not Eulerian. + // check-3 : when more than 2 vertices have odd degree, then graph G is not eulerian. if (oddDegreeVertexCount > 2) { this->_isEulerianPathPresent = false; @@ -169,27 +169,27 @@ namespace EulerianPathAndCircuit } } - bool Graph::IsEulerianPathPresent() + bool Graph::isEulerianPathPresent() { return this->_isEulerianPathPresent; } - bool Graph::IsEulerianCircuitPresent() + bool Graph::isEulerianCircuitPresent() { return this->_isEulerianCircuitPresent; } - vector Graph::UndirectedGraphGetEulerianPath() + vector Graph::undirectedGraphGetEulerianPath() { - // Case-3 : When more than 2 vertices have odd degree, then the graph G is not Eulerian. - // No Eulerian Path is posible. + // Case-3 : when more than 2 vertices have odd degree, then the graph G is not eulerian. + // no eulerian path is posible. if (this->_isEulerianPathPresent == false) { return {}; } - // Now 2 cases remains. - // Case-2 : When 2 vertices have odd degree. Choose any one of them. + // now 2 cases remains. + // Case-2 : when 2 vertices have odd degree. choose any one of them. Node* node = nullptr; for (auto& iterator : this->_nodeMap) { @@ -200,12 +200,12 @@ namespace EulerianPathAndCircuit } } - // Case-1 : When no vertex with odd degree is present. Choose any vertex as starting point. + // Case-1 : when no vertex with odd degree is present. choose any vertex as starting point. if (node == nullptr) { node = this->_nodeMap[0]; } - this->EulerianPathHierholzerAlgorithm(node); + this->_eulerianPathHierholzerAlgorithm(node); reverse(this->_eulerianPath.begin(), this->_eulerianPath.end()); return this->_eulerianPath; } diff --git a/src/0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithm.cc b/src/0003_graph/0007_minimum_spanning_tree_kruskal_algorithm.cc similarity index 59% rename from src/0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithm.cc rename to src/0003_graph/0007_minimum_spanning_tree_kruskal_algorithm.cc index 90d3d8f..9989a3f 100644 --- a/src/0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithm.cc +++ b/src/0003_graph/0007_minimum_spanning_tree_kruskal_algorithm.cc @@ -1,9 +1,9 @@ -#include <0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithm.h> +#include "0007_minimum_spanning_tree_kruskal_algorithm.h" #include #include using namespace std; -namespace MinimumSpanningTreeKruskalAlgorithm +namespace dsa::minimum_spanning_tree_kruskal_algorithm { Node::Node(int data) { @@ -19,8 +19,8 @@ namespace MinimumSpanningTreeKruskalAlgorithm this->weight = weight; } - // Graph Private Member Methods - Node* Graph::MakeOrFindNode(int data) + // Graph private member methods + Node* Graph::_makeOrFindNode(int data) { Node* node = nullptr; if (this->_nodeMap.find(data) == this->_nodeMap.end()) @@ -35,18 +35,18 @@ namespace MinimumSpanningTreeKruskalAlgorithm return node; } - void Graph::MakeSet(Node* node) + void Graph::_makeSet(Node* node) { node->parent = node; node->rank = 0; } - void Graph::Union(Node* nodeU, Node* nodeV) + void Graph::_unionSet(Node* nodeU, Node* nodeV) { - this->Link(this->FindSet(nodeU), this->FindSet(nodeV)); + this->_linkSet(this->_findSet(nodeU), this->_findSet(nodeV)); } - void Graph::Link(Node* nodeU, Node* nodeV) + void Graph::_linkSet(Node* nodeU, Node* nodeV) { if (nodeV->rank > nodeU->rank) { @@ -62,46 +62,46 @@ namespace MinimumSpanningTreeKruskalAlgorithm } } - Node* Graph::FindSet(Node* node) + Node* Graph::_findSet(Node* node) { if (node != node->parent) { - node->parent = this->FindSet(node->parent); + node->parent = this->_findSet(node->parent); } return node->parent; } - // Graph Public Member Methods - void Graph::PushUndirectedEdge(int dataU, int dataV, int weight) + // Graph public member methods + void Graph::pushUndirectedEdge(int dataU, int dataV, int weight) { - Node* nodeU = this->MakeOrFindNode(dataU); - Node* nodeV = this->MakeOrFindNode(dataV); + Node* nodeU = this->_makeOrFindNode(dataU); + Node* nodeV = this->_makeOrFindNode(dataV); this->_adjlist[nodeU].push_back(nodeV); this->_adjlist[nodeV].push_back(nodeU); this->_edgeList.push_back(new Edge(nodeU, nodeV, weight)); } - void Graph::FindMinimumSpanningTreeKruskalAlgorithm() + void Graph::findMinimumSpanningTreeKruskalAlgorithm() { for (auto& iterator : this->_nodeMap) { - this->MakeSet(iterator.second); + this->_makeSet(iterator.second); } sort(this->_edgeList.begin(), this->_edgeList.end(), [](Edge* edgeX, Edge* edgeY) { return edgeX->weight < edgeY->weight; }); for (auto& edge : this->_edgeList) { - if (this->FindSet(edge->nodeU) != this->FindSet(edge->nodeV)) + if (this->_findSet(edge->nodeU) != this->_findSet(edge->nodeV)) { - this->Union(edge->nodeU, edge->nodeV); + this->_unionSet(edge->nodeU, edge->nodeV); this->_minimumSpanningTree.push_back({ {edge->nodeU->data, edge->nodeV->data}, edge->weight }); } } } - vector, int>> Graph::GetMinimumSpanningTree() + vector, int>> Graph::getMinimumSpanningTree() { return this->_minimumSpanningTree; } diff --git a/src/0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.cc b/src/0003_graph/0008_minimum_spanning_tree_prim_algorithm.cc similarity index 74% rename from src/0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.cc rename to src/0003_graph/0008_minimum_spanning_tree_prim_algorithm.cc index 83340b8..fbdb94a 100644 --- a/src/0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.cc +++ b/src/0003_graph/0008_minimum_spanning_tree_prim_algorithm.cc @@ -1,9 +1,9 @@ -#include <0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.h> +#include "0008_minimum_spanning_tree_prim_algorithm.h" #include using namespace std; -namespace MinimumSpanningTreePrimAlgorithm +namespace dsa::minimum_spanning_tree_prim_algorithm { Node::Node(int data) { @@ -13,8 +13,8 @@ namespace MinimumSpanningTreePrimAlgorithm this->isInOperationalSet = false; } - // Graph Private Member Methods - Node* Graph::MakeOrFindNode(int data) + // Graph private member methods + Node* Graph::_makeOrFindNode(int data) { Node* node = nullptr; if (this->_nodeMap.find(data) == this->_nodeMap.end()) @@ -29,17 +29,17 @@ namespace MinimumSpanningTreePrimAlgorithm return node; } - // Graph Public Member Methods - void Graph::PushUndirectedEdge(int dataU, int dataV, int weight) + // Graph public member methods + void Graph::pushUndirectedEdge(int dataU, int dataV, int weight) { - Node* nodeU = this->MakeOrFindNode(dataU); - Node* nodeV = this->MakeOrFindNode(dataV); + Node* nodeU = this->_makeOrFindNode(dataU); + Node* nodeV = this->_makeOrFindNode(dataV); this->_adjlist[nodeU].push_back({nodeV, weight}); this->_adjlist[nodeV].push_back({nodeU, weight}); } - void Graph::FindMinimumSpanningTreePrimAlgorithm() + void Graph::findMinimumSpanningTreePrimAlgorithm() { Node* root = this->_nodeMap.begin()->second; @@ -78,7 +78,7 @@ namespace MinimumSpanningTreePrimAlgorithm } } - vector, int>> Graph::GetMinimumSpanningTree() + vector, int>> Graph::getMinimumSpanningTree() { return this->_minimumSpanningTree; } diff --git a/src/0003_Graph/0009_SingleSourceShortestPathBellmanFord.cc b/src/0003_graph/0009_single_source_shortest_path_bellman_ford.cc similarity index 65% rename from src/0003_Graph/0009_SingleSourceShortestPathBellmanFord.cc rename to src/0003_graph/0009_single_source_shortest_path_bellman_ford.cc index 5b036ac..fa2109b 100644 --- a/src/0003_Graph/0009_SingleSourceShortestPathBellmanFord.cc +++ b/src/0003_graph/0009_single_source_shortest_path_bellman_ford.cc @@ -1,9 +1,9 @@ -#include <0003_Graph/0009_SingleSourceShortestPathBellmanFord.h> +#include "0009_single_source_shortest_path_bellman_ford.h" #include #include using namespace std; -namespace SingleSourceShortestPathBellmanFord +namespace dsa::single_source_shortest_path_bellman_ford { Node::Node(int data) { @@ -19,8 +19,8 @@ namespace SingleSourceShortestPathBellmanFord this->weight = weight; } - // Graph Private Member Methods - Node* Graph::MakeOrFindNode(int data) + // Graph private member methods + Node* Graph::_makeOrFindNode(int data) { Node* node = nullptr; if (this->_nodeMap.find(data) == this->_nodeMap.end()) @@ -35,7 +35,7 @@ namespace SingleSourceShortestPathBellmanFord return node; } - void Graph :: InitializeSingleSource(Node* sourceNode) + void Graph :: _initializeSingleSource(Node* sourceNode) { for (auto& iterator : this->_nodeMap) { @@ -45,7 +45,7 @@ namespace SingleSourceShortestPathBellmanFord sourceNode->distance = 0; } - void Graph::Relax(Edge* edge) + void Graph::_relax(Edge* edge) { if (edge->nodeU->distance != INT_MAX && (edge->nodeV->distance > (edge->nodeU->distance + edge->weight))) { @@ -54,36 +54,36 @@ namespace SingleSourceShortestPathBellmanFord } } - void Graph::GetShortestPath(Node* node, vector& path) + void Graph::_getShortestPath(Node* node, vector& path) { path.push_back(node->data); if (node->parent != nullptr) { - this->GetShortestPath(node->parent, path); + this->_getShortestPath(node->parent, path); } } - // Graph Public Member Methods - void Graph::PushDirectedEdge(int dataU, int dataV, int weight) + // Graph public member methods + void Graph::pushDirectedEdge(int dataU, int dataV, int weight) { - Node* nodeU = this->MakeOrFindNode(dataU); - Node* nodeV = this->MakeOrFindNode(dataV); + Node* nodeU = this->_makeOrFindNode(dataU); + Node* nodeV = this->_makeOrFindNode(dataV); this->_adjlist[nodeU].push_back(nodeV); this->_edgeList.push_back(new Edge(nodeU, nodeV, weight)); } - bool Graph::FindSingleSourceShortestPathBellmanFord(int data) + bool Graph::findSingleSourceShortestPathBellmanFord(int data) { Node* source = this->_nodeMap[data]; - this->InitializeSingleSource(source); + this->_initializeSingleSource(source); for (int i = 0; i < this->_nodeMap.size() - 1; i++) { for (auto& edge : this->_edgeList) { - this->Relax(edge); + this->_relax(edge); } } @@ -97,11 +97,11 @@ namespace SingleSourceShortestPathBellmanFord return true; } - vector Graph::GetShortestPathBellmanFord(int data) + vector Graph::getShortestPathBellmanFord(int data) { vector path = {}; Node* node = this->_nodeMap[data]; - this->GetShortestPath(node, path); + this->_getShortestPath(node, path); reverse(path.begin(), path.end()); return path; } diff --git a/src/0003_Graph/0010_DirectedAcyclicGraphShortestPath.cc b/src/0003_graph/0010_directed_acyclic_graph_shortest_path.cc similarity index 64% rename from src/0003_Graph/0010_DirectedAcyclicGraphShortestPath.cc rename to src/0003_graph/0010_directed_acyclic_graph_shortest_path.cc index a0d1ab2..e5733fe 100644 --- a/src/0003_Graph/0010_DirectedAcyclicGraphShortestPath.cc +++ b/src/0003_graph/0010_directed_acyclic_graph_shortest_path.cc @@ -1,9 +1,9 @@ -#include <0003_Graph/0010_DirectedAcyclicGraphShortestPath.h> +#include "0010_directed_acyclic_graph_shortest_path.h" #include #include using namespace std; -namespace DirectedAcyclicGraphShortestPath +namespace dsa::directed_acyclic_graph_shortest_path { Node::Node(int data) { @@ -20,8 +20,8 @@ namespace DirectedAcyclicGraphShortestPath this->weight = weight; } - // Graph Private Member Methods - Node* Graph::MakeOrFindNode(int data) + // Graph private member methods + Node* Graph::_makeOrFindNode(int data) { Node* node = nullptr; if (this->_nodeMap.find(data) == this->_nodeMap.end()) @@ -36,32 +36,32 @@ namespace DirectedAcyclicGraphShortestPath return node; } - void Graph::DepthFirstSearch(Node* nodeU) + void Graph::_depthFirstSearch(Node* nodeU) { nodeU->color = GRAY; for (auto& nodeV : this->_adjlist[nodeU]) { if (nodeV->color == WHITE) { - this->DepthFirstSearch(nodeV); + this->_depthFirstSearch(nodeV); } } nodeU->color = BLACK; this->_topologicalSortedNodeList.push_front(nodeU); } - void Graph::TopologicalSort() + void Graph::_topologicalSort() { for (auto& iterator : this->_nodeMap) { if (iterator.second->color == WHITE) { - this->DepthFirstSearch(iterator.second); + this->_depthFirstSearch(iterator.second); } } } - void Graph::InitializeSingleSource(Node* sourceNode) + void Graph::_initializeSingleSource(Node* sourceNode) { for (auto& iterator : this->_nodeMap) { @@ -71,7 +71,7 @@ namespace DirectedAcyclicGraphShortestPath sourceNode->distance = 0; } - void Graph::Relax(Edge* edge) + void Graph::_relax(Edge* edge) { if (edge->nodeU->distance != INT_MAX && (edge->nodeV->distance > (edge->nodeU->distance + edge->weight))) { @@ -80,44 +80,44 @@ namespace DirectedAcyclicGraphShortestPath } } - void Graph::GetShortestPath(Node* node, vector& path) + void Graph::_getShortestPath(Node* node, vector& path) { path.push_back(node->data); if (node->parent != nullptr) { - this->GetShortestPath(node->parent, path); + this->_getShortestPath(node->parent, path); } } - // Graph Public Member Methods - void Graph::PushDirectedEdge(int dataU, int dataV, int weight) + // Graph public member methods + void Graph::pushDirectedEdge(int dataU, int dataV, int weight) { - Node* nodeU = this->MakeOrFindNode(dataU); - Node* nodeV = this->MakeOrFindNode(dataV); + Node* nodeU = this->_makeOrFindNode(dataU); + Node* nodeV = this->_makeOrFindNode(dataV); this->_adjlist[nodeU].push_back(nodeV); this->_edgeMap[nodeU].push_back(new Edge(nodeU, nodeV, weight)); } - void Graph::FindDAGShortestPath(int data) + void Graph::findDAGShortestPath(int data) { - this->TopologicalSort(); + this->_topologicalSort(); Node* source = this->_nodeMap[data]; - this->InitializeSingleSource(source); + this->_initializeSingleSource(source); for (auto& node : this->_topologicalSortedNodeList) { for (auto& edge : this->_edgeMap[node]) { - this->Relax(edge); + this->_relax(edge); } } } - vector Graph::GetDAGShortestPath(int data) + vector Graph::getDAGShortestPath(int data) { vector path = {}; Node* node = this->_nodeMap[data]; - this->GetShortestPath(node, path); + this->_getShortestPath(node, path); reverse(path.begin(), path.end()); return path; } diff --git a/src/0003_Graph/0011_SingleSourceShortestPathDijkstra.cc b/src/0003_graph/0011_single_source_shortest_path_dijkstra.cc similarity index 66% rename from src/0003_Graph/0011_SingleSourceShortestPathDijkstra.cc rename to src/0003_graph/0011_single_source_shortest_path_dijkstra.cc index d84e844..ab2c3c9 100644 --- a/src/0003_Graph/0011_SingleSourceShortestPathDijkstra.cc +++ b/src/0003_graph/0011_single_source_shortest_path_dijkstra.cc @@ -1,9 +1,9 @@ -#include <0003_Graph/0011_SingleSourceShortestPathDijkstra.h> +#include "0011_single_source_shortest_path_dijkstra.h" #include #include using namespace std; -namespace SingleSourceShortestPathDijkstra +namespace dsa::single_source_shortest_path_dijkstra { Node::Node(int data) { @@ -19,8 +19,8 @@ namespace SingleSourceShortestPathDijkstra this->weight = weight; } - // Graph Private Member Methods - Node* Graph::MakeOrFindNode(int data) + // Graph private member methods + Node* Graph::_makeOrFindNode(int data) { Node* node = nullptr; if (this->_nodeMap.find(data) == this->_nodeMap.end()) @@ -35,7 +35,7 @@ namespace SingleSourceShortestPathDijkstra return node; } - void Graph::InitializeSingleSource(Node* sourceNode) + void Graph::_initializeSingleSource(Node* sourceNode) { for (auto& iterator : this->_nodeMap) { @@ -45,7 +45,7 @@ namespace SingleSourceShortestPathDijkstra sourceNode->distance = 0; } - void Graph::Relax(Edge* edge) + void Graph::_relax(Edge* edge) { if (edge->nodeU->distance != INT_MAX && (edge->nodeV->distance > (edge->nodeU->distance + edge->weight))) { @@ -56,9 +56,9 @@ namespace SingleSourceShortestPathDijkstra } } - void Graph::Dijkstra(Node* source) + void Graph::_dijkstra(Node* source) { - this->InitializeSingleSource(source); + this->_initializeSingleSource(source); for (auto& node : this->_nodeMap) { @@ -72,41 +72,41 @@ namespace SingleSourceShortestPathDijkstra for (auto& edge : this->_edgeMap[nodeU]) { - this->Relax(edge); + this->_relax(edge); } } } - void Graph::GetShortestPath(Node* node, vector& path) + void Graph::_getShortestPath(Node* node, vector& path) { path.push_back(node->data); if (node->parent != nullptr) { - this->GetShortestPath(node->parent, path); + this->_getShortestPath(node->parent, path); } } - // Graph Public Member Methods - void Graph::PushDirectedEdge(int dataU, int dataV, int weight) + // Graph public member methods + void Graph::pushDirectedEdge(int dataU, int dataV, int weight) { - Node* nodeU = this->MakeOrFindNode(dataU); - Node* nodeV = this->MakeOrFindNode(dataV); + Node* nodeU = this->_makeOrFindNode(dataU); + Node* nodeV = this->_makeOrFindNode(dataV); this->_adjlist[nodeU].push_back(nodeV); this->_edgeMap[nodeU].push_back(new Edge(nodeU, nodeV, weight)); } - void Graph::FindShortestPathDijkstra(int data) + void Graph::findShortestPathDijkstra(int data) { Node* source = this->_nodeMap[data]; - this->Dijkstra(source); + this->_dijkstra(source); } - vector Graph::GetDijkstraShortestPath(int data) + vector Graph::getDijkstraShortestPath(int data) { vector path = {}; Node* node = this->_nodeMap[data]; - this->GetShortestPath(node, path); + this->_getShortestPath(node, path); reverse(path.begin(), path.end()); return path; } diff --git a/src/0003_Graph/0012_DifferenceConstraintsShortestPaths.cc b/src/0003_graph/0012_difference_constraints_shortest_paths.cc similarity index 67% rename from src/0003_Graph/0012_DifferenceConstraintsShortestPaths.cc rename to src/0003_graph/0012_difference_constraints_shortest_paths.cc index 91bbdfd..bab6d5f 100644 --- a/src/0003_Graph/0012_DifferenceConstraintsShortestPaths.cc +++ b/src/0003_graph/0012_difference_constraints_shortest_paths.cc @@ -1,8 +1,8 @@ -#include <0003_Graph/0012_DifferenceConstraintsShortestPaths.h> +#include "0012_difference_constraints_shortest_paths.h" #include using namespace std; -namespace DifferenceConstraintsShortestPaths +namespace dsa::difference_constraints_shortest_paths { Node::Node(string data) { @@ -17,8 +17,8 @@ namespace DifferenceConstraintsShortestPaths this->weight = weight; } - // Graph Private Member Methods - Node* Graph::MakeOrFindNode(string data) + // Graph private member methods + Node* Graph::_makeOrFindNode(string data) { Node* node = nullptr; if (this->_nodeMap.find(data) == this->_nodeMap.end()) @@ -33,16 +33,16 @@ namespace DifferenceConstraintsShortestPaths return node; } - void Graph::PushDirectedEdge(string dataU, string dataV, int weight) + void Graph::_pushDirectedEdge(string dataU, string dataV, int weight) { - Node* nodeU = this->MakeOrFindNode(dataU); - Node* nodeV = this->MakeOrFindNode(dataV); + Node* nodeU = this->_makeOrFindNode(dataU); + Node* nodeV = this->_makeOrFindNode(dataV); this->_adjlist[nodeU].push_back(nodeV); this->_edgeList.push_back(new Edge(nodeU, nodeV, weight)); } - void Graph::InitializeSingleSource(Node* sourceNode) + void Graph::_initializeSingleSource(Node* sourceNode) { for (auto& iterator : this->_nodeMap) { @@ -51,7 +51,7 @@ namespace DifferenceConstraintsShortestPaths sourceNode->distance = 0; } - void Graph::Relax(Edge* edge) + void Graph::_relax(Edge* edge) { if (edge->nodeU->distance != INT_MAX && (edge->nodeV->distance > (edge->nodeU->distance + edge->weight))) { @@ -59,10 +59,10 @@ namespace DifferenceConstraintsShortestPaths } } - // Graph Public Member Methods - void Graph::PushAllDirectedEdges(vector> vectorA, vector vectorX, vector vectorB) + // Graph public member methods + void Graph::pushAllDirectedEdges(vector> vectorA, vector vectorX, vector vectorB) { - // Creating the Actual Graph + // creating the actual Graph string valueU = ""; string valueV = ""; int weight = 0; @@ -80,31 +80,31 @@ namespace DifferenceConstraintsShortestPaths } } weight = vectorB[i]; - this->PushDirectedEdge(valueU, valueV, weight); + this->_pushDirectedEdge(valueU, valueV, weight); } - // Creating all the edges from the additional vertex + // creating all the edges from the additional vertex valueU = ""; valueV = ""; weight = 0; for (int i = 0; i < vectorX.size(); i++) { valueV = vectorX[i]; - this->PushDirectedEdge(valueU, valueV, weight); + this->_pushDirectedEdge(valueU, valueV, weight); } } - bool Graph::FindDifferenceConstraintsSolutionBellmanFord() + bool Graph::findDifferenceConstraintsSolutionBellmanFord() { Node* source = this->_nodeMap[""]; - this->InitializeSingleSource(source); + this->_initializeSingleSource(source); for (int i = 0; i < this->_nodeMap.size(); i++) { for (auto& edge : this->_edgeList) { - this->Relax(edge); + this->_relax(edge); } } @@ -118,7 +118,7 @@ namespace DifferenceConstraintsShortestPaths return true; } - vector> Graph::GetDifferenceConstrtaintsSolution() + vector> Graph::getDifferenceConstrtaintsSolution() { vector> result; for (auto& node : this->_nodeMap) diff --git a/src/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.cc b/src/0003_graph/0013_all_pairs_shortest_paths_floyd_warshall.cc similarity index 76% rename from src/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.cc rename to src/0003_graph/0013_all_pairs_shortest_paths_floyd_warshall.cc index d3eeea6..71e26e9 100644 --- a/src/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.cc +++ b/src/0003_graph/0013_all_pairs_shortest_paths_floyd_warshall.cc @@ -1,11 +1,11 @@ -#include <0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h> +#include "0013_all_pairs_shortest_paths_floyd_warshall.h" #include using namespace std; -namespace AllPairsShortestPathsFloydWarshall +namespace dsa::all_pairs_shortest_paths_floyd_warshall { - // Graph Private Member Methods - void Graph::InitializeDistanceAndPredecessors() + // Graph private member methods + void Graph::_initializeDistanceAndPredecessors() { this->_shortestPathMatrixFloydWarshall = this->_adjMatrix; @@ -25,18 +25,18 @@ namespace AllPairsShortestPathsFloydWarshall } } - void Graph::GetShortestPath(int source, int destination, vector& path) + void Graph::_getShortestPath(int source, int destination, vector& path) { if (this->_predecessorMatrix[source - 1][destination - 1] != source) { int predecessor = this->_predecessorMatrix[source - 1][destination - 1]; - this->GetShortestPath(source, predecessor, path); + this->_getShortestPath(source, predecessor, path); path.push_back(predecessor); } } - // Graph Public Member Methods - void Graph::CreateGraph(int noOfVertices) + // Graph public member methods + void Graph::createGraph(int noOfVertices) { this->_noOfVertices = noOfVertices; this->_adjMatrix = vector>(this->_noOfVertices, vector(this->_noOfVertices, INT_MAX)); @@ -55,14 +55,14 @@ namespace AllPairsShortestPathsFloydWarshall } } - void Graph::PushDirectedEdge(int valueU, int valueV, int weight) + void Graph::pushDirectedEdge(int valueU, int valueV, int weight) { this->_adjMatrix[valueU - 1][valueV - 1] = weight; } - void Graph::FindAllPairsShortestPathsFloydWarshallSolution() + void Graph::findAllPairsShortestPathsFloydWarshallSolution() { - this->InitializeDistanceAndPredecessors(); + this->_initializeDistanceAndPredecessors(); for (int k = 0; k < this->_noOfVertices; k++) { @@ -82,7 +82,7 @@ namespace AllPairsShortestPathsFloydWarshall } } - vector> Graph::GetFloydWarshallShortestPath() + vector> Graph::getFloydWarshallShortestPath() { vector> result; for (int i = 0; i < this->_noOfVertices; i++) @@ -93,7 +93,7 @@ namespace AllPairsShortestPathsFloydWarshall { vector path = {}; path.push_back(i + 1); - this->GetShortestPath(i + 1, j + 1, path); + this->_getShortestPath(i + 1, j + 1, path); path.push_back(j + 1); result.push_back(path); } diff --git a/src/0003_Graph/0014_AllPairsShortestPathsJohnson.cc b/src/0003_graph/0014_all_pairs_shortest_paths_johnson.cc similarity index 73% rename from src/0003_Graph/0014_AllPairsShortestPathsJohnson.cc rename to src/0003_graph/0014_all_pairs_shortest_paths_johnson.cc index 05d1df2..25a92ff 100644 --- a/src/0003_Graph/0014_AllPairsShortestPathsJohnson.cc +++ b/src/0003_graph/0014_all_pairs_shortest_paths_johnson.cc @@ -1,8 +1,8 @@ -#include <0003_Graph/0014_AllPairsShortestPathsJohnson.h> +#include "0014_all_pairs_shortest_paths_johnson.h" #include using namespace std; -namespace AllPairsShortestPathsJohnson +namespace dsa::all_pairs_shortest_paths_johnson { Node::Node(int data) { @@ -19,8 +19,8 @@ namespace AllPairsShortestPathsJohnson this->weight = weight; } - // Graph Private Member Methods - Node* Graph::MakeOrFindNode(int data) + // Graph private member methods + Node* Graph::_makeOrFindNode(int data) { Node* node = nullptr; if (this->_nodeMap.find(data) == this->_nodeMap.end()) @@ -35,13 +35,13 @@ namespace AllPairsShortestPathsJohnson return node; } - void Graph::PushAugmentedDirectedEdges(Node* sourceNode, Node* nodeV, int weight) + void Graph::_pushAugmentedDirectedEdges(Node* sourceNode, Node* nodeV, int weight) { this->_augmentedAdjlist[sourceNode].push_back(nodeV); this->_augmentedEdgeList.push_back(new Edge(sourceNode, nodeV, weight)); } - void Graph::InitializeSingleSource(Node* sourceNode) + void Graph::_initializeSingleSource(Node* sourceNode) { for (auto& iterator : this->_nodeMap) { @@ -51,7 +51,7 @@ namespace AllPairsShortestPathsJohnson sourceNode->distance = 0; } - void Graph::RelaxBellmanFord(Edge* edge) + void Graph::_relaxBellmanFord(Edge* edge) { if (edge->nodeU->distance != INT_MAX && (edge->nodeV->distance > (edge->nodeU->distance + edge->weight))) { @@ -60,15 +60,15 @@ namespace AllPairsShortestPathsJohnson } } - bool Graph::BellmanFord(Node* source) + bool Graph::_bellmanFord(Node* source) { - this->InitializeSingleSource(source); + this->_initializeSingleSource(source); for (int i = 0; i < this->_nodeMap.size() - 1; i++) { for (auto& edge : this->_augmentedEdgeList) { - this->RelaxBellmanFord(edge); + this->_relaxBellmanFord(edge); } } @@ -82,7 +82,7 @@ namespace AllPairsShortestPathsJohnson return true; } - void Graph::RelaxDijkstra(Edge* edge) + void Graph::_relaxDijkstra(Edge* edge) { if (edge->nodeU->distance != INT_MAX && (edge->nodeV->distance > (edge->nodeU->distance + edge->weight))) { @@ -93,9 +93,9 @@ namespace AllPairsShortestPathsJohnson } } - void Graph::Dijkstra(Node* source) + void Graph::_dijkstra(Node* source) { - this->InitializeSingleSource(source); + this->_initializeSingleSource(source); for (auto& node : this->_nodeMap) { @@ -109,26 +109,26 @@ namespace AllPairsShortestPathsJohnson for (auto& edge : this->_edgeMap[nodeU]) { - this->RelaxDijkstra(edge); + this->_relaxDijkstra(edge); } } } - void Graph::GetShortestPath(int source, int destination, vector& path) + void Graph::_getShortestPath(int source, int destination, vector& path) { if (this->_predecessorMatrix[source - 1][destination - 1] != source) { int predecessor = this->_predecessorMatrix[source - 1][destination - 1]; - this->GetShortestPath(source, predecessor, path); + this->_getShortestPath(source, predecessor, path); path.push_back(predecessor); } } - // Graph Public Member Methods - void Graph::PushDirectedEdge(int dataU, int dataV, int weight) + // Graph public member methods + void Graph::pushDirectedEdge(int dataU, int dataV, int weight) { - Node* nodeU = this->MakeOrFindNode(dataU); - Node* nodeV = this->MakeOrFindNode(dataV); + Node* nodeU = this->_makeOrFindNode(dataU); + Node* nodeV = this->_makeOrFindNode(dataV); this->_adjlist[nodeU].push_back(nodeV); Edge* edge = new Edge(nodeU, nodeV, weight); @@ -136,26 +136,26 @@ namespace AllPairsShortestPathsJohnson this->_edgeList.push_back(edge); } - bool Graph::FindAllPairsShortestPathsJohnsonAlgorithm() + bool Graph::findAllPairsShortestPathsJohnsonAlgorithm() { - // Creating the graph G' + // creating the graph G' this->_augmentedAdjlist = this->_adjlist; this->_augmentedEdgeList = this->_edgeList; - // Source Node s + // source Node s Node* source = new Node(0); this->_nodeMap[0] = source; - // Creating all the augmented edges in G'.E = G.E U {(s, v) : v in G.V + // creating all the augmented edges in G'.E = G.E U {(s, v) : v in G.V for (auto& node : this->_nodeMap) { if (node.second != source) { - this->PushAugmentedDirectedEdges(source, node.second, 0); + this->_pushAugmentedDirectedEdges(source, node.second, 0); } } - if (this->BellmanFord(source) == false) + if (this->_bellmanFord(source) == false) { return false; } @@ -178,7 +178,7 @@ namespace AllPairsShortestPathsJohnson for (auto& iteratorU : this->_nodeMap) { Node* nodeU = iteratorU.second; - this->Dijkstra(nodeU); + this->_dijkstra(nodeU); for (auto& iteratorV : this->_nodeMap) { Node* nodeV = iteratorV.second; @@ -190,12 +190,12 @@ namespace AllPairsShortestPathsJohnson } } - vector> Graph::GetAllPairsShortestPathsDistanceMatrix() + vector> Graph::getAllPairsShortestPathsDistanceMatrix() { return this->_shortestPathMatrix; } - vector> Graph::GetAllPairsShortestPathsPathMatrix() + vector> Graph::getAllPairsShortestPathsPathMatrix() { vector> result; for (int i = 0; i < this->_noOfVertices; i++) @@ -206,7 +206,7 @@ namespace AllPairsShortestPathsJohnson { vector path = {}; path.push_back(i + 1); - this->GetShortestPath(i + 1, j + 1, path); + this->_getShortestPath(i + 1, j + 1, path); path.push_back(j + 1); result.push_back(path); } diff --git a/src/0003_Graph/0015_MaximumFlowFordFulkerson.cc b/src/0003_graph/0015_maximum_flow_ford_fulkerson.cc similarity index 69% rename from src/0003_Graph/0015_MaximumFlowFordFulkerson.cc rename to src/0003_graph/0015_maximum_flow_ford_fulkerson.cc index d7c41ed..90dde88 100644 --- a/src/0003_Graph/0015_MaximumFlowFordFulkerson.cc +++ b/src/0003_graph/0015_maximum_flow_ford_fulkerson.cc @@ -1,11 +1,11 @@ -#include <0003_Graph/0015_MaximumFlowFordFulkerson.h> +#include "0015_maximum_flow_ford_fulkerson.h" #include using namespace std; -namespace MaximumFlowFordFulkerson +namespace dsa::maximum_flow_ford_fulkerson { - // Graph Private Member Methods - void Graph::ResolveAntiParallelEdges() + // Graph private member methods + void Graph::_resolveAntiParallelEdges() { int countParallelEdges = 0; for (int i = 0; i < this->_noOfVertices; i++) @@ -19,12 +19,12 @@ namespace MaximumFlowFordFulkerson } } - // As i->j and j->i both edges has been counted, actual count is count = count / 2 + // as i->j and j->i both edges has been counted, actual count is count = count / 2 countParallelEdges /= 2; this->_flagParallelEdges = countParallelEdges > 0; - // If there are no anti-parallel edges, no need to modify the adjMatrix + // if there are no anti-parallel edges, no need to modify the adjMatrix if (!this->_flagParallelEdges) { return; @@ -32,7 +32,7 @@ namespace MaximumFlowFordFulkerson int newNoOfVertices = this->_noOfVertices + countParallelEdges; - // Modifying the adjMatrix + // modifying the adjMatrix for (auto& edge : this->_adjMatrix) { edge.resize(newNoOfVertices, 0); @@ -42,7 +42,7 @@ namespace MaximumFlowFordFulkerson this->_parent.resize(newNoOfVertices, -1); this->_adjMatrix.resize(newNoOfVertices, vector(newNoOfVertices, 0)); - // Removing the anti-parallel edges by adding new nodes + // removing the anti-parallel edges by adding new nodes for (int i = 0; i < this->_noOfVertices; i++) { for (int j = 0; j < this->_noOfVertices; j++) @@ -57,11 +57,11 @@ namespace MaximumFlowFordFulkerson } } - // Updating the total no of vertices after modifying the adjMatrix + // updating the total no of vertices after modifying the adjMatrix this->_noOfVertices = newNoOfVertices; } - void Graph::DepthFirstSearchVisit(int nodeU) + void Graph::_depthFirstSearchVisit(int nodeU) { this->_visited[nodeU] = true; for (int nodeV = 0; nodeV < this->_noOfVertices; nodeV++) @@ -69,28 +69,28 @@ namespace MaximumFlowFordFulkerson if (!this->_visited[nodeV] && this->_residualGraph[nodeU][nodeV] > 0) { this->_parent[nodeV] = nodeU; - this->DepthFirstSearchVisit(nodeV); + this->_depthFirstSearchVisit(nodeV); } } } - bool Graph::DepthFirstSearch() + bool Graph::_depthFirstSearch() { - // Resetting the visited values + // resetting the visited values fill(this->_visited.begin(), this->_visited.end(), false); - // Resetting the parent values + // resetting the parent values fill(this->_parent.begin(), this->_parent.end(), -1); - // Starting the DepthFirstSearch from the source vertex - this->DepthFirstSearchVisit(this->_source); + // starting the depthFirstSearch from the source vertex + this->_depthFirstSearchVisit(this->_source); - // Returning the visited value of the sink vertex, initially it was set to false + // returning the visited value of the sink vertex, initially it was set to false return this->_visited[this->_sink]; } - // Graph Public Member Methods - void Graph::CreateGraph(int noOfVertices) + // Graph public member methods + void Graph::createGraph(int noOfVertices) { this->_noOfVertices = noOfVertices; this->_source = 0; @@ -102,23 +102,23 @@ namespace MaximumFlowFordFulkerson this->_visited = vector(this->_noOfVertices, false); } - void Graph::PushDirectedEdge(int valueU, int valueV, int capacity) + void Graph::pushDirectedEdge(int valueU, int valueV, int capacity) { this->_adjMatrix[valueU][valueV] = capacity; } - int Graph::FindMaximumFlowFordFulkerson() + int Graph::findMaximumFlowFordFulkerson() { - // Resolving all the parallel edges if present - this->ResolveAntiParallelEdges(); + // resolving all the parallel edges if present + this->_resolveAntiParallelEdges(); this->_residualGraph = this->_adjMatrix; - // While there exists a path p from source to sink in the residual network G' - while (this->DepthFirstSearch()) + // while there exists a path p from source to sink in the residual network G' + while (this->_depthFirstSearch()) { int augmentedPathFlow = INT_MAX; - // Calculating c'(p) = min{ c'(u,v) : (u,v) is in p } + // calculating c'(p) = min{ c'(u,v) : (u,v) is in p } for (int nodeV = this->_sink; nodeV > this->_source; nodeV = this->_parent[nodeV]) { int nodeU = this->_parent[nodeV]; diff --git a/src/0003_Graph/0016_MaximumFlowEdmondsKarp.cc b/src/0003_graph/0016_maximum_flow_edmonds_karp.cc similarity index 74% rename from src/0003_Graph/0016_MaximumFlowEdmondsKarp.cc rename to src/0003_graph/0016_maximum_flow_edmonds_karp.cc index 25340fe..4cb9a6f 100644 --- a/src/0003_Graph/0016_MaximumFlowEdmondsKarp.cc +++ b/src/0003_graph/0016_maximum_flow_edmonds_karp.cc @@ -1,12 +1,12 @@ -#include <0003_Graph/0016_MaximumFlowEdmondsKarp.h> +#include "0016_maximum_flow_edmonds_karp.h" #include #include using namespace std; -namespace MaximumFlowEdmondsKarp +namespace dsa::maximum_flow_edmonds_karp { - // Graph Private Member Methods - void Graph::ResolveAntiParallelEdges() + // Graph private member methods + void Graph::_resolveAntiParallelEdges() { int countParallelEdges = 0; for (int i = 0; i < this->_noOfVertices; i++) @@ -20,12 +20,12 @@ namespace MaximumFlowEdmondsKarp } } - // As i->j and j->i both edges has been counted, actual count is count = count / 2 + // as i->j and j->i both edges has been counted, actual count is count = count / 2 countParallelEdges /= 2; this->_flagParallelEdges = countParallelEdges > 0; - // If there are no anti-parallel edges, no need to modify the adjMatrix + // if there are no anti-parallel edges, no need to modify the adjMatrix if (!this->_flagParallelEdges) { return; @@ -33,7 +33,7 @@ namespace MaximumFlowEdmondsKarp int newNoOfVertices = this->_noOfVertices + countParallelEdges; - // Modifying the adjMatrix + // modifying the adjMatrix for (auto& edge : this->_adjMatrix) { edge.resize(newNoOfVertices, 0); @@ -43,7 +43,7 @@ namespace MaximumFlowEdmondsKarp this->_parent.resize(newNoOfVertices, -1); this->_adjMatrix.resize(newNoOfVertices, vector(newNoOfVertices, 0)); - // Removing the anti-parallel edges by adding new nodes + // removing the anti-parallel edges by adding new nodes for (int i = 0; i < this->_noOfVertices; i++) { for (int j = 0; j < this->_noOfVertices; j++) @@ -58,16 +58,16 @@ namespace MaximumFlowEdmondsKarp } } - // Updating the total no of vertices after modifying the adjMatrix + // updating the total no of vertices after modifying the adjMatrix this->_noOfVertices = newNoOfVertices; } - bool Graph::BreadthFirstSearch() + bool Graph::_breadthFirstSearch() { - // Resetting the visited values + // resetting the visited values fill(this->_visited.begin(), this->_visited.end(), false); - // Resetting the parent values + // resetting the parent values fill(this->_parent.begin(), this->_parent.end(), -1); queue nodeQueue; @@ -90,12 +90,12 @@ namespace MaximumFlowEdmondsKarp } } - // Returning the visited value of the sink vertex, initially it was set to false + // returning the visited value of the sink vertex, initially it was set to false return this->_visited[this->_sink]; } - // Graph Public Member Methods - void Graph::CreateGraph(int noOfVertices) + // Graph public member methods + void Graph::createGraph(int noOfVertices) { this->_noOfVertices = noOfVertices; this->_source = 0; @@ -107,23 +107,23 @@ namespace MaximumFlowEdmondsKarp this->_visited = vector(this->_noOfVertices, false); } - void Graph::PushDirectedEdge(int valueU, int valueV, int capacity) + void Graph::pushDirectedEdge(int valueU, int valueV, int capacity) { this->_adjMatrix[valueU][valueV] = capacity; } - int Graph::FindMaximumFlowEdmondsKarp() + int Graph::findMaximumFlowEdmondsKarp() { - // Resolving all the parallel edges if present - this->ResolveAntiParallelEdges(); + // resolving all the parallel edges if present + this->_resolveAntiParallelEdges(); this->_residualGraph = this->_adjMatrix; - // While there exists a path p from source to sink in the residual network G' - while (this->BreadthFirstSearch()) + // while there exists a path p from source to sink in the residual network G' + while (this->_breadthFirstSearch()) { int augmentedPathFlow = INT_MAX; - // Calculating c'(p) = min{ c'(u,v) : (u,v) is in p } + // calculating c'(p) = min{ c'(u,v) : (u,v) is in p } for (int nodeV = this->_sink; nodeV > this->_source; nodeV = this->_parent[nodeV]) { int nodeU = this->_parent[nodeV]; diff --git a/src/0003_Graph/0017_MaximumBipartiteMatching.cc b/src/0003_graph/0017_maximum_bipartite_matching.cc similarity index 68% rename from src/0003_Graph/0017_MaximumBipartiteMatching.cc rename to src/0003_graph/0017_maximum_bipartite_matching.cc index 18224a2..c309ef8 100644 --- a/src/0003_Graph/0017_MaximumBipartiteMatching.cc +++ b/src/0003_graph/0017_maximum_bipartite_matching.cc @@ -1,12 +1,12 @@ -#include <0003_Graph/0017_MaximumBipartiteMatching.h> +#include "0017_maximum_bipartite_matching.h" #include #include using namespace std; -namespace MaximumBipartiteMatching +namespace dsa::maximum_bipartite_matching { - // Graph Private Member Methods - void Graph::ResolveAntiParallelEdges() + // Graph private member methods + void Graph::_resolveAntiParallelEdges() { int countParallelEdges = 0; for (int i = 0; i < this->_noOfVertices; i++) @@ -20,12 +20,12 @@ namespace MaximumBipartiteMatching } } - // As i->j and j->i both edges has been counted, actual count is count = count / 2 + // as i->j and j->i both edges has been counted, actual count is count = count / 2 countParallelEdges /= 2; this->_flagParallelEdges = countParallelEdges > 0; - // If there are no anti-parallel edges, no need to modify the adjMatrix + // if there are no anti-parallel edges, no need to modify the adjMatrix if (!this->_flagParallelEdges) { return; @@ -33,7 +33,7 @@ namespace MaximumBipartiteMatching int newNoOfVertices = this->_noOfVertices + countParallelEdges; - // Modifying the adjMatrix + // modifying the adjMatrix for (auto& edge : this->_adjMatrix) { edge.resize(newNoOfVertices, 0); @@ -43,7 +43,7 @@ namespace MaximumBipartiteMatching this->_parent.resize(newNoOfVertices, -1); this->_adjMatrix.resize(newNoOfVertices, vector(newNoOfVertices, 0)); - // Removing the anti-parallel edges by adding new nodes + // removing the anti-parallel edges by adding new nodes for (int i = 0; i < this->_noOfVertices; i++) { for (int j = 0; j < this->_noOfVertices; j++) @@ -58,14 +58,14 @@ namespace MaximumBipartiteMatching } } - // Updating the total no of vertices after modifying the adjMatrix + // updating the total no of vertices after modifying the adjMatrix this->_noOfVertices = newNoOfVertices; } - // This method is used to color the vertices of the graph to determine if the given graph is bipartite or not - void Graph::ColorGraph() + // this method is used to color the vertices of the graph to determine if the given graph is bipartite or not + void Graph::_colorGraph() { - // Color of all the vertices are initialised to WHITE + // color of all the vertices are initialised to WHITE fill(this->_color.begin(), this->_color.end(), WHITE); // Queue to hold the vertices @@ -73,41 +73,41 @@ namespace MaximumBipartiteMatching for (int node = 0; node < this->_noOfVertices; node++) { - // Check if the node is already not colored + // check if the node is already not colored if (this->_color[node] == WHITE) { - // The color of the node is set to RED + // the color of the node is set to RED this->_color[node] = RED; - // The node is inserted into the queue + // the node is inserted into the queue nodeQueue.push(node); - // Using BFS method to color all the vertices + // using BFS method to color all the vertices while (!nodeQueue.empty()) { int nodeU = nodeQueue.front(); nodeQueue.pop(); - // Iterating over G.Adj[nodeU] + // iterating over G.adj[nodeU] for (int nodeV = 0; nodeV < this->_noOfVertices; nodeV++) { - // As there are no self loops, continue + // as there are no self loops, continue if (nodeU == nodeV) { continue; } - // Check if there is an edge u --> v and nodeV is not colored yet + // check if there is an edge u --> v and nodeV is not colored yet else if (this->_residualGraph[nodeU][nodeV] != 0 && this->_color[nodeV] == WHITE) { - // Set the color of nodeV opposite of nodeU + // set the color of nodeV opposite of nodeU this->_color[nodeV] = 1 - this->_color[nodeU]; - // Insert the nodeV into the queue + // insert the nodeV into the queue nodeQueue.push(nodeV); } - // Check if there is an edge u --> v and nodeV is of same color as nodeU + // check if there is an edge u --> v and nodeV is of same color as nodeU else if (this->_residualGraph[nodeU][nodeV] != 0 && this->_color[nodeV] == this->_color[nodeU]) { - // Set the _isBipartite flag to false and return + // set the _isBipartite flag to false and return this->_isBipartite = false; return; } @@ -116,18 +116,18 @@ namespace MaximumBipartiteMatching } } - // If the above operation completes without returning yet that indicates the graph is bipartite - // Set the _isBipartite flag to true and return + // if the above operation completes without returning yet that indicates the graph is bipartite + // set the _isBipartite flag to true and return this->_isBipartite = true; return; } - // This method is used to create the additional edges + // this method is used to create the additional edges // from the source vertex to the RED colored vertices and // from the BLUE colored vertices to the sink vertex - void Graph::AddAdditionalEdges() + void Graph::_addAdditionalEdges() { - // Resizing the residual graph to accomodate space for the new edges + // resizing the residual graph to accomodate space for the new edges for (auto& edge : this->_residualGraph) { edge.resize(this->_noOfVertices, 0); @@ -138,16 +138,16 @@ namespace MaximumBipartiteMatching this->_color.resize(this->_noOfVertices, WHITE); this->_residualGraph.resize(this->_noOfVertices, vector(this->_noOfVertices, 0)); - // Creating the additional edges + // creating the additional edges for (int node = 0; node < this->_source; node++) { - // From source vertex --> RED colored vertices + // from source vertex --> RED colored vertices if (this->_color[node] == RED) { this->_residualGraph[this->_source][node] = 1; } - // From BLUE colored vertices --> sink vertex + // from BLUE colored vertices --> sink vertex else if (this->_color[node] == BLUE) { this->_residualGraph[node][this->_sink] = 1; @@ -155,13 +155,13 @@ namespace MaximumBipartiteMatching } } - // Implementation of BreadthFirstSearch for EdmondsKarp algorithm to find the path from source to sink - bool Graph::BreadthFirstSearch() + // implementation of breadthFirstSearch for edmondsKarp algorithm to find the path from source to sink + bool Graph::_breadthFirstSearch() { - // Resetting the visited values + // resetting the visited values fill(this->_visited.begin(), this->_visited.end(), false); - // Resetting the parent values + // resetting the parent values fill(this->_parent.begin(), this->_parent.end(), -1); queue nodeQueue; @@ -184,12 +184,12 @@ namespace MaximumBipartiteMatching } } - // Returning the visited value of the sink vertex, initially it was set to false + // returning the visited value of the sink vertex, initially it was set to false return this->_visited[this->_sink]; } - // Graph Public Member Methods - void Graph::CreateGraph(int noOfVertices) + // Graph public member methods + void Graph::createGraph(int noOfVertices) { this->_noOfVertices = noOfVertices; this->_maximumFlow = 0; @@ -200,32 +200,32 @@ namespace MaximumBipartiteMatching this->_color = vector(this->_noOfVertices, WHITE); } - void Graph::PushDirectedEdge(int valueU, int valueV) + void Graph::pushDirectedEdge(int valueU, int valueV) { this->_adjMatrix[valueU][valueV] = 1; } - int Graph::FindMaximumBipartiteMatching() + int Graph::findMaximumBipartiteMatching() { - // Resolving all the parallel edges if present - this->ResolveAntiParallelEdges(); + // resolving all the parallel edges if present + this->_resolveAntiParallelEdges(); this->_residualGraph = this->_adjMatrix; - this->ColorGraph(); + this->_colorGraph(); this->_source = this->_noOfVertices; this->_noOfVertices++; this->_sink = this->_noOfVertices; this->_noOfVertices++; - this->AddAdditionalEdges(); + this->_addAdditionalEdges(); - // While there exists a path p from source to sink in the residual network G' - while (this->BreadthFirstSearch()) + // while there exists a path p from source to sink in the residual network G' + while (this->_breadthFirstSearch()) { int augmentedPathFlow = 1; - // No need to find the minimum amount of augmentedPathFlow as like standard EdmondsKarp algorithm + // no need to find the minimum amount of augmentedPathFlow as like standard edmondsKarp algorithm // as here capacity of each edges is 1 for (int nodeV = this->_sink; nodeV != this->_source; nodeV = this->_parent[nodeV]) { @@ -239,14 +239,14 @@ namespace MaximumBipartiteMatching return this->_maximumFlow; } - // This method is used for finding the matchings - vector> Graph::GetMatchings() + // this method is used for finding the matchings + vector> Graph::getMatchings() { for (int nodeU = 0; nodeU < this->_adjMatrix.size(); nodeU++) { for (int nodeV = 0; nodeV < this->_adjMatrix.size(); nodeV++) { - // Check if the nodeU and nodeV are not source or sink + // check if the nodeU and nodeV are not source or sink // and there is a flow of 1 unit from nodeU --> nodeV // which means nodeU --> nodeV is being used for the maximum flow (maximum matching) if ((nodeU != this->_source || nodeU != this->_sink || nodeV != this->_source || nodeV != this->_sink) diff --git a/src/0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabel.cc b/src/0003_graph/0018_maximum_flow_goldberg_generic_push_relabel.cc similarity index 56% rename from src/0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabel.cc rename to src/0003_graph/0018_maximum_flow_goldberg_generic_push_relabel.cc index 23f7923..69e61ce 100644 --- a/src/0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabel.cc +++ b/src/0003_graph/0018_maximum_flow_goldberg_generic_push_relabel.cc @@ -1,21 +1,21 @@ -#include <0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabel.h> +#include "0018_maximum_flow_goldberg_generic_push_relabel.h" #include using namespace std; -namespace MaximumFlowGoldbergGenericPushRelabel +namespace dsa::maximum_flow_goldberg_generic_push_relabel { - // Graph Private Member Methods + // Graph private member methods - // Initializes Pre-Flow in the given Flow Network - void Graph::InitializePreflow() + // initializes pre-flow in the given flow network + void Graph::_initializePreflow() { - // The height of source is set to highest possible height value + // the height of source is set to highest possible height value this->_height[this->_source] = this->_noOfVertices; - // Iterating over all the vertices + // iterating over all the vertices for (int i = 0; i < this->_noOfVertices; i++) { - // For the all the edges (source, v) + // for the all the edges (source, v) if (this->_residualGraph[this->_source][i] > 0) { // v.excessFlow = capacity(source, v) @@ -24,32 +24,32 @@ namespace MaximumFlowGoldbergGenericPushRelabel // source.excessFlow = source.excessFlow - capacity(source, v) this->_excessFlow[this->_source] = this->_excessFlow[this->_source] - this->_residualGraph[this->_source][i]; - // Adjusting the flow and reverse flow along source->v and v->source respectively + // adjusting the flow and reverse flow along source->v and v->source respectively this->_residualGraph[i][this->_source] = this->_residualGraph[this->_source][i]; this->_residualGraph[this->_source][i] = 0; } } } - // Checks if there is any vertex which has excess flow - bool Graph::CheckOverFlow() + // checks if there is any vertex which has excess flow + bool Graph::_checkOverFlow() { - // Iterating over all of the vertices + // iterating over all of the vertices for (int i = 0; i < this->_noOfVertices; i++) { - // Checks if the current vertex is not any special vertex like source, sink + // checks if the current vertex is not any special vertex like source, sink // and also if there is excess flow in the current vertex and it is already not present in the queue if (i!=this->_source && i!=this->_sink && this->_excessFlow[i] > 0 && this->_visited[i] == false) { - // Insert the current vertex into the queue + // insert the current vertex into the queue this->_nodeQueue.push(i); - // Mark it as visited, so until it leaves the queue it is not inserted again even if all the excess flow is neutralized + // mark it as visited, so until it leaves the queue it is not inserted again even if all the excess flow is neutralized this->_visited[i] = true; } } - // Checks if there is no vertex having excess flow then returns false + // checks if there is no vertex having excess flow then returns false if (this->_nodeQueue.empty()) { return false; @@ -58,16 +58,16 @@ namespace MaximumFlowGoldbergGenericPushRelabel return true; } - // Pushes the flow from nodeU to its neighbour vertices - bool Graph::Push(int nodeU) + // pushes the flow from nodeU to its neighbour vertices + bool Graph::_push(int nodeU) { int nodeV = -1; int minimumFlow = INT_MAX; - // Iterating over all the vertices + // iterating over all the vertices for (int i = 0; i < this->_noOfVertices; i++) { - // For G'.Adj[nodeU] select the vertex if edge (nodeU, i) is non-saturated and height[nodeU] == height[i] + 1 + // for G'.adj[nodeU] select the vertex if edge (nodeU, i) is non-saturated and height[nodeU] == height[i] + 1 if (this->_residualGraph[nodeU][i] > 0 && this->_height[nodeU] == this->_height[i] + 1) { nodeV = i; @@ -75,51 +75,51 @@ namespace MaximumFlowGoldbergGenericPushRelabel } } - // Checks if any neighbour vertex found having non-saturated edge + // checks if any neighbour vertex found having non-saturated edge if (nodeV != -1) { - // Calculate the flow amount to be added along the edge and excess flow subtracted from nodeU + // calculate the flow amount to be added along the edge and excess flow subtracted from nodeU minimumFlow = min(this->_residualGraph[nodeU][nodeV], this->_excessFlow[nodeU]); - // Adjust the flow and the reverse flow along (nodeU, nodeV) + // adjust the flow and the reverse flow along (nodeU, nodeV) this->_residualGraph[nodeU][nodeV] = this->_residualGraph[nodeU][nodeV] - minimumFlow; this->_residualGraph[nodeV][nodeU] = this->_residualGraph[nodeV][nodeU] + minimumFlow; - // Adjust the excess flows in nodeU and nodeV + // adjust the excess flows in nodeU and nodeV this->_excessFlow[nodeU] = this->_excessFlow[nodeU] - minimumFlow; this->_excessFlow[nodeV] = this->_excessFlow[nodeV] + minimumFlow; - // Return that the Push operation is successful + // return that the push operation is successful return true; } - // Return that the Push operation is not successful + // return that the push operation is not successful return false; } - // Relabels height of vertex nodeU when there are outgoing non-saturated edges available - void Graph::Relabel(int nodeU) + // relabels height of vertex nodeU when there are outgoing non-saturated edges available + void Graph::_relabel(int nodeU) { int minimumHeight = INT_MAX; - // Iterating over all the vertices + // iterating over all the vertices for (int nodeV = 0; nodeV < this->_noOfVertices; nodeV++) { - // For G'.Adj[nodeU] select for which nodeV, height[nodeU] <= height[nodeV] + // for G'.adj[nodeU] select for which nodeV, height[nodeU] <= height[nodeV] if (this->_residualGraph[nodeU][nodeV] > 0 && this->_height[nodeU] <= this->_height[nodeV]) { - // Get the minimum height among all these G'.Adj[nodeU] + // get the minimum height among all these G'.adj[nodeU] minimumHeight = min(minimumHeight, this->_height[nodeV]); } } - // Set height[nodeU] + // set height[nodeU] this->_height[nodeU] = minimumHeight + 1; } - // Graph Public Member Methods - void Graph::CreateGraph(int noOfVertices) + // Graph public member methods + void Graph::createGraph(int noOfVertices) { this->_noOfVertices = noOfVertices; this->_source = 0; @@ -131,42 +131,42 @@ namespace MaximumFlowGoldbergGenericPushRelabel this->_visited = vector(this->_noOfVertices, false); } - void Graph::PushDirectedEdge(int valueU, int valueV, int capacity) + void Graph::pushDirectedEdge(int valueU, int valueV, int capacity) { this->_adjMatrix[valueU][valueV] = capacity; } - int Graph::FindMaximumFlowGoldbergGenericPushRelabel() + int Graph::findMaximumFlowGoldbergGenericPushRelabel() { this->_residualGraph = this->_adjMatrix; - // Initialize Pre-flow - this->InitializePreflow(); + // initialize pre-flow + this->_initializePreflow(); - // Checks if there is some vertices which have excess flow - while (this->CheckOverFlow()) + // checks if there is some vertices which have excess flow + while (this->_checkOverFlow()) { - // Get the vertex + // get the vertex int nodeU = this->_nodeQueue.front(); - // Checks if the Push operation is successful - if (this->Push(nodeU)) + // checks if the push operation is successful + if (this->_push(nodeU)) { - // Then remove the vertex from queue and set visited[nodeU] = true - // so that on next CheckOverFlow() method call this vertex can be discovered if it still has some excess flow + // then remove the vertex from queue and set visited[nodeU] = true + // so that on next checkOverFlow() method call this vertex can be discovered if it still has some excess flow this->_nodeQueue.pop(); this->_visited[nodeU] = false; } - // If the Push operation is not successful + // if the push operation is not successful else { - // Then Relabel nodeU without removing it from the queue - this->Relabel(nodeU); + // then relabel nodeU without removing it from the queue + this->_relabel(nodeU); } } - // Return the excess flow in the sink vertex which is actually the maximum flow along the given flow network + // return the excess flow in the sink vertex which is actually the maximum flow along the given flow network return this->_excessFlow[this->_sink]; } } \ No newline at end of file diff --git a/src/0003_Graph/0019_MaximumFlowRelabelToFront.cc b/src/0003_graph/0019_maximum_flow_relabel_to_front.cc similarity index 56% rename from src/0003_Graph/0019_MaximumFlowRelabelToFront.cc rename to src/0003_graph/0019_maximum_flow_relabel_to_front.cc index d50176d..034e6ca 100644 --- a/src/0003_Graph/0019_MaximumFlowRelabelToFront.cc +++ b/src/0003_graph/0019_maximum_flow_relabel_to_front.cc @@ -1,22 +1,22 @@ -#include <0003_Graph/0019_MaximumFlowRelabelToFront.h> +#include "0019_maximum_flow_relabel_to_front.h" #include #include using namespace std; -namespace MaximumFlowRelabelToFront +namespace dsa::maximum_flow_relabel_to_front { - // Graph Private Member Methods + // Graph private member methods - // Initializes Pre-Flow in the given Flow Network - void Graph::InitializePreflow() + // initializes pre-flow in the given flow network + void Graph::_initializePreflow() { - // The height of source is set to highest possible height value + // the height of source is set to highest possible height value this->_height[this->_source] = this->_noOfVertices; - // Iterating over all the vertices + // iterating over all the vertices for (int i = 0; i < this->_noOfVertices; i++) { - // For the all the edges (source, v) + // for the all the edges (source, v) if (this->_residualGraph[this->_source][i] > 0) { // v.excessFlow = capacity(source, v) @@ -25,89 +25,89 @@ namespace MaximumFlowRelabelToFront // source.excessFlow = source.excessFlow - capacity(source, v) this->_excessFlow[this->_source] = this->_excessFlow[this->_source] - this->_residualGraph[this->_source][i]; - // Adjusting the flow and reverse flow along source->v and v->source respectively + // adjusting the flow and reverse flow along source->v and v->source respectively this->_residualGraph[i][this->_source] = this->_residualGraph[this->_source][i]; this->_residualGraph[this->_source][i] = 0; } } } - // Discharges the excess flow from nodeU - void Graph::Discharge(int nodeU) + // discharges the excess flow from nodeU + void Graph::_discharge(int nodeU) { - // Check if excess flow of nodeU is > 0 + // check if excess flow of nodeU is > 0 while (this->_excessFlow[nodeU] > 0) { - // Falg to check if any amount of excess flow is pushed to any neighbour vertex + // falg to check if any amount of excess flow is pushed to any neighbour vertex bool hasPushed = false; - // Iterating over all of the vertices + // iterating over all of the vertices for (int nodeV = 0; nodeV < this->_noOfVertices; nodeV++) { - // For G'.Adj[nodeU] check if edge (nodeU, nodeV) is admissible + // for G'.adj[nodeU] check if edge (nodeU, nodeV) is admissible if (this->_residualGraph[nodeU][nodeV] > 0 && this->_height[nodeU] == 1 + this->_height[nodeV]) { - // Push excess flow along the admissible edge (nodeU, nodeV) - this->Push(nodeU, nodeV); - // Set the hasPushed flag to true + // push excess flow along the admissible edge (nodeU, nodeV) + this->_push(nodeU, nodeV); + // set the hasPushed flag to true hasPushed = true; - // Check if there is no excess flow left in nodeU then no need to check any more admissible edge going from nodeU + // check if there is no excess flow left in nodeU then no need to check any more admissible edge going from nodeU if (this->_excessFlow[nodeU] == 0) { - // Then break from iterating over G'.Adj[nodeU] + // then break from iterating over G'.adj[nodeU] break; } } } - // Check if Push operation is not done yet + // check if push operation is not done yet if (!hasPushed) { - // Then it indicates that all the outgoing edges from nodeU are inadmissible - // so perform the Relabel operation on nodeU - this->Relabel(nodeU); + // then it indicates that all the outgoing edges from nodeU are inadmissible + // so perform the relabel operation on nodeU + this->_relabel(nodeU); } } } - // Pushes the flow from nodeU to its neighbour vertices - void Graph::Push(int nodeU, int nodeV) + // pushes the flow from nodeU to its neighbour vertices + void Graph::_push(int nodeU, int nodeV) { - // Calculate the flow amount to be added along the edge and excess flow subtracted from nodeU + // calculate the flow amount to be added along the edge and excess flow subtracted from nodeU int minimumFlow = min(this->_residualGraph[nodeU][nodeV], this->_excessFlow[nodeU]); - // Adjust the flow and the reverse flow along (nodeU, nodeV) + // adjust the flow and the reverse flow along (nodeU, nodeV) this->_residualGraph[nodeU][nodeV] = this->_residualGraph[nodeU][nodeV] - minimumFlow; this->_residualGraph[nodeV][nodeU] = this->_residualGraph[nodeV][nodeU] + minimumFlow; - // Adjust the excess flows in nodeU and nodeV + // adjust the excess flows in nodeU and nodeV this->_excessFlow[nodeU] = this->_excessFlow[nodeU] - minimumFlow; this->_excessFlow[nodeV] = this->_excessFlow[nodeV] + minimumFlow; } - // Relabels height of vertex nodeU when there are outgoing non-saturated edges available - void Graph::Relabel(int nodeU) + // relabels height of vertex nodeU when there are outgoing non-saturated edges available + void Graph::_relabel(int nodeU) { int minimumHeight = INT_MAX; - // Iterating over all the vertices + // iterating over all the vertices for (int nodeV = 0; nodeV < this->_noOfVertices; nodeV++) { - // For G'.Adj[nodeU] select for which nodeV, height[nodeU] <= height[nodeV] + // for G'.adj[nodeU] select for which nodeV, height[nodeU] <= height[nodeV] if (this->_residualGraph[nodeU][nodeV] > 0 && this->_height[nodeU] <= this->_height[nodeV]) { - // Get the minimum height among all these G'.Adj[nodeU] + // get the minimum height among all these G'.adj[nodeU] minimumHeight = min(minimumHeight, this->_height[nodeV]); } } - // Set height[nodeU] + // set height[nodeU] this->_height[nodeU] = minimumHeight + 1; } - // Graph Public Member Methods - void Graph::CreateGraph(int noOfVertices) + // Graph public member methods + void Graph::createGraph(int noOfVertices) { this->_noOfVertices = noOfVertices; this->_source = 0; @@ -119,19 +119,19 @@ namespace MaximumFlowRelabelToFront this->_visited = vector(this->_noOfVertices, false); } - void Graph::PushDirectedEdge(int valueU, int valueV, int capacity) + void Graph::pushDirectedEdge(int valueU, int valueV, int capacity) { this->_adjMatrix[valueU][valueV] = capacity; } - int Graph::FindMaximumFlowRelabelToFront() + int Graph::findMaximumFlowRelabelToFront() { this->_residualGraph = this->_adjMatrix; - // Initialize Pre-flow - this->InitializePreflow(); + // initialize pre-flow + this->_initializePreflow(); - // Make the list L = G.V - {source, sink} + // make the list L = G.V - {source, sink} for (int i = 0; i < this->_noOfVertices; i++) { if (i != this->_source && i != this->_sink) @@ -140,30 +140,30 @@ namespace MaximumFlowRelabelToFront } } - // Set current vertex = L.head + // set current vertex = L.head list::iterator nodeUiterator = this->_nodeList.begin(); - // Iterate over all of the elements in the list L + // iterate over all of the elements in the list L while (nodeUiterator != this->_nodeList.end()) { - // Get the height of current vertex + // get the height of current vertex int oldHeight = this->_height[*nodeUiterator]; - // Discharge the excess flow of current vertex - this->Discharge(*nodeUiterator); + // discharge the excess flow of current vertex + this->_discharge(*nodeUiterator); - // Check if the height of current vertex increases which means the current vertex got relabeled + // check if the height of current vertex increases which means the current vertex got relabeled if (this->_height[*nodeUiterator] > oldHeight) { - // Then move current vertex to the front of the list L + // then move current vertex to the front of the list L this->_nodeList.splice(this->_nodeList.begin(), this->_nodeList, nodeUiterator); } - // Go to the next vertex of current vertex in L + // go to the next vertex of current vertex in L nodeUiterator++; } - // Return the excess flow in the sink vertex which is actually the maximum flow along the given flow network + // return the excess flow in the sink vertex which is actually the maximum flow along the given flow network return this->_excessFlow[this->_sink]; } } \ No newline at end of file diff --git a/src/0003_graph/CMakeLists.txt b/src/0003_graph/CMakeLists.txt new file mode 100644 index 0000000..3e98596 --- /dev/null +++ b/src/0003_graph/CMakeLists.txt @@ -0,0 +1,30 @@ +# Specify the source files +set(0003GRAPH_SOURCES + 0001_breadth_first_search.cc + 0002_depth_first_search.cc + 0003_topological_sort.cc + 0004_strongly_connected_components.cc + 0005_hamiltonian_path_and_cycle.cc + 0006_eulerian_path_and_circuit.cc + 0007_minimum_spanning_tree_kruskal_algorithm.cc + 0008_minimum_spanning_tree_prim_algorithm.cc + 0009_single_source_shortest_path_bellman_ford.cc + 0010_directed_acyclic_graph_shortest_path.cc + 0011_single_source_shortest_path_dijkstra.cc + 0012_difference_constraints_shortest_paths.cc + 0013_all_pairs_shortest_paths_floyd_warshall.cc + 0014_all_pairs_shortest_paths_johnson.cc + 0015_maximum_flow_ford_fulkerson.cc + 0016_maximum_flow_edmonds_karp.cc + 0017_maximum_bipartite_matching.cc + 0018_maximum_flow_goldberg_generic_push_relabel.cc + 0019_maximum_flow_relabel_to_front.cc + +) + +# Create a library target +add_library(0003_Graph ${0003GRAPH_SOURCES}) + +target_include_directories(0003_Graph PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/headers +) \ No newline at end of file diff --git a/include/0003_Graph/0001_BreadthFirstSearch.h b/src/0003_graph/headers/0001_breadth_first_search.h similarity index 63% rename from include/0003_Graph/0001_BreadthFirstSearch.h rename to src/0003_graph/headers/0001_breadth_first_search.h index ba7aec8..1388ed6 100644 --- a/include/0003_Graph/0001_BreadthFirstSearch.h +++ b/src/0003_graph/headers/0001_breadth_first_search.h @@ -7,7 +7,7 @@ #include using namespace std; -namespace BreadthFirstSearch +namespace dsa::breadth_first_search { enum color { WHITE, GRAY, BLACK }; class Node @@ -25,11 +25,11 @@ namespace BreadthFirstSearch private: map> _adjlist; map _nodeMap; - Node* MakeOrFindNode(int value); - void BreadthFirstSearch(Node* node); + Node* _makeOrFindNode(int value); + void _breadthFirstSearch(Node* node); public: - void PushUndirectedEdge(int valueU, int valueV); - void BFS(int value); - vector> ShowBFSResult(); + void pushUndirectedEdge(int valueU, int valueV); + void bfs(int value); + vector> showBFSResult(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0002_DepthFirstSearch.h b/src/0003_graph/headers/0002_depth_first_search.h similarity index 65% rename from include/0003_Graph/0002_DepthFirstSearch.h rename to src/0003_graph/headers/0002_depth_first_search.h index e376295..79612f2 100644 --- a/include/0003_Graph/0002_DepthFirstSearch.h +++ b/src/0003_graph/headers/0002_depth_first_search.h @@ -6,7 +6,7 @@ #include using namespace std; -namespace DepthFirstSearch +namespace dsa::depth_first_search { enum color { WHITE, GRAY, BLACK }; @@ -27,11 +27,11 @@ namespace DepthFirstSearch int _time; map> _adjlist; map _nodeMap; - Node* MakeOrFindNode(int value); - void DepthFirstSearch(Node* Node); + Node* _makeOrFindNode(int value); + void _depthFirstSearch(Node* Node); public: - void PushDirectedEdge(int valueU, int valueV); - void DFS(); - vector>> ShowDFSResult(); + void pushDirectedEdge(int valueU, int valueV); + void dfs(); + vector>> showDFSResult(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0003_TopologicalSort.h b/src/0003_graph/headers/0003_topological_sort.h similarity index 62% rename from include/0003_Graph/0003_TopologicalSort.h rename to src/0003_graph/headers/0003_topological_sort.h index 441d7d1..7b34cd8 100644 --- a/include/0003_Graph/0003_TopologicalSort.h +++ b/src/0003_graph/headers/0003_topological_sort.h @@ -6,7 +6,7 @@ #include using namespace std; -namespace TopologicalSort +namespace dsa::topological_sort { enum color { WHITE, GRAY, BLACK }; @@ -30,13 +30,13 @@ namespace TopologicalSort map> _adjlist; map _nodeMap; list _topologicalSortedNodeList; - Node* MakeOrFindNode(int value); - void DepthFirstSearch(Node* DFSNode); + Node* _makeOrFindNode(int value); + void _depthFirstSearch(Node* dFSNode); public: - void PushDirectedEdge(int valueU, int valueV); - void PushSingleNode(int valueU); - void TopologicalSort(); - void KahnTopologicalSort(); - vector>> ShowTopologicalSortResult(); + void pushDirectedEdge(int valueU, int valueV); + void pushSingleNode(int valueU); + void topologicalSort(); + void kahnTopologicalSort(); + vector>> showTopologicalSortResult(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0004_StronglyConnectedComponents.h b/src/0003_graph/headers/0004_strongly_connected_components.h similarity index 58% rename from include/0003_Graph/0004_StronglyConnectedComponents.h rename to src/0003_graph/headers/0004_strongly_connected_components.h index 0e37f60..266fce5 100644 --- a/include/0003_Graph/0004_StronglyConnectedComponents.h +++ b/src/0003_graph/headers/0004_strongly_connected_components.h @@ -6,7 +6,7 @@ #include using namespace std; -namespace StronglyConnectedComponents +namespace dsa::strongly_connected_components { enum color { WHITE, GRAY, BLACK }; @@ -30,14 +30,14 @@ namespace StronglyConnectedComponents map _nodeMap; list _nodesFinishingTimeOrder; vector> _allConnectedComponents; - Node* MakeOrFindNode(int value); - void DepthFirstSearchOnGraphG(Node* DFSNode); - void DepthFirstSearchOnGraphT(Node* DFSNode, vector& connectedComponents); + Node* _makeOrFindNode(int value); + void _depthFirstSearchOnGraphG(Node* dFSNode); + void _depthFirstSearchOnGraphT(Node* dFSNode, vector& connectedComponents); public: - void PushDirectedEdge(int valueU, int valueV); - void PushSingleNode(int valueU); - void DFSOnGraphG(); - void DFSOnGraphT(); - vector> FindAllStronglyConnectedComponents(); + void pushDirectedEdge(int valueU, int valueV); + void pushSingleNode(int valueU); + void dFSOnGraphG(); + void dFSOnGraphT(); + vector> findAllStronglyConnectedComponents(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0005_HamiltonianPathAndCycle.h b/src/0003_graph/headers/0005_hamiltonian_path_and_cycle.h similarity index 52% rename from include/0003_Graph/0005_HamiltonianPathAndCycle.h rename to src/0003_graph/headers/0005_hamiltonian_path_and_cycle.h index 7ccca6a..d29af50 100644 --- a/include/0003_Graph/0005_HamiltonianPathAndCycle.h +++ b/src/0003_graph/headers/0005_hamiltonian_path_and_cycle.h @@ -5,7 +5,7 @@ #include using namespace std; -namespace HamiltonianPathAndCycle +namespace dsa::hamiltonian_path_and_cycle { class Node { @@ -25,16 +25,16 @@ namespace HamiltonianPathAndCycle map> _adjlist; map _nodeMap; vector _hamiltonianPath; - Node* MakeOrFindNode(int value); - bool IsSafe(Node* nodeU, Node* nodeV); - bool HamiltonianCycleAndPathUtil(Node* node); + Node* _makeOrFindNode(int value); + bool _isSafe(Node* nodeU, Node* nodeV); + bool _hamiltonianCycleAndPathUtil(Node* node); public: - void PushUndirectedEdge(int valueU, int valueV); - void PushSingleNode(int valueU); - void FindHamiltonianCycleAndPath(); - bool IsHamiltonianCyclePresent(); - bool IsHamiltonianPathPresent(); - vector GetHamiltonianPath(); + void pushUndirectedEdge(int valueU, int valueV); + void pushSingleNode(int valueU); + void findHamiltonianCycleAndPath(); + bool isHamiltonianCyclePresent(); + bool isHamiltonianPathPresent(); + vector getHamiltonianPath(); }; } \ No newline at end of file diff --git a/src/0003_graph/headers/0006_eulerian_path_and_circuit.h b/src/0003_graph/headers/0006_eulerian_path_and_circuit.h new file mode 100644 index 0000000..09fd175 --- /dev/null +++ b/src/0003_graph/headers/0006_eulerian_path_and_circuit.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include +using namespace std; + +namespace dsa::eulerian_path_and_circuit +{ + class Node + { + public: + int data; + int degree; + int inDegree; + int outDegree; + bool visited; + Node(int value); + }; + + class Graph + { + private: + bool _isEulerianPathPresent; + bool _isEulerianCircuitPresent; + map> _adjlist; + map _nodeMap; + vector _eulerianPath; + Node* _makeOrFindNode(int value); + void _depthFirstSearch(Node* node); + bool _isConnected(); + void _eulerianPathHierholzerAlgorithm(Node* startingNode); + + public: + void pushUndirectedEdge(int valueU, int valueV); + void pushDirectedEdge(int valueU, int valueV); + void pushSingleNode(int valueU); + void findEulerianPathAndCircuit(); + bool isEulerianPathPresent(); + bool isEulerianCircuitPresent(); + vector undirectedGraphGetEulerianPath(); + }; +} \ No newline at end of file diff --git a/include/0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithm.h b/src/0003_graph/headers/0007_minimum_spanning_tree_kruskal_algorithm.h similarity index 54% rename from include/0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithm.h rename to src/0003_graph/headers/0007_minimum_spanning_tree_kruskal_algorithm.h index 8ca704c..52ec487 100644 --- a/include/0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithm.h +++ b/src/0003_graph/headers/0007_minimum_spanning_tree_kruskal_algorithm.h @@ -5,7 +5,7 @@ #include using namespace std; -namespace MinimumSpanningTreeKruskalAlgorithm +namespace dsa::minimum_spanning_tree_kruskal_algorithm { class Node { @@ -32,15 +32,15 @@ namespace MinimumSpanningTreeKruskalAlgorithm map _nodeMap; vector _edgeList; vector, int>> _minimumSpanningTree; - Node* MakeOrFindNode(int data); - void MakeSet(Node* node); - void Union(Node* nodeU, Node* nodeV); - void Link(Node* nodeU, Node* nodeV); - Node* FindSet(Node* node); + Node* _makeOrFindNode(int data); + void _makeSet(Node* node); + void _unionSet(Node* nodeU, Node* nodeV); + void _linkSet(Node* nodeU, Node* nodeV); + Node* _findSet(Node* node); public: - void PushUndirectedEdge(int valueU, int valueV, int weight); - void FindMinimumSpanningTreeKruskalAlgorithm(); - vector, int>> GetMinimumSpanningTree(); + void pushUndirectedEdge(int valueU, int valueV, int weight); + void findMinimumSpanningTreeKruskalAlgorithm(); + vector, int>> getMinimumSpanningTree(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.h b/src/0003_graph/headers/0008_minimum_spanning_tree_prim_algorithm.h similarity index 68% rename from include/0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.h rename to src/0003_graph/headers/0008_minimum_spanning_tree_prim_algorithm.h index ffe7c08..79a193f 100644 --- a/include/0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.h +++ b/src/0003_graph/headers/0008_minimum_spanning_tree_prim_algorithm.h @@ -5,7 +5,7 @@ #include using namespace std; -namespace MinimumSpanningTreePrimAlgorithm +namespace dsa::minimum_spanning_tree_prim_algorithm { class Node { @@ -33,10 +33,10 @@ namespace MinimumSpanningTreePrimAlgorithm map _nodeMap; vector, int>> _minimumSpanningTree; multiset _operationalSet; - Node* MakeOrFindNode(int data); + Node* _makeOrFindNode(int data); public: - void PushUndirectedEdge(int valueU, int valueV, int weight); - void FindMinimumSpanningTreePrimAlgorithm(); - vector, int>> GetMinimumSpanningTree(); + void pushUndirectedEdge(int valueU, int valueV, int weight); + void findMinimumSpanningTreePrimAlgorithm(); + vector, int>> getMinimumSpanningTree(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0009_SingleSourceShortestPathBellmanFord.h b/src/0003_graph/headers/0009_single_source_shortest_path_bellman_ford.h similarity index 51% rename from include/0003_Graph/0009_SingleSourceShortestPathBellmanFord.h rename to src/0003_graph/headers/0009_single_source_shortest_path_bellman_ford.h index e51ca10..618f3da 100644 --- a/include/0003_Graph/0009_SingleSourceShortestPathBellmanFord.h +++ b/src/0003_graph/headers/0009_single_source_shortest_path_bellman_ford.h @@ -4,7 +4,7 @@ #include using namespace std; -namespace SingleSourceShortestPathBellmanFord +namespace dsa::single_source_shortest_path_bellman_ford { class Node { @@ -30,15 +30,15 @@ namespace SingleSourceShortestPathBellmanFord map> _adjlist; map _nodeMap; vector _edgeList; - Node* MakeOrFindNode(int data); - void InitializeSingleSource(Node* sourceNode); - void Relax(Edge* edge); - void GetShortestPath(Node* node, vector& path); + Node* _makeOrFindNode(int data); + void _initializeSingleSource(Node* sourceNode); + void _relax(Edge* edge); + void _getShortestPath(Node* node, vector& path); public: - void PushDirectedEdge(int valueU, int valueV, int weight); - bool FindSingleSourceShortestPathBellmanFord(int data); - vector GetShortestPathBellmanFord(int data); + void pushDirectedEdge(int valueU, int valueV, int weight); + bool findSingleSourceShortestPathBellmanFord(int data); + vector getShortestPathBellmanFord(int data); }; } \ No newline at end of file diff --git a/include/0003_Graph/0010_DirectedAcyclicGraphShortestPath.h b/src/0003_graph/headers/0010_directed_acyclic_graph_shortest_path.h similarity index 55% rename from include/0003_Graph/0010_DirectedAcyclicGraphShortestPath.h rename to src/0003_graph/headers/0010_directed_acyclic_graph_shortest_path.h index 8826ebc..e641b55 100644 --- a/include/0003_Graph/0010_DirectedAcyclicGraphShortestPath.h +++ b/src/0003_graph/headers/0010_directed_acyclic_graph_shortest_path.h @@ -5,7 +5,7 @@ #include using namespace std; -namespace DirectedAcyclicGraphShortestPath +namespace dsa::directed_acyclic_graph_shortest_path { enum color {WHITE, GRAY, BLACK}; @@ -35,17 +35,17 @@ namespace DirectedAcyclicGraphShortestPath map _nodeMap; map> _edgeMap; list _topologicalSortedNodeList; - Node* MakeOrFindNode(int data); - void DepthFirstSearch(Node* node); - void TopologicalSort(); - void InitializeSingleSource(Node* sourceNode); - void Relax(Edge* edge); - void GetShortestPath(Node* node, vector& path); + Node* _makeOrFindNode(int data); + void _depthFirstSearch(Node* node); + void _topologicalSort(); + void _initializeSingleSource(Node* sourceNode); + void _relax(Edge* edge); + void _getShortestPath(Node* node, vector& path); public: - void PushDirectedEdge(int valueU, int valueV, int weight); - void FindDAGShortestPath(int data); - vector GetDAGShortestPath(int data); + void pushDirectedEdge(int valueU, int valueV, int weight); + void findDAGShortestPath(int data); + vector getDAGShortestPath(int data); }; } \ No newline at end of file diff --git a/include/0003_Graph/0011_SingleSourceShortestPathDijkstra.h b/src/0003_graph/headers/0011_single_source_shortest_path_dijkstra.h similarity index 61% rename from include/0003_Graph/0011_SingleSourceShortestPathDijkstra.h rename to src/0003_graph/headers/0011_single_source_shortest_path_dijkstra.h index 8911ac8..7bb439a 100644 --- a/include/0003_Graph/0011_SingleSourceShortestPathDijkstra.h +++ b/src/0003_graph/headers/0011_single_source_shortest_path_dijkstra.h @@ -5,7 +5,7 @@ #include using namespace std; -namespace SingleSourceShortestPathDijkstra +namespace dsa::single_source_shortest_path_dijkstra { class Node { @@ -41,15 +41,15 @@ namespace SingleSourceShortestPathDijkstra map _nodeMap; map> _edgeMap; multiset _operationalSet; - Node* MakeOrFindNode(int data); - void InitializeSingleSource(Node* sourceNode); - void Relax(Edge* edge); - void Dijkstra(Node* source); - void GetShortestPath(Node* node, vector& path); + Node* _makeOrFindNode(int data); + void _initializeSingleSource(Node* sourceNode); + void _relax(Edge* edge); + void _dijkstra(Node* source); + void _getShortestPath(Node* node, vector& path); public: - void PushDirectedEdge(int valueU, int valueV, int weight); - void FindShortestPathDijkstra(int data); - vector GetDijkstraShortestPath(int data); + void pushDirectedEdge(int valueU, int valueV, int weight); + void findShortestPathDijkstra(int data); + vector getDijkstraShortestPath(int data); }; } \ No newline at end of file diff --git a/include/0003_Graph/0012_DifferenceConstraintsShortestPaths.h b/src/0003_graph/headers/0012_difference_constraints_shortest_paths.h similarity index 52% rename from include/0003_Graph/0012_DifferenceConstraintsShortestPaths.h rename to src/0003_graph/headers/0012_difference_constraints_shortest_paths.h index 02d1426..265b9f4 100644 --- a/include/0003_Graph/0012_DifferenceConstraintsShortestPaths.h +++ b/src/0003_graph/headers/0012_difference_constraints_shortest_paths.h @@ -5,7 +5,7 @@ #include using namespace std; -namespace DifferenceConstraintsShortestPaths +namespace dsa::difference_constraints_shortest_paths { class Node { @@ -30,14 +30,14 @@ namespace DifferenceConstraintsShortestPaths map> _adjlist; map _nodeMap; vector _edgeList; - Node* MakeOrFindNode(string data); - void PushDirectedEdge(string valueU, string valueV, int weight); - void InitializeSingleSource(Node* sourceNode); - void Relax(Edge* edge); + Node* _makeOrFindNode(string data); + void _pushDirectedEdge(string valueU, string valueV, int weight); + void _initializeSingleSource(Node* sourceNode); + void _relax(Edge* edge); public: - void PushAllDirectedEdges(vector> vectorA, vector vectorX, vector vectorB); - bool FindDifferenceConstraintsSolutionBellmanFord(); - vector> GetDifferenceConstrtaintsSolution(); + void pushAllDirectedEdges(vector> vectorA, vector vectorX, vector vectorB); + bool findDifferenceConstraintsSolutionBellmanFord(); + vector> getDifferenceConstrtaintsSolution(); }; } \ No newline at end of file diff --git a/src/0003_graph/headers/0013_all_pairs_shortest_paths_floyd_warshall.h b/src/0003_graph/headers/0013_all_pairs_shortest_paths_floyd_warshall.h new file mode 100644 index 0000000..2185604 --- /dev/null +++ b/src/0003_graph/headers/0013_all_pairs_shortest_paths_floyd_warshall.h @@ -0,0 +1,24 @@ +#pragma once + +#include +using namespace std; + +namespace dsa::all_pairs_shortest_paths_floyd_warshall +{ + class Graph + { + private: + int _noOfVertices; + vector> _adjMatrix; + vector> _shortestPathMatrixFloydWarshall; + vector> _predecessorMatrix; + void _initializeDistanceAndPredecessors(); + void _getShortestPath(int source, int destination, vector& path); + + public: + void createGraph(int noOfVertices); + void pushDirectedEdge(int valueU, int valueV, int weight); + void findAllPairsShortestPathsFloydWarshallSolution(); + vector> getFloydWarshallShortestPath(); + }; +} \ No newline at end of file diff --git a/include/0003_Graph/0014_AllPairsShortestPathsJohnson.h b/src/0003_graph/headers/0014_all_pairs_shortest_paths_johnson.h similarity index 57% rename from include/0003_Graph/0014_AllPairsShortestPathsJohnson.h rename to src/0003_graph/headers/0014_all_pairs_shortest_paths_johnson.h index 925e89e..22e48c4 100644 --- a/include/0003_Graph/0014_AllPairsShortestPathsJohnson.h +++ b/src/0003_graph/headers/0014_all_pairs_shortest_paths_johnson.h @@ -5,7 +5,7 @@ #include using namespace std; -namespace AllPairsShortestPathsJohnson +namespace dsa::all_pairs_shortest_paths_johnson { class Node { @@ -48,19 +48,19 @@ namespace AllPairsShortestPathsJohnson multiset _operationalSet; vector> _shortestPathMatrix; vector> _predecessorMatrix; - Node* MakeOrFindNode(int data); - void PushAugmentedDirectedEdges(Node* sourceNode, Node* nodeV, int weight); - void InitializeSingleSource(Node* sourceNode); - void RelaxBellmanFord(Edge* edge); - bool BellmanFord(Node* source); - void RelaxDijkstra(Edge* edge); - void Dijkstra(Node* source); - void GetShortestPath(int source, int destination, vector& path); + Node* _makeOrFindNode(int data); + void _pushAugmentedDirectedEdges(Node* sourceNode, Node* nodeV, int weight); + void _initializeSingleSource(Node* sourceNode); + void _relaxBellmanFord(Edge* edge); + bool _bellmanFord(Node* source); + void _relaxDijkstra(Edge* edge); + void _dijkstra(Node* source); + void _getShortestPath(int source, int destination, vector& path); public: - void PushDirectedEdge(int dataU, int dataV, int weight); - bool FindAllPairsShortestPathsJohnsonAlgorithm(); - vector> GetAllPairsShortestPathsDistanceMatrix(); - vector> GetAllPairsShortestPathsPathMatrix(); + void pushDirectedEdge(int dataU, int dataV, int weight); + bool findAllPairsShortestPathsJohnsonAlgorithm(); + vector> getAllPairsShortestPathsDistanceMatrix(); + vector> getAllPairsShortestPathsPathMatrix(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0015_MaximumFlowFordFulkerson.h b/src/0003_graph/headers/0015_maximum_flow_ford_fulkerson.h similarity index 53% rename from include/0003_Graph/0015_MaximumFlowFordFulkerson.h rename to src/0003_graph/headers/0015_maximum_flow_ford_fulkerson.h index 429b247..a3ff467 100644 --- a/include/0003_Graph/0015_MaximumFlowFordFulkerson.h +++ b/src/0003_graph/headers/0015_maximum_flow_ford_fulkerson.h @@ -4,7 +4,7 @@ #include using namespace std; -namespace MaximumFlowFordFulkerson +namespace dsa::maximum_flow_ford_fulkerson { class Graph { @@ -18,12 +18,12 @@ namespace MaximumFlowFordFulkerson vector> _residualGraph; vector _parent; vector _visited; - void ResolveAntiParallelEdges(); - void DepthFirstSearchVisit(int nodeU); - bool DepthFirstSearch(); + void _resolveAntiParallelEdges(); + void _depthFirstSearchVisit(int nodeU); + bool _depthFirstSearch(); public: - void CreateGraph(int noOfVertices); - void PushDirectedEdge(int valueU, int valueV, int capacity); - int FindMaximumFlowFordFulkerson(); + void createGraph(int noOfVertices); + void pushDirectedEdge(int valueU, int valueV, int capacity); + int findMaximumFlowFordFulkerson(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0016_MaximumFlowEdmondsKarp.h b/src/0003_graph/headers/0016_maximum_flow_edmonds_karp.h similarity index 57% rename from include/0003_Graph/0016_MaximumFlowEdmondsKarp.h rename to src/0003_graph/headers/0016_maximum_flow_edmonds_karp.h index 25c72f1..799bc15 100644 --- a/include/0003_Graph/0016_MaximumFlowEdmondsKarp.h +++ b/src/0003_graph/headers/0016_maximum_flow_edmonds_karp.h @@ -4,7 +4,7 @@ #include using namespace std; -namespace MaximumFlowEdmondsKarp +namespace dsa::maximum_flow_edmonds_karp { class Graph { @@ -18,11 +18,11 @@ namespace MaximumFlowEdmondsKarp vector> _residualGraph; vector _parent; vector _visited; - void ResolveAntiParallelEdges(); - bool BreadthFirstSearch(); + void _resolveAntiParallelEdges(); + bool _breadthFirstSearch(); public: - void CreateGraph(int noOfVertices); - void PushDirectedEdge(int valueU, int valueV, int capacity); - int FindMaximumFlowEdmondsKarp(); + void createGraph(int noOfVertices); + void pushDirectedEdge(int valueU, int valueV, int capacity); + int findMaximumFlowEdmondsKarp(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0017_MaximumBipartiteMatching.h b/src/0003_graph/headers/0017_maximum_bipartite_matching.h similarity index 57% rename from include/0003_Graph/0017_MaximumBipartiteMatching.h rename to src/0003_graph/headers/0017_maximum_bipartite_matching.h index 741c3c0..12d9a6a 100644 --- a/include/0003_Graph/0017_MaximumBipartiteMatching.h +++ b/src/0003_graph/headers/0017_maximum_bipartite_matching.h @@ -4,9 +4,9 @@ #include using namespace std; -namespace MaximumBipartiteMatching +namespace dsa::maximum_bipartite_matching { - enum Color + enum color { WHITE = -1, RED = 0, @@ -28,14 +28,14 @@ namespace MaximumBipartiteMatching vector _visited; vector _color; vector> _matchings; - void ResolveAntiParallelEdges(); - void ColorGraph(); - void AddAdditionalEdges(); - bool BreadthFirstSearch(); + void _resolveAntiParallelEdges(); + void _colorGraph(); + void _addAdditionalEdges(); + bool _breadthFirstSearch(); public: - void CreateGraph(int noOfVertices); - void PushDirectedEdge(int valueU, int valueV); - int FindMaximumBipartiteMatching(); - vector> GetMatchings(); + void createGraph(int noOfVertices); + void pushDirectedEdge(int valueU, int valueV); + int findMaximumBipartiteMatching(); + vector> getMatchings(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabel.h b/src/0003_graph/headers/0018_maximum_flow_goldberg_generic_push_relabel.h similarity index 52% rename from include/0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabel.h rename to src/0003_graph/headers/0018_maximum_flow_goldberg_generic_push_relabel.h index fb13a01..34b7dae 100644 --- a/include/0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabel.h +++ b/src/0003_graph/headers/0018_maximum_flow_goldberg_generic_push_relabel.h @@ -4,7 +4,7 @@ #include using namespace std; -namespace MaximumFlowGoldbergGenericPushRelabel +namespace dsa::maximum_flow_goldberg_generic_push_relabel { class Graph { @@ -19,13 +19,13 @@ namespace MaximumFlowGoldbergGenericPushRelabel vector _height; vector _visited; queue _nodeQueue; - void InitializePreflow(); - bool CheckOverFlow(); - bool Push(int nodeU); - void Relabel(int nodeU); + void _initializePreflow(); + bool _checkOverFlow(); + bool _push(int nodeU); + void _relabel(int nodeU); public: - void CreateGraph(int noOfVertices); - void PushDirectedEdge(int valueU, int valueV, int capacity); - int FindMaximumFlowGoldbergGenericPushRelabel(); + void createGraph(int noOfVertices); + void pushDirectedEdge(int valueU, int valueV, int capacity); + int findMaximumFlowGoldbergGenericPushRelabel(); }; } \ No newline at end of file diff --git a/include/0003_Graph/0019_MaximumFlowRelabelToFront.h b/src/0003_graph/headers/0019_maximum_flow_relabel_to_front.h similarity index 53% rename from include/0003_Graph/0019_MaximumFlowRelabelToFront.h rename to src/0003_graph/headers/0019_maximum_flow_relabel_to_front.h index aea70f6..4f57573 100644 --- a/include/0003_Graph/0019_MaximumFlowRelabelToFront.h +++ b/src/0003_graph/headers/0019_maximum_flow_relabel_to_front.h @@ -4,7 +4,7 @@ #include using namespace std; -namespace MaximumFlowRelabelToFront +namespace dsa::maximum_flow_relabel_to_front { class Graph { @@ -19,13 +19,13 @@ namespace MaximumFlowRelabelToFront vector _height; vector _visited; list _nodeList; - void InitializePreflow(); - void Discharge(int nodeU); - void Push(int nodeU, int nodeV); - void Relabel(int nodeU); + void _initializePreflow(); + void _discharge(int nodeU); + void _push(int nodeU, int nodeV); + void _relabel(int nodeU); public: - void CreateGraph(int noOfVertices); - void PushDirectedEdge(int valueU, int valueV, int capacity); - int FindMaximumFlowRelabelToFront(); + void createGraph(int noOfVertices); + void pushDirectedEdge(int valueU, int valueV, int capacity); + int findMaximumFlowRelabelToFront(); }; } \ No newline at end of file diff --git a/src/0004_GreedyAlgorithms/CMakeLists.txt b/src/0004_GreedyAlgorithms/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/0004_dynamic_programming/0001_fibonacci_number.cc b/src/0004_dynamic_programming/0001_fibonacci_number.cc new file mode 100644 index 0000000..837f8d2 --- /dev/null +++ b/src/0004_dynamic_programming/0001_fibonacci_number.cc @@ -0,0 +1,28 @@ +#include "0001_fibonacci_number.h" + +namespace dsa::fibonacci_number +{ + int DynamicProgramming::recursiveNthFibonacci(int n) + { + if (n <= 1) + { + return n; + } + + return this->recursiveNthFibonacci(n - 1) + this->recursiveNthFibonacci(n - 2); + } + + int DynamicProgramming::dpNthFibonacci(int n) + { + vector dp(n + 1, 0); + dp[0] = 0; + dp[1] = 1; + + for (int i = 2; i <= n; i++) + { + dp[i] = dp[i - 1] + dp[i - 2]; + } + + return dp[n]; + } +} diff --git a/src/0004_dynamic_programming/0002_tribonacci_number.cc b/src/0004_dynamic_programming/0002_tribonacci_number.cc new file mode 100644 index 0000000..f9a7f31 --- /dev/null +++ b/src/0004_dynamic_programming/0002_tribonacci_number.cc @@ -0,0 +1,33 @@ +#include "0002_tribonacci_number.h" + +namespace dsa::tribonacci_number +{ + int DynamicProgramming::recursiveNthTribonacci(int n) + { + if (n == 0 || n == 1 || n == 2) + { + return 0; + } + + if (n == 3) + { + return 1; + } + + return this->recursiveNthTribonacci(n - 1) + this->recursiveNthTribonacci(n - 2) + this->recursiveNthTribonacci(n - 3); + } + + int DynamicProgramming::dpNthTribonacci(int n) + { + vector dp(n, 0); + dp[0] = dp[1] = 0; + dp[2] = 1; + + for (int i = 3; i < n; i++) + { + dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]; + } + + return dp[n - 1]; + } +} diff --git a/src/0005_DynamicProgramming/0003_ClimbingStairs.cc b/src/0004_dynamic_programming/0003_climbing_stairs.cc similarity index 50% rename from src/0005_DynamicProgramming/0003_ClimbingStairs.cc rename to src/0004_dynamic_programming/0003_climbing_stairs.cc index 3dfdba6..0d7e0bf 100644 --- a/src/0005_DynamicProgramming/0003_ClimbingStairs.cc +++ b/src/0004_dynamic_programming/0003_climbing_stairs.cc @@ -1,19 +1,19 @@ -#include <0005_DynamicProgramming/0003_ClimbingStairs.h> +#include "0003_climbing_stairs.h" using namespace std; -namespace ClimbingStairs +namespace dsa::climbing_stairs { - int DynamicProgramming::RecursiveCountWays(int n) + int DynamicProgramming::recursiveCountWays(int n) { if (n == 0 || n == 1) { return 1; } - return this->RecursiveCountWays(n - 1) + this->RecursiveCountWays(n - 2); + return this->recursiveCountWays(n - 1) + this->recursiveCountWays(n - 2); } - int DynamicProgramming::DpCountWays(int n) + int DynamicProgramming::dpCountWays(int n) { vector dp(n + 1, 0); dp[0] = 1; diff --git a/src/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.cc b/src/0004_dynamic_programming/0004_minimum_cost_climbing_stairs.cc similarity index 50% rename from src/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.cc rename to src/0004_dynamic_programming/0004_minimum_cost_climbing_stairs.cc index d6b4cc1..9b2e136 100644 --- a/src/0005_DynamicProgramming/0004_MinimumCostClimbingStairs.cc +++ b/src/0004_dynamic_programming/0004_minimum_cost_climbing_stairs.cc @@ -1,19 +1,19 @@ -#include <0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h> +#include "0004_minimum_cost_climbing_stairs.h" #include -namespace MinimumCostClimbingStairs +namespace dsa::minimum_cost_climbing_stairs { - int DynamicProgramming::MinCostRecursive(size_t step, vector& cost) + int DynamicProgramming::_minCostRecursive(size_t step, vector& cost) { if (step == 0 || step == 1) { return cost[step]; } - return cost[step] + min(this->MinCostRecursive(step - 1, cost), this->MinCostRecursive(step - 2, cost)); + return cost[step] + min(this->_minCostRecursive(step - 1, cost), this->_minCostRecursive(step - 2, cost)); } - int DynamicProgramming::RecursiveMinimumCostClimbingStairs(vector& cost) + int DynamicProgramming::recursiveMinimumCostClimbingStairs(vector& cost) { size_t totalSteps = cost.size(); @@ -22,10 +22,10 @@ namespace MinimumCostClimbingStairs return cost[0]; } - return min(this->MinCostRecursive(totalSteps - 1, cost), this->MinCostRecursive(totalSteps - 2, cost)); + return min(this->_minCostRecursive(totalSteps - 1, cost), this->_minCostRecursive(totalSteps - 2, cost)); } - int DynamicProgramming::DpMinimumCostClimbingStairs(vector& cost) + int DynamicProgramming::dpMinimumCostClimbingStairs(vector& cost) { size_t totalSteps = cost.size(); vector dp(totalSteps, 0); diff --git a/src/0004_dynamic_programming/0005_house_robber1.cc b/src/0004_dynamic_programming/0005_house_robber1.cc new file mode 100644 index 0000000..5427acf --- /dev/null +++ b/src/0004_dynamic_programming/0005_house_robber1.cc @@ -0,0 +1,44 @@ +#include "0005_house_robber1.h" + +namespace dsa::house_robber1 +{ + int DynamicProgramming::_maxLootRecursive(size_t house, vector& houseValues) + { + if (house <= 0) + { + return 0; + } + + if (house == 1) + { + return houseValues[0]; + } + + int pickCurrentHouse = houseValues[house - 1] + this->_maxLootRecursive(house - 2, houseValues); + int dropCurrentHouse = this->_maxLootRecursive(house - 1, houseValues); + + return max(pickCurrentHouse, dropCurrentHouse); + } + + int DynamicProgramming::recursiveMaximumLoot(vector& houseValues) + { + size_t totalNumberOfHouses = houseValues.size(); + return this->_maxLootRecursive(totalNumberOfHouses, houseValues); + } + + int DynamicProgramming::dpMaximumLoot(vector& houseValues) + { + size_t totalNumberOfHouses = houseValues.size(); + vector dp(totalNumberOfHouses + 1, 0); + + dp[0] = 0; + dp[1] = houseValues[0]; + + for (size_t i = 2; i <= totalNumberOfHouses; i++) + { + dp[i] = max(dp[i - 2] + houseValues[i - 1], dp[i - 1]); + } + + return dp[totalNumberOfHouses]; + } +} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0006_HouseRobber2.cc b/src/0004_dynamic_programming/0006_house_robber2.cc similarity index 55% rename from src/0005_DynamicProgramming/0006_HouseRobber2.cc rename to src/0004_dynamic_programming/0006_house_robber2.cc index 42b4603..daeddc8 100644 --- a/src/0005_DynamicProgramming/0006_HouseRobber2.cc +++ b/src/0004_dynamic_programming/0006_house_robber2.cc @@ -1,8 +1,8 @@ -#include <0005_DynamicProgramming/0006_HouseRobber2.h> +#include "0006_house_robber2.h" -namespace HouseRobber2 +namespace dsa::house_robber2 { - int DynamicProgramming::MaxLootRecursive(size_t house, vector& houseValues) + int DynamicProgramming::_maxLootRecursive(size_t house, vector& houseValues) { if (house <= 0) { @@ -14,13 +14,13 @@ namespace HouseRobber2 return houseValues[0]; } - int pickCurrentHouse = houseValues[house - 1] + this->MaxLootRecursive(house - 2, houseValues); - int dropCurrentHouse = this->MaxLootRecursive(house - 1, houseValues); + int pickCurrentHouse = houseValues[house - 1] + this->_maxLootRecursive(house - 2, houseValues); + int dropCurrentHouse = this->_maxLootRecursive(house - 1, houseValues); return max(pickCurrentHouse, dropCurrentHouse); } - int DynamicProgramming::MaxLootDp(size_t firstHouse, size_t lastHouse, vector& houseValues) + int DynamicProgramming::_maxLootDp(size_t firstHouse, size_t lastHouse, vector& houseValues) { int totalNumberOfHouses = lastHouse - firstHouse + 1; @@ -47,7 +47,7 @@ namespace HouseRobber2 return dp[totalNumberOfHouses - 1]; } - int DynamicProgramming::RecursiveMaximumLoot(vector& houseValues) + int DynamicProgramming::recursiveMaximumLoot(vector& houseValues) { if (houseValues.size() == 0) { @@ -61,16 +61,16 @@ namespace HouseRobber2 size_t totalNumberOfHouses = houseValues.size()-1; - // Case 1: Exclude last house. + // Case 1: exclude last house. vector pickFirstHouse(houseValues.begin(), houseValues.end() - 1); - // Case 2: Exlcude first house. + // Case 2: exlcude first house. vector pickLastHouse(houseValues.begin() + 1, houseValues.end()); - return max(this->MaxLootRecursive(totalNumberOfHouses, pickFirstHouse), this->MaxLootRecursive(totalNumberOfHouses, pickLastHouse)); + return max(this->_maxLootRecursive(totalNumberOfHouses, pickFirstHouse), this->_maxLootRecursive(totalNumberOfHouses, pickLastHouse)); } - int DynamicProgramming::DpMaximumLoot(vector& houseValues) + int DynamicProgramming::dpMaximumLoot(vector& houseValues) { size_t totalNumberOfHouses = houseValues.size(); @@ -84,11 +84,11 @@ namespace HouseRobber2 return houseValues[0]; } - // Case 1: Exclude last house. - int pickFirstHouse = this->MaxLootDp(0, totalNumberOfHouses - 2, houseValues); + // Case 1: exclude last house. + int pickFirstHouse = this->_maxLootDp(0, totalNumberOfHouses - 2, houseValues); - // Case 2: Exlcude first house. - int pickLastHouse = this->MaxLootDp(1, totalNumberOfHouses - 1, houseValues); + // Case 2: exlcude first house. + int pickLastHouse = this->_maxLootDp(1, totalNumberOfHouses - 1, houseValues); return max(pickFirstHouse, pickLastHouse); } diff --git a/src/0005_DynamicProgramming/0007_DecodeWays.cc b/src/0004_dynamic_programming/0007_decode_ways.cc similarity index 51% rename from src/0005_DynamicProgramming/0007_DecodeWays.cc rename to src/0004_dynamic_programming/0007_decode_ways.cc index 23464f5..5b8e009 100644 --- a/src/0005_DynamicProgramming/0007_DecodeWays.cc +++ b/src/0004_dynamic_programming/0007_decode_ways.cc @@ -1,12 +1,12 @@ -#include <0005_DynamicProgramming/0007_DecodeWays.h> +#include "0007_decode_ways.h" -namespace DecodeWays +namespace dsa::decode_ways { - int DynamicProgramming::CountWaysRecursiveHelper(string& digits, size_t index) + int DynamicProgramming::_countWaysRecursiveHelper(string& digits, size_t index) { size_t digitsLength = digits.size(); - // Base case: If the end of the string is reached, return 1 as it signifies a valid decoding. + // Base case: if the end of the string is reached, return 1 as it signifies a valid decoding. if (index >= digitsLength) { return 1; @@ -14,26 +14,26 @@ namespace DecodeWays int ways = 0; - // Single digit decoding: check if current digit is not '0'. + // single digit decoding: check if current digit is not '0'. if (digits[index] != '0') { - ways = this->CountWaysRecursiveHelper(digits, index + 1); + ways = this->_countWaysRecursiveHelper(digits, index + 1); } - // Two digit decoding: check if next two digits are valid. + // two digit decoding: check if next two digits are valid. if ((index + 1 < digitsLength) && ((digits[index] == '1' && digits[index + 1] <= '9') || (digits[index] == '2' && digits[index + 1] <= '6'))) { - ways += this->CountWaysRecursiveHelper(digits, index + 2); + ways += this->_countWaysRecursiveHelper(digits, index + 2); } return ways; } - int DynamicProgramming::RecursiveCountWays(string digits) + int DynamicProgramming::recursiveCountWays(string digits) { - return this->CountWaysRecursiveHelper(digits, 0); + return this->_countWaysRecursiveHelper(digits, 0); } - int DynamicProgramming::DpCountways(string digits) + int DynamicProgramming::dpCountways(string digits) { size_t digitsLength = digits.size(); @@ -43,13 +43,13 @@ namespace DecodeWays for (int index = digitsLength - 1; index >= 0; index--) { - // Single digit decoding: check if current digit is not '0'. + // single digit decoding: check if current digit is not '0'. if (digits[index] != '0') { dp[index] = dp[index + 1]; } - // Two digit decoding: check if next two digits are valid. + // two digit decoding: check if next two digits are valid. if ((index + 1 < digitsLength) && ((digits[index] == '1' && digits[index + 1] <= '9') || (digits[index] == '2' && digits[index + 1] <= '6'))) { dp[index] += dp[index + 2]; diff --git a/src/0004_dynamic_programming/0008_tiling_problem.cc b/src/0004_dynamic_programming/0008_tiling_problem.cc new file mode 100644 index 0000000..5fa6cf8 --- /dev/null +++ b/src/0004_dynamic_programming/0008_tiling_problem.cc @@ -0,0 +1,42 @@ +#include "0008_tiling_problem.h" + +namespace dsa::tiling_problem +{ + int DynamicProgramming::_numberOfWaysRecursiveHelper(int n) + { + if (n < 0) + { + return 0; + } + + if (n == 0) + { + return 1; + } + + int result = 0; + result += this->_numberOfWaysRecursiveHelper(n - 1); + result += this->_numberOfWaysRecursiveHelper(n - 2); + + return result; + } + + int DynamicProgramming::recursiveNumberOfWays(int n) + { + return this->_numberOfWaysRecursiveHelper(n); + } + + int DynamicProgramming::dpNumberOfWays(int n) + { + vector dp(n + 1, 0); + dp[0] = 1; + dp[1] = 1; + + for (int i = 2; i <= n; i++) + { + dp[i] = dp[i - 1] + dp[i - 2]; + } + + return dp[n]; + } +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/0009_friends_pairing_problem.cc b/src/0004_dynamic_programming/0009_friends_pairing_problem.cc new file mode 100644 index 0000000..ca37ca6 --- /dev/null +++ b/src/0004_dynamic_programming/0009_friends_pairing_problem.cc @@ -0,0 +1,39 @@ +#include "0009_friends_pairing_problem.h" + +namespace dsa::friends_pairing_problem +{ + // dynamic programming private member methods. + int DynamicProgramming::_countFriendsPairingsRecursiveHelper(int n) + { + if (n <= 1) + { + return 1; + } + int result = 0; + result += this->_countFriendsPairingsRecursiveHelper(n - 1); + result += (n - 1) * this->_countFriendsPairingsRecursiveHelper(n - 2); + + return result; + } + + // dynamic programming public member methods. + int DynamicProgramming::recursiveCountFriendsPairings(int n) + { + return this->_countFriendsPairingsRecursiveHelper(n); + } + + int DynamicProgramming::dpCountFriendsPairings(int n) + { + vector dp(n + 1, 0); + dp[0] = 0; + dp[1] = 1; + dp[2] = 2; + + for (int i = 3; i <= n; i++) + { + dp[i] = dp[i - 1] + (i - 1) * dp[i - 2]; + } + + return dp[n]; + } +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/0010_ways_to_cover_distance.cc b/src/0004_dynamic_programming/0010_ways_to_cover_distance.cc new file mode 100644 index 0000000..c26c4c6 --- /dev/null +++ b/src/0004_dynamic_programming/0010_ways_to_cover_distance.cc @@ -0,0 +1,52 @@ +#include "0010_ways_to_cover_distance.h" + +namespace dsa::ways_to_cover_distance +{ + // dynamic programming private member methods. + int DynamicProgramming::_waysToCoverDistanceRecursiveHelper(int dist) + { + if (dist < 0) + { + return 0; + } + + if (dist == 0) + { + return 1; + } + + int result = 0; + result += this->_waysToCoverDistanceRecursiveHelper(dist - 1); + result += this->_waysToCoverDistanceRecursiveHelper(dist - 2); + result += this->_waysToCoverDistanceRecursiveHelper(dist - 3); + + return result; + } + + // dynamic programming public member methods. + int DynamicProgramming::recursiveWaysToCoverDistance(int dist) + { + return this->_waysToCoverDistanceRecursiveHelper(dist); + } + + int DynamicProgramming::dpWaysToCoverDistance(int dist) + { + vector dp(dist + 1, 0); + dp[0] = 1; + if (dist >= 1) + { + dp[1] = 1; + } + if (dist >= 2) + { + dp[2] = 2; + } + + for(int i = 3; i <= dist; i++) + { + dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]; + } + + return dp[dist]; + } +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/0011_count_ways_to_reach_nth_stair_include_order.cc b/src/0004_dynamic_programming/0011_count_ways_to_reach_nth_stair_include_order.cc new file mode 100644 index 0000000..3609d80 --- /dev/null +++ b/src/0004_dynamic_programming/0011_count_ways_to_reach_nth_stair_include_order.cc @@ -0,0 +1,44 @@ +#include "0011_count_ways_to_reach_nth_stair_include_order.h" + +namespace dsa::count_ways_to_reach_nth_stair_include_order +{ + // dynamic programming private member methods. + int DynamicProgramming::_recursiveCountWaysHelper(int n) + { + if (n < 0) + { + return 0; + } + if (n == 0 || n == 1) + { + return 1; + } + + int result = 0; + result += this->_recursiveCountWaysHelper(n - 1); + result += this->_recursiveCountWaysHelper(n - 2); + + return result; + } + + // dynamic programming public member methods. + int DynamicProgramming::recursiveCountWays(int n) + { + return this->_recursiveCountWaysHelper(n); + } + + int DynamicProgramming::dpCountWays(int n) + { + vector dp(n + 1, 0); + dp[0] = 1; + if (n >= 1) + { + dp[1] = 1; + } + for(int i = 2; i <= n; i++) + { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; + } +} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.cc b/src/0004_dynamic_programming/0012_count_ways_to_reach_nth_stair_exclude_order.cc similarity index 50% rename from src/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.cc rename to src/0004_dynamic_programming/0012_count_ways_to_reach_nth_stair_exclude_order.cc index 9b39bf8..8c2f165 100644 --- a/src/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.cc +++ b/src/0004_dynamic_programming/0012_count_ways_to_reach_nth_stair_exclude_order.cc @@ -1,22 +1,22 @@ -#include <0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h> +#include "0012_count_ways_to_reach_nth_stair_exclude_order.h" -namespace CountWaysToReachNthStairExcludeOrder +namespace dsa::count_ways_to_reach_nth_stair_exclude_order { // notes: /* To avoid counting ways which only differ in order, we can assume that a person initially takes only steps of size 1 followed by steps of size 2. In other words, once a person takes a step of size 2, he will continue taking steps of size 2 till he reaches the nth stair. - A person can reach nth stair from either(n - 1)th stair or from(n - 2)th stair.So, there are two cases : - The person has reached nth step from(n - 1)th step, this means that the last step was of size 1 and all the previous steps should also be of size 1. So, there is only 1 way. - The person has reached nth step from(n - 2)th step, this means that the last step was of size 2 and the previous steps can either be of size 1 or size 2. - Therefore the Recurrence relation will be : + A person can reach nth stair from either(n - 1)th stair or from(n - 2)th stair.so, there are two cases : + the person has reached nth step from(n - 1)th step, this means that the last step was of size 1 and all the previous steps should also be of size 1. so, there is only 1 way. + the person has reached nth step from(n - 2)th step, this means that the last step was of size 2 and the previous steps can either be of size 1 or size 2. + therefore the recurrence relation will be : nthStair(n) = 1 (last step was of size 1) + nthStair(n - 2) (last step was of size 2) so f(n) = 1 + f(n - 2) */ - // Dynamic Programming Private Member Methods. - int DynamicProgramming::RecursiveCountWaysToReachNthStairExcludeOrderHelper(int n) + // dynamic programming private member methods. + int DynamicProgramming::_recursiveCountWaysHelper(int n) { if (n < 0) { @@ -27,16 +27,16 @@ namespace CountWaysToReachNthStairExcludeOrder return 1; } - return 1 + this->RecursiveCountWaysToReachNthStairExcludeOrderHelper(n - 2); + return 1 + this->_recursiveCountWaysHelper(n - 2); } - // Dynamic Programming Public Member Methods. - int DynamicProgramming::RecursiveCountWaysToReachNthStairExcludeOrder(int n) + // dynamic programming public member methods. + int DynamicProgramming::recursiveCountWays(int n) { - return this->RecursiveCountWaysToReachNthStairExcludeOrderHelper(n); + return this->_recursiveCountWaysHelper(n); } - int DynamicProgramming::DpCountWaysToReachNthStairExcludeOrder(int n) + int DynamicProgramming::dpCountWays(int n) { vector dp(n + 1, 0); dp[0] = 1; diff --git a/src/0005_DynamicProgramming/0013_KnapsackProblem.cc b/src/0004_dynamic_programming/0013_knapsack_problem.cc similarity index 57% rename from src/0005_DynamicProgramming/0013_KnapsackProblem.cc rename to src/0004_dynamic_programming/0013_knapsack_problem.cc index d012a44..5952344 100644 --- a/src/0005_DynamicProgramming/0013_KnapsackProblem.cc +++ b/src/0004_dynamic_programming/0013_knapsack_problem.cc @@ -1,9 +1,9 @@ -#include <0005_DynamicProgramming/0013_KnapsackProblem.h> +#include "0013_knapsack_problem.h" -namespace KnapsackProblem +namespace dsa::knapsack_problem { - // Dynamic Programming Private Member Methods. - int DynamicProgramming::KnapsackRecursiveHelper(int capacity, vector& weight, vector& profit, int numberOfItems) + // dynamic programming private member methods. + int DynamicProgramming::_recursiveKnapsackHelper(int capacity, vector& weight, vector& profit, int numberOfItems) { if (capacity <= 0 || numberOfItems == 0) { @@ -12,25 +12,25 @@ namespace KnapsackProblem int pickCurrentItem = 0; - // Pick the current item only if does not exceed the capacity. + // pick the current item only if does not exceed the capacity. if (weight[numberOfItems - 1] <= capacity) { - pickCurrentItem = profit[numberOfItems - 1] + this->KnapsackRecursiveHelper(capacity - weight[numberOfItems - 1], weight, profit, numberOfItems - 1); + pickCurrentItem = profit[numberOfItems - 1] + this->_recursiveKnapsackHelper(capacity - weight[numberOfItems - 1], weight, profit, numberOfItems - 1); } - int dropCurrentItem = this->KnapsackRecursiveHelper(capacity, weight, profit, numberOfItems - 1); + int dropCurrentItem = this->_recursiveKnapsackHelper(capacity, weight, profit, numberOfItems - 1); return max(pickCurrentItem, dropCurrentItem); } - // Dynamic Programming Public Member Methods. - int DynamicProgramming::RecursiveKnapsack(int capacity, vector weight, vector profit) + // dynamic programming public member methods. + int DynamicProgramming::recursiveKnapsack(int capacity, vector weight, vector profit) { size_t totalNumberOfItems = weight.size(); - return this->KnapsackRecursiveHelper(capacity, weight, profit, totalNumberOfItems); + return this->_recursiveKnapsackHelper(capacity, weight, profit, totalNumberOfItems); } - int DynamicProgramming::DpKnapsack(int capacity, vector weight, vector profit) + int DynamicProgramming::dpKnapsack(int capacity, vector weight, vector profit) { int numberOfItems = weight.size(); vector> dp(numberOfItems + 1, vector(capacity + 1, 0)); @@ -60,7 +60,7 @@ namespace KnapsackProblem return dp[numberOfItems][capacity]; } - int DynamicProgramming::DpKnapsackSpaceOptimized(int capacity, vector weight, vector profit) + int DynamicProgramming::dpKnapsackSpaceOptimized(int capacity, vector weight, vector profit) { int numberOfItems = weight.size(); vector dp(capacity + 1, 0); diff --git a/src/0004_dynamic_programming/0014_subset_sum_problem.cc b/src/0004_dynamic_programming/0014_subset_sum_problem.cc new file mode 100644 index 0000000..4712c61 --- /dev/null +++ b/src/0004_dynamic_programming/0014_subset_sum_problem.cc @@ -0,0 +1,71 @@ +#include "0014_subset_sum_problem.h" + +namespace dsa::subset_sum_problem +{ + // dynamic programming private member methods. + bool DynamicProgramming::_recursiveSubsetSumHelper(vector& nums, int sum, int numberOfElements) + { + // Base case. + // if the sum is 0, we found a subset with a given sum. + if (sum == 0) + { + return true; + } + + // Base case. + // if there are no elements left to process and the sum is not 0 yet, we did not find a subset with given sum, so return false. + if (numberOfElements == 0) + { + return false; + } + + // when the current element is greater than the sum, we skip it, as all elemeents are non-negative. + if (nums[numberOfElements - 1] > sum) + { + return this->_recursiveSubsetSumHelper(nums, sum, numberOfElements - 1); + } + + // when the current element is equal to or less than the sum, we have two choices. + // 1. include the current element in the subset and the sum is reduced by the current element value and also the number of elements is reducded by 1. + // 2. exclude the current element from the subset and the sum remains the same but the number of eleements is reduced by 1. + // if either of these two choices return true, we return true. + return this->_recursiveSubsetSumHelper(nums, sum - nums[numberOfElements - 1], numberOfElements - 1) || this->_recursiveSubsetSumHelper(nums, sum, numberOfElements - 1); + } + + // dynamic programming public member methods. + bool DynamicProgramming::recursiveSubsetSum(vector nums, int sum) + { + int numberOfElements = nums.size(); + return this->_recursiveSubsetSumHelper(nums, sum, numberOfElements); + } + + bool DynamicProgramming::dpIsSubsetSum(vector nums, int sum) + { + int numberOfElements = nums.size(); + vector> dp(numberOfElements + 1, vector(sum + 1, false)); + + // when the sum is 0, the result is true + for (int i = 0; i < numberOfElements; i++) + { + dp[i][0] = true; + } + + for (int i = 1; i < numberOfElements + 1; i++) + { + for (int j = 1; j < sum + 1; j++) + { + if (j < nums[i - 1]) + { + dp[i][j] = dp[i - 1][j]; + } + else + { + // include or exclude the current element + dp[i][j] = (dp[i-1][j-nums[i-1]] || dp[i-1][j]); + } + } + } + + return dp[numberOfElements][sum]; + } +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/0015_count_subsets_for_sum.cc b/src/0004_dynamic_programming/0015_count_subsets_for_sum.cc new file mode 100644 index 0000000..394bac2 --- /dev/null +++ b/src/0004_dynamic_programming/0015_count_subsets_for_sum.cc @@ -0,0 +1,55 @@ +#include "0015_count_subsets_for_sum.h" + +namespace dsa::count_subsets_for_sum +{ + // dynamic programming private member methods + int DynamicProgramming::_recursiveCountSubsetsHelper(vector& nums, int targetSum, int currentSum, int index) + { + int noOfElements = nums.size(); + if (index == noOfElements) + { + return (targetSum == currentSum); + } + + int exclude = this->_recursiveCountSubsetsHelper(nums, targetSum, currentSum, index + 1); + int include = 0; + + if ((nums[index] + currentSum) <= targetSum) + { + include = this->_recursiveCountSubsetsHelper(nums, targetSum, currentSum + nums[index], index + 1); + } + + return (exclude + include); + } + + // dynamic programming public member methods + int DynamicProgramming::recursiveCountSubsets(vector nums, int sum) + { + return this->_recursiveCountSubsetsHelper(nums, sum, 0, 0); + } + + int DynamicProgramming::dpCountSubsets(vector nums, int sum) + { + int noOfElements = nums.size(); + vector> dp(noOfElements + 1, vector(sum + 1, 0)); + + dp[0][0] = 1; + + for (int i = 1; i <= noOfElements; i++) + { + for (int j = 0; j <= sum; j++) + { + // considering excluding the current element + dp[i][j] = dp[i - 1][j]; + + // Case to include the current element + if (nums[i - 1] <= j) + { + dp[i][j] += dp[i - 1][j - nums[i - 1]]; + } + } + } + + return dp[noOfElements][sum]; + } +} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0016_PartitionEqualSubsetSum.cc b/src/0004_dynamic_programming/0016_partition_equal_subset_sum.cc similarity index 53% rename from src/0005_DynamicProgramming/0016_PartitionEqualSubsetSum.cc rename to src/0004_dynamic_programming/0016_partition_equal_subset_sum.cc index 883b599..54f0456 100644 --- a/src/0005_DynamicProgramming/0016_PartitionEqualSubsetSum.cc +++ b/src/0004_dynamic_programming/0016_partition_equal_subset_sum.cc @@ -1,8 +1,8 @@ -#include <0005_DynamicProgramming/0016_PartitionEqualSubsetSum.h> +#include "0016_partition_equal_subset_sum.h" -namespace PartitionEqualSubsetSum +namespace dsa::partition_equal_subset_sum { - bool DynamicProgramming::RecursivePartitionEqualSubsetsHelper(vector& nums, int targetSum, int numberOfElements) + bool DynamicProgramming::_recursivePartitionEqualSubsetsHelper(vector& nums, int targetSum, int numberOfElements) { if (targetSum == 0) { @@ -16,31 +16,31 @@ namespace PartitionEqualSubsetSum if (nums[numberOfElements - 1] > targetSum) { - return this->RecursivePartitionEqualSubsetsHelper(nums, targetSum, numberOfElements - 1); + return this->_recursivePartitionEqualSubsetsHelper(nums, targetSum, numberOfElements - 1); } - return (this->RecursivePartitionEqualSubsetsHelper(nums, targetSum - nums[numberOfElements - 1], numberOfElements - 1) || this->RecursivePartitionEqualSubsetsHelper(nums, targetSum, numberOfElements - 1)); + return (this->_recursivePartitionEqualSubsetsHelper(nums, targetSum - nums[numberOfElements - 1], numberOfElements - 1) || this->_recursivePartitionEqualSubsetsHelper(nums, targetSum, numberOfElements - 1)); } - bool DynamicProgramming::RecursivePartitionEqualSubsets(vector nums) + bool DynamicProgramming::recursivePartitionEqualSubsets(vector nums) { int targetSum = accumulate(nums.begin(), nums.end(), 0); - // Check if targetSum is odd, then equal partition is not possible at all + // check if targetSum is odd, then equal partition is not possible at all if (targetSum % 2 != 0) { return false; } int numberOfElements = nums.size(); - return this->RecursivePartitionEqualSubsetsHelper(nums, targetSum / 2, numberOfElements); + return this->_recursivePartitionEqualSubsetsHelper(nums, targetSum / 2, numberOfElements); } - bool DynamicProgramming::DpPartitionEqualSubsets(vector nums) + bool DynamicProgramming::dpPartitionEqualSubsets(vector nums) { int targetSum = accumulate(nums.begin(), nums.end(), 0); - // Check if targetSum is odd, then equal partition is not possible at all + // check if targetSum is odd, then equal partition is not possible at all if (targetSum % 2 != 0) { return false; diff --git a/src/0005_DynamicProgramming/0017_TargetSum.cc b/src/0004_dynamic_programming/0017_target_sum.cc similarity index 54% rename from src/0005_DynamicProgramming/0017_TargetSum.cc rename to src/0004_dynamic_programming/0017_target_sum.cc index 2ae4891..c610813 100644 --- a/src/0005_DynamicProgramming/0017_TargetSum.cc +++ b/src/0004_dynamic_programming/0017_target_sum.cc @@ -1,8 +1,8 @@ -#include <0005_DynamicProgramming/0017_TargetSum.h> +#include "0017_target_sum.h" -namespace TargetSum +namespace dsa::target_sum { - int DynamicProgramming::RecursiveFindTotalWaysHelper(vector& nums, int currentSum, int targetSum, int index) + int DynamicProgramming::_recursiveFindTotalWaysHelper(vector& nums, int currentSum, int targetSum, int index) { // Base case if (currentSum == targetSum && index == nums.size()) @@ -15,21 +15,21 @@ namespace TargetSum return 0; } - // Return total count of two possible ways while considering the current element - // 1. Add the current element to currentSum - // 2. Subtract the current element from currentSum + // return total count of two possible ways while considering the current element + // 1. add the current element to currentSum + // 2. subtract the current element from currentSum return ( - this->RecursiveFindTotalWaysHelper(nums, currentSum + nums[index], targetSum, index + 1) + this->_recursiveFindTotalWaysHelper(nums, currentSum + nums[index], targetSum, index + 1) + - this->RecursiveFindTotalWaysHelper(nums, currentSum - nums[index], targetSum, index + 1)); + this->_recursiveFindTotalWaysHelper(nums, currentSum - nums[index], targetSum, index + 1)); } - int DynamicProgramming::RecursiveFindTotalWays(vector nums, int target) + int DynamicProgramming::recursiveFindTotalWays(vector nums, int target) { - return this->RecursiveFindTotalWaysHelper(nums, 0, target, 0); + return this->_recursiveFindTotalWaysHelper(nums, 0, target, 0); } - int DynamicProgramming::DpFindTotalWays(vector nums, int target) + int DynamicProgramming::dpFindTotalWays(vector nums, int target) { int totalSum = accumulate(nums.begin(), nums.end(), 0); @@ -54,7 +54,7 @@ namespace TargetSum { for (int j = 0; j <= targetSubsetSum; j++) { - // Considering excluding the current element + // considering excluding the current element dp[i][j] = dp[i - 1][j]; // Case to include the current element diff --git a/src/0004_dynamic_programming/CMakeLists.txt b/src/0004_dynamic_programming/CMakeLists.txt new file mode 100644 index 0000000..fa18701 --- /dev/null +++ b/src/0004_dynamic_programming/CMakeLists.txt @@ -0,0 +1,28 @@ +# Specify the source files +set(0005DYNAMICPROGRAMMING_SOURCES + 0001_fibonacci_number.cc + 0002_tribonacci_number.cc + 0003_climbing_stairs.cc + 0004_minimum_cost_climbing_stairs.cc + 0005_house_robber1.cc + 0006_house_robber2.cc + 0007_decode_ways.cc + 0008_tiling_problem.cc + 0009_friends_pairing_problem.cc + 0010_ways_to_cover_distance.cc + 0011_count_ways_to_reach_nth_stair_include_order.cc + 0012_count_ways_to_reach_nth_stair_exclude_order.cc + 0013_knapsack_problem.cc + 0014_subset_sum_problem.cc + 0015_count_subsets_for_sum.cc + 0016_partition_equal_subset_sum.cc + 0017_target_sum.cc + +) + +# Create a library target +add_library(0005_DynamicProgramming ${0005DYNAMICPROGRAMMING_SOURCES}) + +target_include_directories(0005_DynamicProgramming PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/headers +) \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0001_fibonacci_number.h b/src/0004_dynamic_programming/headers/0001_fibonacci_number.h new file mode 100644 index 0000000..fa8fabb --- /dev/null +++ b/src/0004_dynamic_programming/headers/0001_fibonacci_number.h @@ -0,0 +1,23 @@ +#pragma once +#include +using namespace std; + +/* +pattern 1 +linear recurrence + +description +print the n'th fibonacci number. + +*/ + +namespace dsa::fibonacci_number +{ + class DynamicProgramming + { + private: + public: + int recursiveNthFibonacci(int n); + int dpNthFibonacci(int n); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0002_tribonacci_number.h b/src/0004_dynamic_programming/headers/0002_tribonacci_number.h new file mode 100644 index 0000000..9f2ab4c --- /dev/null +++ b/src/0004_dynamic_programming/headers/0002_tribonacci_number.h @@ -0,0 +1,23 @@ +#pragma once +#include +using namespace std; + +/* +pattern 1 +linear recurrence + +description +print the n'th tribonacci number. + +*/ + +namespace dsa::tribonacci_number +{ + class DynamicProgramming + { + private: + public: + int recursiveNthTribonacci(int n); + int dpNthTribonacci(int n); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0003_climbing_stairs.h b/src/0004_dynamic_programming/headers/0003_climbing_stairs.h new file mode 100644 index 0000000..ba3f089 --- /dev/null +++ b/src/0004_dynamic_programming/headers/0003_climbing_stairs.h @@ -0,0 +1,24 @@ +#pragma once +#include +using namespace std; + +/* +pattern 1 +linear recurrence + +description +there are n stairs, and a person standing at the bottom wants to climb stairs to reach the top. +the person can climb either 1 stair or 2 stairs at a time, the task is to count the number of ways that a person can reach at the top. + +*/ + +namespace dsa::climbing_stairs +{ + class DynamicProgramming + { + private: + public: + int recursiveCountWays(int n); + int dpCountWays(int n); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0004_minimum_cost_climbing_stairs.h b/src/0004_dynamic_programming/headers/0004_minimum_cost_climbing_stairs.h new file mode 100644 index 0000000..c38a1c8 --- /dev/null +++ b/src/0004_dynamic_programming/headers/0004_minimum_cost_climbing_stairs.h @@ -0,0 +1,25 @@ +#pragma once +#include +using namespace std; + +/* +pattern 1 +linear recurrence + +description +given an array of integers cost[] of length n, where cost[i] is the cost of the ith step on a staircase. once the cost is paid, we can either climb 1 or 2 steps. +we can either start from the step with index 0, or the step with index 1. the task is to find the minimum cost to reach the top. + +*/ + +namespace dsa::minimum_cost_climbing_stairs +{ + class DynamicProgramming + { + private: + int _minCostRecursive(size_t step, vector& cost); + public: + int recursiveMinimumCostClimbingStairs(vector& cost); + int dpMinimumCostClimbingStairs(vector& cost); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0005_house_robber1.h b/src/0004_dynamic_programming/headers/0005_house_robber1.h new file mode 100644 index 0000000..ea990d2 --- /dev/null +++ b/src/0004_dynamic_programming/headers/0005_house_robber1.h @@ -0,0 +1,25 @@ +#pragma once +#include +using namespace std; + +/* +pattern 1 +linear recurrence + +description +there are n houses built in a line, each of which contains some money in it. +A robber wants to steal money from these houses, but he can�t steal from two adjacent houses. the task is to find the maximum amount of money which can be stolen. + +*/ + +namespace dsa::house_robber1 +{ + class DynamicProgramming + { + private: + int _maxLootRecursive(size_t house, vector& houseValues); + public: + int recursiveMaximumLoot(vector& houseValues); + int dpMaximumLoot(vector& houseValues); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0006_house_robber2.h b/src/0004_dynamic_programming/headers/0006_house_robber2.h new file mode 100644 index 0000000..34648a2 --- /dev/null +++ b/src/0004_dynamic_programming/headers/0006_house_robber2.h @@ -0,0 +1,28 @@ +#pragma once +#include +using namespace std; + +/* +pattern 1 +linear recurrence + +description +you are given an array arr[] which represents houses arranged in a circle, where each house has a certain value. A thief aims to maximize the total stolen value without robbing two adjacent houses. +determine the maximum amount the thief can steal. + +note: since the houses are in a circle, the first and last houses are also considered adjacent. + +*/ + +namespace dsa::house_robber2 +{ + class DynamicProgramming + { + private: + int _maxLootRecursive(size_t house, vector& houseValues); + int _maxLootDp(size_t firstHouse, size_t lastHouse, vector& houseValues); + public: + int recursiveMaximumLoot(vector& houseValues); + int dpMaximumLoot(vector& houseValues); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0007_decode_ways.h b/src/0004_dynamic_programming/headers/0007_decode_ways.h new file mode 100644 index 0000000..f2525ec --- /dev/null +++ b/src/0004_dynamic_programming/headers/0007_decode_ways.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +using namespace std; + +/* +pattern 1 +linear recurrence + +description +let 1 maps to 'A', 2 maps to 'B', ..., 26 to 'Z'.given a digit sequence, count the number of possible decodings of the given digit sequence. + +consider the input string "123".there are three valid ways to decode it : +"ABC" : the grouping is(1, 2, 3) -> 'A', 'B', 'C' +"AW" : the grouping is(1, 23) -> 'A', 'W' +"LC" : the grouping is(12, 3) -> 'L', 'C' +note : groupings that contain invalid codes(e.g., "0" by itself or numbers greater than "26") are not allowed. +for instance, the string "230" is invalid because "0" cannot stand alone, and "30" is greater than "26", so it cannot represent any letter.the task is to find the total number of valid ways to decode a given string. +*/ + +namespace dsa::decode_ways +{ + class DynamicProgramming + { + private: + int _countWaysRecursiveHelper(string& digits, size_t index); + public: + int recursiveCountWays(string digits); + int dpCountways(string digits); + }; +} \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0008_TilingProblem.h b/src/0004_dynamic_programming/headers/0008_tiling_problem.h similarity index 54% rename from include/0005_DynamicProgramming/0008_TilingProblem.h rename to src/0004_dynamic_programming/headers/0008_tiling_problem.h index e9befb0..ef0c97f 100644 --- a/include/0005_DynamicProgramming/0008_TilingProblem.h +++ b/src/0004_dynamic_programming/headers/0008_tiling_problem.h @@ -4,22 +4,22 @@ using namespace std; /* -Pattern 1 -Linear Recurrence +pattern 1 +linear recurrence -Description -Given a "2 x n" board and tiles of size "2 x 1", the task is to count the number of ways to tile the given board using the 2 x 1 tiles. +description +given a "2 x n" board and tiles of size "2 x 1", the task is to count the number of ways to tile the given board using the 2 x 1 tiles. A tile can either be placed horizontally i.e., as a 1 x 2 tile or vertically i.e., as 2 x 1 tile. */ -namespace TilingProblem +namespace dsa::tiling_problem { class DynamicProgramming { private: - int NumberOfWaysRecursiveHelper(int n); + int _numberOfWaysRecursiveHelper(int n); public: - int RecursiveNumberOfWays(int n); - int DpNumberOfWays(int n); + int recursiveNumberOfWays(int n); + int dpNumberOfWays(int n); }; } \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0009_FriendsPairingProblem.h b/src/0004_dynamic_programming/headers/0009_friends_pairing_problem.h similarity index 58% rename from include/0005_DynamicProgramming/0009_FriendsPairingProblem.h rename to src/0004_dynamic_programming/headers/0009_friends_pairing_problem.h index 79cd9da..6433a8d 100644 --- a/include/0005_DynamicProgramming/0009_FriendsPairingProblem.h +++ b/src/0004_dynamic_programming/headers/0009_friends_pairing_problem.h @@ -4,25 +4,25 @@ using namespace std; /* -Pattern 1 -Linear Recurrence +pattern 1 +linear recurrence -Description -Given n friends, each one can remain single or can be paired up with some other friend. Each friend can be paired only once. Find out the total number of ways in which friends can remain single or can be paired up. +description +given n friends, each one can remain single or can be paired up with some other friend. each friend can be paired only once. find out the total number of ways in which friends can remain single or can be paired up. -Examples: +examples: -Input : n = 3 -Output : 4 -Explanation: +input : n = 3 +output : 4 +explanation: {1}, {2}, {3} : all single {1}, {2, 3} : 2 and 3 paired but 1 is single. {1, 2}, {3} : 1 and 2 are paired but 3 is single. {1, 3}, {2} : 1 and 3 are paired but 2 is single. -Note that {1, 2} and {2, 1} are considered same. +note that {1, 2} and {2, 1} are considered same. -Mathematical Explanation: -The problem is simplified version of how many ways we can divide n elements into multiple groups. +mathematical explanation: +the problem is simplified version of how many ways we can divide n elements into multiple groups. (here group size will be max of 2 elements). In case of n = 3, we have only 2 ways to make a group: 1) all elements are individual(1,1,1) @@ -33,14 +33,14 @@ In case of n = 4, we have 3 ways to form a group: 3) 2 separate pairs (2,2) */ -namespace FriendsPairingProblem +namespace dsa::friends_pairing_problem { class DynamicProgramming { private: - int CountFriendsPairingsRecursiveHelper(int n); + int _countFriendsPairingsRecursiveHelper(int n); public: - int RecursiveCountFriendsPairings(int n); - int DpCountFriendsPairings(int n); + int recursiveCountFriendsPairings(int n); + int dpCountFriendsPairings(int n); }; } \ No newline at end of file diff --git a/include/0005_DynamicProgramming/0010_WaysToCoverDistance.h b/src/0004_dynamic_programming/headers/0010_ways_to_cover_distance.h similarity index 50% rename from include/0005_DynamicProgramming/0010_WaysToCoverDistance.h rename to src/0004_dynamic_programming/headers/0010_ways_to_cover_distance.h index 0268ff5..eb264b2 100644 --- a/include/0005_DynamicProgramming/0010_WaysToCoverDistance.h +++ b/src/0004_dynamic_programming/headers/0010_ways_to_cover_distance.h @@ -4,17 +4,17 @@ using namespace std; /* -Pattern 1 -Linear Recurrence +pattern 1 +linear recurrence -Description -Given a distance 'dist', count total number of ways to cover the distance with 1, 2 and 3 steps. +description +given a distance 'dist', count total number of ways to cover the distance with 1, 2 and 3 steps. -Examples: +examples: -Input: n = 3 -Output: 4 -Explanation: Below are the four ways +input: n = 3 +output: 4 +explanation: below are the four ways => 1 step + 1 step + 1 step => 1 step + 2 step => 2 step + 1 step @@ -22,9 +22,9 @@ Explanation: Below are the four ways -Input: n = 4 -Output: 7 -Explanation: Below are the four ways +input: n = 4 +output: 7 +explanation: below are the four ways => 1 step + 1 step + 1 step + 1 step => 1 step + 2 step + 1 step => 2 step + 1 step + 1 step @@ -34,14 +34,14 @@ Explanation: Below are the four ways => 1 step + 3 step */ -namespace WaysToCoverDistance +namespace dsa::ways_to_cover_distance { class DynamicProgramming { private: - int WaysToCoverDistanceRecursiveHelper(int dist); + int _waysToCoverDistanceRecursiveHelper(int dist); public: - int RecursiveWaysToCoverDistance(int dist); - int DpWaysToCoverDistance(int dist); + int recursiveWaysToCoverDistance(int dist); + int dpWaysToCoverDistance(int dist); }; } \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0011_count_ways_to_reach_nth_stair_include_order.h b/src/0004_dynamic_programming/headers/0011_count_ways_to_reach_nth_stair_include_order.h new file mode 100644 index 0000000..b9b8fcc --- /dev/null +++ b/src/0004_dynamic_programming/headers/0011_count_ways_to_reach_nth_stair_include_order.h @@ -0,0 +1,42 @@ +#pragma once + +#include +using namespace std; + +/* +pattern 1 +linear recurrence + +description +there are n stairs, and a person standing at the bottom wants to climb stairs to reach the top. +the person can climb either 1 stair or 2 stairs at a time, the task is to count the number of ways that a person can reach at the top. + +note: this problem is similar to count ways to reach nth stair (order does not matter) with the only difference that in this problem, +we count all distinct ways where different orderings of the steps are considered unique. + +examples: + +input: n = 1 +output: 1 +explanation: there is only one way to climb 1 stair. + +input: n = 2 +output: 2 +explanation: there are two ways to reach 2th stair: {1, 1} and {2}. + +input: n = 4 +output: 5 +explanation: there are five ways to reach 4th stair: {1, 1, 1, 1}, {1, 1, 2}, {2, 1, 1}, {1, 2, 1} and {2, 2}. +*/ + +namespace dsa::count_ways_to_reach_nth_stair_include_order +{ + class DynamicProgramming + { + private: + int _recursiveCountWaysHelper(int n); + public: + int recursiveCountWays(int n); + int dpCountWays(int n); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0012_count_ways_to_reach_nth_stair_exclude_order.h b/src/0004_dynamic_programming/headers/0012_count_ways_to_reach_nth_stair_exclude_order.h new file mode 100644 index 0000000..0cca6d3 --- /dev/null +++ b/src/0004_dynamic_programming/headers/0012_count_ways_to_reach_nth_stair_exclude_order.h @@ -0,0 +1,44 @@ +#pragma once + +#include +using namespace std; + +/* +pattern 1 +linear recurrence + +description +there are n stairs, and a person standing at the bottom wants to reach the top. the person can climb either 1 stair or 2 stairs at a time. count the number of ways, the person can reach the top (order does not matter). + +note: the problem is similar to climbing stairs - count ways to reach nth stair with the only difference that in this problem, we don't have to count those ways which only differ in ordering of the steps. + +examples: + +input: n = 1 +output: 1 +explanation: there is only one way to climb 1 stair. + +input: n = 2 +output: 2 +explanation: there are two ways to climb 2 stairs: {1, 1} and {2}. + +input: n = 4 +output: 3 +explanation: three ways to reach 4th stair: {1, 1, 1, 1}, {1, 1, 2} and {2, 2}. + +input: n = 5 +output: 3 +explanation: three ways to reach 5th stair: {1, 1, 1, 1, 1}, {1, 1, 1, 2} and {1, 2, 2}. +*/ + +namespace dsa::count_ways_to_reach_nth_stair_exclude_order +{ + class DynamicProgramming + { + private: + int _recursiveCountWaysHelper(int n); + public: + int recursiveCountWays(int n); + int dpCountWays(int n); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0013_knapsack_problem.h b/src/0004_dynamic_programming/headers/0013_knapsack_problem.h new file mode 100644 index 0000000..51f8287 --- /dev/null +++ b/src/0004_dynamic_programming/headers/0013_knapsack_problem.h @@ -0,0 +1,34 @@ +#pragma once + +#include +using namespace std; + +/* +pattern 2 +subset / 0-1 knapsack + +description +given n items where each item has some weight and profit associated with it and also given a bag with capacity W, [i.e., the bag can hold at most W weight in it]. the task is to put the items into the bag such that the sum of profits associated with them is the maximum possible. + +note: the constraint here is we can either put an item completely into the bag or cannot put it at all [it is not possible to put a part of an item into the bag]. + +input: W = 4, profit[] = [1, 2, 3], weight[] = [4, 5, 1] +output: 3 +explanation: there are two items which have weight less than or equal to 4. if we select the item with weight 4, the possible profit is 1. and if we select the item with weight 1, the possible profit is 3. so the maximum possible profit is 3. note that we cannot put both the items with weight 4 and 1 together as the capacity of the bag is 4. + +input: W = 3, profit[] = [1, 2, 3], weight[] = [4, 5, 6] +output: 0 +*/ + +namespace dsa::knapsack_problem +{ + class DynamicProgramming + { + private: + int _recursiveKnapsackHelper(int capacity, vector& weight, vector& profit, int numberOfItems); + public: + int recursiveKnapsack(int capacity, vector weight, vector profit); + int dpKnapsack(int capacity, vector weight, vector profit); + int dpKnapsackSpaceOptimized(int capacity, vector weight, vector profit); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0014_subset_sum_problem.h b/src/0004_dynamic_programming/headers/0014_subset_sum_problem.h new file mode 100644 index 0000000..0ecb546 --- /dev/null +++ b/src/0004_dynamic_programming/headers/0014_subset_sum_problem.h @@ -0,0 +1,34 @@ +#pragma once + +#include +using namespace std; + +/* +pattern 2 +subset / 0-1 knapsack + +description +given an array arr[] of non-negative integers and a value sum, the task is to check if there is a subset of the given array whose sum is equal to the given sum. + +examples: + +input: arr[] = [3, 34, 4, 12, 5, 2], sum = 9 +output: true +explanation: there is a subset (4, 5) with sum 9. + +input: arr[] = [3, 34, 4, 12, 5, 2], sum = 30 +output: false +explanation: there is no subset that add up to 30. +*/ + +namespace dsa::subset_sum_problem +{ + class DynamicProgramming + { + private: + bool _recursiveSubsetSumHelper(vector& nums, int sum, int numberOfElements); + public: + bool recursiveSubsetSum(vector nums, int sum); + bool dpIsSubsetSum(vector nums, int sum); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0015_count_subsets_for_sum.h b/src/0004_dynamic_programming/headers/0015_count_subsets_for_sum.h new file mode 100644 index 0000000..db5e7da --- /dev/null +++ b/src/0004_dynamic_programming/headers/0015_count_subsets_for_sum.h @@ -0,0 +1,34 @@ +#pragma once + +#include +using namespace std; + +/* +pattern 2 +subset / 0-1 knapsack + +description +given an array arr[] of length n and an integer target, the task is to find the number of subsets with a sum equal to target. + +examples: + +input: arr[] = [1, 2, 3, 3], target = 6 +output: 3 +explanation: all the possible subsets are [1, 2, 3], [1, 2, 3] and [3, 3] + +input: arr[] = [1, 1, 1, 1], target = 1 +output: 4 +explanation: all the possible subsets are [1], [1], [1] and [1] +*/ + +namespace dsa::count_subsets_for_sum +{ + class DynamicProgramming + { + private: + int _recursiveCountSubsetsHelper(vector& nums, int targetSum, int currentSum, int index); + public: + int recursiveCountSubsets(vector nums, int sum); + int dpCountSubsets(vector nums, int sum); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0016_partition_equal_subset_sum.h b/src/0004_dynamic_programming/headers/0016_partition_equal_subset_sum.h new file mode 100644 index 0000000..9aa6a04 --- /dev/null +++ b/src/0004_dynamic_programming/headers/0016_partition_equal_subset_sum.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +using namespace std; + +/* +pattern 2 +subset / 0-1 knapsack + +description +given an array arr[], check if it can be partitioned into two parts such that the sum of elements in both parts is the same. +note: each element is present in either the first subset or the second subset, but not in both. + +examples: + +input: arr[] = [1, 5, 11, 5] +output: true +explanation: the array can be partitioned as [1, 5, 5] and [11] and the sum of both the subsets are equal. + +input: arr[] = [1, 5, 3] +output: false +explanation: the array cannot be partitioned into equal sum sets. +*/ + +namespace dsa::partition_equal_subset_sum +{ + class DynamicProgramming + { + private: + bool _recursivePartitionEqualSubsetsHelper(vector& nums, int targetSum, int numberOfElements); + public: + bool recursivePartitionEqualSubsets(vector nums); + bool dpPartitionEqualSubsets(vector nums); + }; +} \ No newline at end of file diff --git a/src/0004_dynamic_programming/headers/0017_target_sum.h b/src/0004_dynamic_programming/headers/0017_target_sum.h new file mode 100644 index 0000000..20b2a05 --- /dev/null +++ b/src/0004_dynamic_programming/headers/0017_target_sum.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +using namespace std; + +/* +pattern 2 +subset / 0-1 knapsack + +description +given an array arr[] of length N and an integer target. +you want to build an expression out of arr[] by adding one of the symbols '+' and '-' before each integer in arr[] and then concatenate all the integers. +return the number of different expressions that can be built, which evaluates to target. + +example: + +input : N = 5, arr[] = {1, 1, 1, 1, 1}, target = 3 +output: 5 +explanation: +there are 5 ways to assign symbols to +make the sum of array be target 3. + +-1 + 1 + 1 + 1 + 1 = 3 ++1 - 1 + 1 + 1 + 1 = 3 ++1 + 1 - 1 + 1 + 1 = 3 ++1 + 1 + 1 - 1 + 1 = 3 ++1 + 1 + 1 + 1 - 1 = 3 + +input: N = 1, arr[] = {1}, target = 1 +output: 1 +*/ + +namespace dsa::target_sum +{ + class DynamicProgramming + { + private: + int _recursiveFindTotalWaysHelper(vector& nums, int currentSum, int targetSum, int index); + public: + int recursiveFindTotalWays(vector nums, int target); + int dpFindTotalWays(vector nums, int target); + }; +} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0001_FibonacciNumber.cc b/src/0005_DynamicProgramming/0001_FibonacciNumber.cc deleted file mode 100644 index 417140c..0000000 --- a/src/0005_DynamicProgramming/0001_FibonacciNumber.cc +++ /dev/null @@ -1,28 +0,0 @@ -#include <0005_DynamicProgramming/0001_FibonacciNumber.h> - -namespace FibonacciNumber -{ - int DynamicProgramming::RecursiveNthFibonacci(int n) - { - if (n <= 1) - { - return n; - } - - return this->RecursiveNthFibonacci(n - 1) + this->RecursiveNthFibonacci(n - 2); - } - - int DynamicProgramming::DpNthFibonacci(int n) - { - vector dp(n + 1, 0); - dp[0] = 0; - dp[1] = 1; - - for (int i = 2; i <= n; i++) - { - dp[i] = dp[i - 1] + dp[i - 2]; - } - - return dp[n]; - } -} diff --git a/src/0005_DynamicProgramming/0002_TribonacciNumber.cc b/src/0005_DynamicProgramming/0002_TribonacciNumber.cc deleted file mode 100644 index 8e3c95c..0000000 --- a/src/0005_DynamicProgramming/0002_TribonacciNumber.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include <0005_DynamicProgramming/0002_TribonacciNumber.h> - -namespace TribonacciNumber -{ - int DynamicProgramming::RecursiveNthTribonacci(int n) - { - if (n == 0 || n == 1 || n == 2) - { - return 0; - } - - if (n == 3) - { - return 1; - } - - return this->RecursiveNthTribonacci(n - 1) + this->RecursiveNthTribonacci(n - 2) + this->RecursiveNthTribonacci(n - 3); - } - - int DynamicProgramming::DpNthTribonacci(int n) - { - vector dp(n, 0); - dp[0] = dp[1] = 0; - dp[2] = 1; - - for (int i = 3; i < n; i++) - { - dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]; - } - - return dp[n - 1]; - } -} diff --git a/src/0005_DynamicProgramming/0005_HouseRobber1.cc b/src/0005_DynamicProgramming/0005_HouseRobber1.cc deleted file mode 100644 index 3bb1e18..0000000 --- a/src/0005_DynamicProgramming/0005_HouseRobber1.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include <0005_DynamicProgramming/0005_HouseRobber1.h> - -namespace HouseRobber1 -{ - int DynamicProgramming::MaxLootRecursive(size_t house, vector& houseValues) - { - if (house <= 0) - { - return 0; - } - - if (house == 1) - { - return houseValues[0]; - } - - int pickCurrentHouse = houseValues[house - 1] + this->MaxLootRecursive(house - 2, houseValues); - int dropCurrentHouse = this->MaxLootRecursive(house - 1, houseValues); - - return max(pickCurrentHouse, dropCurrentHouse); - } - - int DynamicProgramming::RecursiveMaximumLoot(vector& houseValues) - { - size_t totalNumberOfHouses = houseValues.size(); - return this->MaxLootRecursive(totalNumberOfHouses, houseValues); - } - - int DynamicProgramming::DpMaximumLoot(vector& houseValues) - { - size_t totalNumberOfHouses = houseValues.size(); - vector dp(totalNumberOfHouses + 1, 0); - - dp[0] = 0; - dp[1] = houseValues[0]; - - for (size_t i = 2; i <= totalNumberOfHouses; i++) - { - dp[i] = max(dp[i - 2] + houseValues[i - 1], dp[i - 1]); - } - - return dp[totalNumberOfHouses]; - } -} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0008_TilingProblem.cc b/src/0005_DynamicProgramming/0008_TilingProblem.cc deleted file mode 100644 index 4b7e50d..0000000 --- a/src/0005_DynamicProgramming/0008_TilingProblem.cc +++ /dev/null @@ -1,42 +0,0 @@ -#include <0005_DynamicProgramming/0008_TilingProblem.h> - -namespace TilingProblem -{ - int DynamicProgramming::NumberOfWaysRecursiveHelper(int n) - { - if (n < 0) - { - return 0; - } - - if (n == 0) - { - return 1; - } - - int result = 0; - result += this->NumberOfWaysRecursiveHelper(n - 1); - result += this->NumberOfWaysRecursiveHelper(n - 2); - - return result; - } - - int DynamicProgramming::RecursiveNumberOfWays(int n) - { - return this->NumberOfWaysRecursiveHelper(n); - } - - int DynamicProgramming::DpNumberOfWays(int n) - { - vector dp(n + 1, 0); - dp[0] = 1; - dp[1] = 1; - - for (int i = 2; i <= n; i++) - { - dp[i] = dp[i - 1] + dp[i - 2]; - } - - return dp[n]; - } -} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0009_FriendsPairingProblem.cc b/src/0005_DynamicProgramming/0009_FriendsPairingProblem.cc deleted file mode 100644 index 4a3db08..0000000 --- a/src/0005_DynamicProgramming/0009_FriendsPairingProblem.cc +++ /dev/null @@ -1,39 +0,0 @@ -#include <0005_DynamicProgramming/0009_FriendsPairingProblem.h> - -namespace FriendsPairingProblem -{ - // Dynamic Programming Private Member Methods. - int DynamicProgramming::CountFriendsPairingsRecursiveHelper(int n) - { - if (n <= 1) - { - return 1; - } - int result = 0; - result += this->CountFriendsPairingsRecursiveHelper(n - 1); - result += (n - 1) * this->CountFriendsPairingsRecursiveHelper(n - 2); - - return result; - } - - // Dynamic Programming Public Member Methods. - int DynamicProgramming::RecursiveCountFriendsPairings(int n) - { - return this->CountFriendsPairingsRecursiveHelper(n); - } - - int DynamicProgramming::DpCountFriendsPairings(int n) - { - vector dp(n + 1, 0); - dp[0] = 0; - dp[1] = 1; - dp[2] = 2; - - for (int i = 3; i <= n; i++) - { - dp[i] = dp[i - 1] + (i - 1) * dp[i - 2]; - } - - return dp[n]; - } -} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0010_WaysToCoverDistance.cc b/src/0005_DynamicProgramming/0010_WaysToCoverDistance.cc deleted file mode 100644 index 5c3e90a..0000000 --- a/src/0005_DynamicProgramming/0010_WaysToCoverDistance.cc +++ /dev/null @@ -1,52 +0,0 @@ -#include <0005_DynamicProgramming/0010_WaysToCoverDistance.h> - -namespace WaysToCoverDistance -{ - // Dynamic Programming Private Member Methods. - int DynamicProgramming::WaysToCoverDistanceRecursiveHelper(int dist) - { - if (dist < 0) - { - return 0; - } - - if (dist == 0) - { - return 1; - } - - int result = 0; - result += this->WaysToCoverDistanceRecursiveHelper(dist - 1); - result += this->WaysToCoverDistanceRecursiveHelper(dist - 2); - result += this->WaysToCoverDistanceRecursiveHelper(dist - 3); - - return result; - } - - // Dynamic Programming Public Member Methods. - int DynamicProgramming::RecursiveWaysToCoverDistance(int dist) - { - return this->WaysToCoverDistanceRecursiveHelper(dist); - } - - int DynamicProgramming::DpWaysToCoverDistance(int dist) - { - vector dp(dist + 1, 0); - dp[0] = 1; - if (dist >= 1) - { - dp[1] = 1; - } - if (dist >= 2) - { - dp[2] = 2; - } - - for(int i = 3; i <= dist; i++) - { - dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]; - } - - return dp[dist]; - } -} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.cc b/src/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.cc deleted file mode 100644 index 42c20ba..0000000 --- a/src/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include <0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h> - -namespace CountWaysToReachNthStairIncludeOrder -{ - // Dynamic Programming Private Member Methods. - int DynamicProgramming::RecursiveCountWaysToReachNthStairIncludeOrderHelper(int n) - { - if (n < 0) - { - return 0; - } - if (n == 0 || n == 1) - { - return 1; - } - - int result = 0; - result += this->RecursiveCountWaysToReachNthStairIncludeOrderHelper(n - 1); - result += this->RecursiveCountWaysToReachNthStairIncludeOrderHelper(n - 2); - - return result; - } - - // Dynamic Programming Public Member Methods. - int DynamicProgramming::RecursiveCountWaysToReachNthStairIncludeOrder(int n) - { - return this->RecursiveCountWaysToReachNthStairIncludeOrderHelper(n); - } - - int DynamicProgramming::DpCountWaysToReachNthStairIncludeOrder(int n) - { - vector dp(n + 1, 0); - dp[0] = 1; - if (n >= 1) - { - dp[1] = 1; - } - for(int i = 2; i <= n; i++) - { - dp[i] = dp[i - 1] + dp[i - 2]; - } - return dp[n]; - } -} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0014_SubsetSumProblem.cc b/src/0005_DynamicProgramming/0014_SubsetSumProblem.cc deleted file mode 100644 index d3e60cd..0000000 --- a/src/0005_DynamicProgramming/0014_SubsetSumProblem.cc +++ /dev/null @@ -1,71 +0,0 @@ -#include <0005_DynamicProgramming/0014_SubsetSumProblem.h> - -namespace SubsetSumProblem -{ - // Dynamic Programming Private Member Methods. - bool DynamicProgramming::SubsetSumRecursiveHelper(vector& nums, int sum, int numberOfElements) - { - // Base case. - // If the sum is 0, we found a subset with a given sum. - if (sum == 0) - { - return true; - } - - // Base case. - // If there are no elements left to process and the sum is not 0 yet, we did not find a subset with given sum, so return false. - if (numberOfElements == 0) - { - return false; - } - - // When the current element is greater than the sum, we skip it, as all elemeents are non-negative. - if (nums[numberOfElements - 1] > sum) - { - return this->SubsetSumRecursiveHelper(nums, sum, numberOfElements - 1); - } - - // When the current element is equal to or less than the sum, we have two choices. - // 1. Include the current element in the subset and the sum is reduced by the current element value and also the number of elements is reducded by 1. - // 2. Exclude the current element from the subset and the sum remains the same but the number of eleements is reduced by 1. - // If either of these two choices return true, we return true. - return this->SubsetSumRecursiveHelper(nums, sum - nums[numberOfElements - 1], numberOfElements - 1) || this->SubsetSumRecursiveHelper(nums, sum, numberOfElements - 1); - } - - // Dynamic Programming Public Member Methods. - bool DynamicProgramming::RecursiveSubsetSum(vector nums, int sum) - { - int numberOfElements = nums.size(); - return this->SubsetSumRecursiveHelper(nums, sum, numberOfElements); - } - - bool DynamicProgramming::DpIsSubsetSum(vector nums, int sum) - { - int numberOfElements = nums.size(); - vector> dp(numberOfElements + 1, vector(sum + 1, false)); - - // When the sum is 0, the result is true - for (int i = 0; i < numberOfElements; i++) - { - dp[i][0] = true; - } - - for (int i = 1; i < numberOfElements + 1; i++) - { - for (int j = 1; j < sum + 1; j++) - { - if (j < nums[i - 1]) - { - dp[i][j] = dp[i - 1][j]; - } - else - { - // include or exclude the current element - dp[i][j] = (dp[i-1][j-nums[i-1]] || dp[i-1][j]); - } - } - } - - return dp[numberOfElements][sum]; - } -} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/0015_CountSubsetsForSum.cc b/src/0005_DynamicProgramming/0015_CountSubsetsForSum.cc deleted file mode 100644 index a8ddfd2..0000000 --- a/src/0005_DynamicProgramming/0015_CountSubsetsForSum.cc +++ /dev/null @@ -1,55 +0,0 @@ -#include <0005_DynamicProgramming/0015_CountSubsetsForSum.h> - -namespace CountSubsetsForSum -{ - // Dynamic Programming private member methods - int DynamicProgramming::RecursiveCountSubsetsHelper(vector& nums, int targetSum, int currentSum, int index) - { - int noOfElements = nums.size(); - if (index == noOfElements) - { - return (targetSum == currentSum); - } - - int exclude = this->RecursiveCountSubsetsHelper(nums, targetSum, currentSum, index + 1); - int include = 0; - - if ((nums[index] + currentSum) <= targetSum) - { - include = this->RecursiveCountSubsetsHelper(nums, targetSum, currentSum + nums[index], index + 1); - } - - return (exclude + include); - } - - // Dynamic Programming public member methods - int DynamicProgramming::RecursiveCountSubsets(vector nums, int sum) - { - return this->RecursiveCountSubsetsHelper(nums, sum, 0, 0); - } - - int DynamicProgramming::DpCountSubsets(vector nums, int sum) - { - int noOfElements = nums.size(); - vector> dp(noOfElements + 1, vector(sum + 1, 0)); - - dp[0][0] = 1; - - for (int i = 1; i <= noOfElements; i++) - { - for (int j = 0; j <= sum; j++) - { - // Considering excluding the current element - dp[i][j] = dp[i - 1][j]; - - // Case to include the current element - if (nums[i - 1] <= j) - { - dp[i][j] += dp[i - 1][j - nums[i - 1]]; - } - } - } - - return dp[noOfElements][sum]; - } -} \ No newline at end of file diff --git a/src/0005_DynamicProgramming/CMakeLists.txt b/src/0005_DynamicProgramming/CMakeLists.txt deleted file mode 100644 index adf0747..0000000 --- a/src/0005_DynamicProgramming/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -# Specify the source files -set(0005DYNAMICPROGRAMMING_SOURCES - 0001_FibonacciNumber.cc - 0002_TribonacciNumber.cc - 0003_ClimbingStairs.cc - 0004_MinimumCostClimbingStairs.cc - 0005_HouseRobber1.cc - 0006_HouseRobber2.cc - 0007_DecodeWays.cc - 0008_TilingProblem.cc - 0009_FriendsPairingProblem.cc - 0010_WaysToCoverDistance.cc - 0011_CountWaysToReachNthStairIncludeOrder.cc - 0012_CountWaysToReachNthStairExcludeOrder.cc - 0013_KnapsackProblem.cc - 0014_SubsetSumProblem.cc - 0015_CountSubsetsForSum.cc - 0016_PartitionEqualSubsetSum.cc - 0017_TargetSum.cc - -) - -# Create a library target -add_library(0005DYNAMICPROGRAMMING ${0005DYNAMICPROGRAMMING_SOURCES}) \ No newline at end of file diff --git a/include/0001_Basics/CMakeLists.txt b/src/0005_greedy_algorithms/CMakeLists.txt similarity index 100% rename from include/0001_Basics/CMakeLists.txt rename to src/0005_greedy_algorithms/CMakeLists.txt diff --git a/src/0006_BitwiseAlgorithms/CMakeLists.txt b/src/0006_BitwiseAlgorithms/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/include/0002_Tree/CMakeLists.txt b/src/0006_bitwise_algorithms/CMakeLists.txt similarity index 100% rename from include/0002_Tree/CMakeLists.txt rename to src/0006_bitwise_algorithms/CMakeLists.txt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 65d79e1..708289d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ -add_subdirectory(0001_Basics) -add_subdirectory(0002_Tree) -add_subdirectory(0003_Graph) -add_subdirectory(0004_GreedyAlgorithms) -add_subdirectory(0005_DynamicProgramming) -add_subdirectory(0006_BitwiseAlgorithms) \ No newline at end of file +add_subdirectory(0001_basics) +add_subdirectory(0002_tree) +add_subdirectory(0003_graph) +add_subdirectory(0004_dynamic_programming) +add_subdirectory(0005_greedy_algorithms) +add_subdirectory(0006_bitwise_algorithms) \ No newline at end of file diff --git a/tests/0000_CommonUtilities/CMakeLists.txt b/tests/0000_CommonUtilities/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/include/0003_Graph/CMakeLists.txt b/tests/0000_common_utilities/CMakeLists.txt similarity index 100% rename from include/0003_Graph/CMakeLists.txt rename to tests/0000_common_utilities/CMakeLists.txt diff --git a/tests/0000_CommonUtilities/UnitTestHelper.h b/tests/0000_common_utilities/unit_test_helper.h similarity index 71% rename from tests/0000_CommonUtilities/UnitTestHelper.h rename to tests/0000_common_utilities/unit_test_helper.h index ff676bd..956cb1b 100644 --- a/tests/0000_CommonUtilities/UnitTestHelper.h +++ b/tests/0000_common_utilities/unit_test_helper.h @@ -10,7 +10,7 @@ class UnitTestHelper { public: template - string SerializeVectorToString(vector vector) + string serializeVectorToString(vector vector) { string result = ""; for (auto& iterator : vector) @@ -22,7 +22,7 @@ class UnitTestHelper } template - string SerializeVectorToString(vector> vector) + string serializeVectorToString(vector> vector) { string result = ""; for (auto& iterator : vector) @@ -38,7 +38,7 @@ class UnitTestHelper } template - string SerializeVectorToString(vector>> vector) + string serializeVectorToString(vector>> vector) { string result = ""; for (auto& iterator : vector) @@ -54,7 +54,7 @@ class UnitTestHelper } template - string SerializeVectorToString(vector> vector) + string serializeVectorToString(vector> vector) { string result = ""; for (auto& iterator : vector) @@ -73,34 +73,34 @@ class UnitTestHelper return result; } - // This helper method is used to sort the vector of vectors of a particular typename. - // Each inner vector is sorted first. - // Then each of them are sorted by their first element, in increasing order. + // this helper method is used to sort the vector of vectors of a particular typename. + // each inner vector is sorted first. + // then each of them are sorted by their first element, in increasing order. template - vector> SortVectorOfVectors(vector> data) + vector> sortVectorOfVectors(vector> data) { - // Step 1: Sorting each inner vectors. + // step 1: sorting each inner vectors. for (auto& innerVector : data) { sort(innerVector.begin(), innerVector.end()); } - // Step 2: Sorting all the vectors by their first element, in increasing order. + // step 2: sorting all the vectors by their first element, in increasing order. sort(data.begin(), data.end(), [](const vector& a, const vector& b) { - // Checking if both inner vectors are empty to prevent out-of-bounds access. + // checking if both inner vectors are empty to prevent out-of-bounds access. if (a.empty() && b.empty()) return false; - // Considering empty vector as less than non-empty vector. + // considering empty vector as less than non-empty vector. if (a.empty()) return true; - // Considering non-empty vector as greater than empty vector. + // considering non-empty vector as greater than empty vector. if (b.empty()) return false; - // Comparing the first elements of each vector. + // comparing the first elements of each vector. return (a[0] < b[0]); }); @@ -108,36 +108,36 @@ class UnitTestHelper } template - bool NormalizeCyclesAndCompare(vector data1, vector data2) + bool normalizeCyclesAndCompare(vector data1, vector data2) { if (data1.size() != data2.size()) { return false; } - // Normalized rotation of cycle 1 + // normalized rotation of cycle 1 vector normalizedCycle1(data1); auto minIterator1 = min_element(normalizedCycle1.begin(), normalizedCycle1.end()); rotate(normalizedCycle1.begin(), minIterator1, normalizedCycle1.end()); - // Normalized rotation of cycle 2 + // normalized rotation of cycle 2 vector normalizedCycle2(data2); auto minIterator2 = min_element(normalizedCycle2.begin(), normalizedCycle2.end()); rotate(normalizedCycle2.begin(), minIterator2, normalizedCycle2.end()); - // Check clock wise + // check clock wise if (normalizedCycle1 == normalizedCycle2) { return true; } - // Check counter clock wise + // check counter clock wise reverse(normalizedCycle2.begin() + 1, normalizedCycle2.end()); return (normalizedCycle1 == normalizedCycle2); } template - vector, T>> SortVectorOfPair(vector, T>> data) + vector, T>> sortVectorOfPair(vector, T>> data) { for (auto& iterator : data) { @@ -159,15 +159,15 @@ class UnitTestHelper } template - string SortVectorOfPairAndSerialize(vector> data) + string sortVectorOfPairAndSerialize(vector> data) { - // Sorting the vector in non-decreasing order on typename T1 + // sorting the vector in non-decreasing order on typename T1 sort(data.begin(), data.end(), [](const pair& pair1, const pair& pair2) { return pair1.first < pair2.first; }); - // Serializing the vector to string + // serializing the vector to string string result = ""; for (auto& iterator : data) { diff --git a/tests/0001_Basics/NodeTest.cc b/tests/0001_Basics/NodeTest.cc deleted file mode 100644 index 35d9c36..0000000 --- a/tests/0001_Basics/NodeTest.cc +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include <0001_Basics/Node.h> - -// Demonstrate some basic assertions. -namespace NodeTesting -{ - TEST(TestingNodeValue, PositiveTestCase) - { - // Expect two strings not to be equal. - EXPECT_EQ(2 * 4, 8); - } -} \ No newline at end of file diff --git a/tests/0002_Tree/CMakeLists.txt b/tests/0001_basics/CMakeLists.txt similarity index 71% rename from tests/0002_Tree/CMakeLists.txt rename to tests/0001_basics/CMakeLists.txt index aef689e..320fb67 100644 --- a/tests/0002_Tree/CMakeLists.txt +++ b/tests/0001_basics/CMakeLists.txt @@ -5,28 +5,28 @@ FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip ) - # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(googletest) + enable_testing() add_executable( - 0002TreeTests - 0001_BinarySearchTreeTest.cc + 0001_BasicsTests + node_test.cc ) target_link_libraries( - 0002TreeTests + 0001_BasicsTests GTest::gtest_main - 0002TREE + 0001_Basics ) # Add .clang-tidy configuration to this library. if(CLANG_TIDY_EXE) - set_target_properties(0002TREE PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") + set_target_properties(0001_Basics PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") endif() include(GoogleTest) -gtest_discover_tests(0002TreeTests DISCOVERY_TIMEOUT 30) \ No newline at end of file +gtest_discover_tests(0001_BasicsTests DISCOVERY_TIMEOUT 30) \ No newline at end of file diff --git a/tests/0001_basics/node_test.cc b/tests/0001_basics/node_test.cc new file mode 100644 index 0000000..f537ce2 --- /dev/null +++ b/tests/0001_basics/node_test.cc @@ -0,0 +1,12 @@ +#include +#include "node.h" + +// demonstrate some basic assertions. +namespace dsa::node_testing +{ + TEST(testingNodeValue, positiveTestCase) + { + // expect two strings not to be equal. + EXPECT_EQ(2 * 4, 8); + } +} \ No newline at end of file diff --git a/tests/0002_Tree/0001_BinarySearchTreeTest.cc b/tests/0002_Tree/0001_BinarySearchTreeTest.cc deleted file mode 100644 index 34bf139..0000000 --- a/tests/0002_Tree/0001_BinarySearchTreeTest.cc +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include <0002_Tree/0001_BinarySearchTree.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace BinarySearchTree -{ - UnitTestHelper unitTestHelper; - - TEST(BSTInsertData, RecursiveInorderTest) - { - BinarySearchTree bst; - bst.InsertNode(50); - bst.InsertNode(30); - bst.InsertNode(60); - - - string actualResult = unitTestHelper.SerializeVectorToString(bst.GetRecursiveInorderTravesalResult()); - string expectedResult = "30 50 60"; - - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(BSTInsertData, RecursivePreorderTest) - { - BinarySearchTree bst; - bst.InsertNode(50); - bst.InsertNode(30); - bst.InsertNode(60); - - string actualResult = unitTestHelper.SerializeVectorToString(bst.GetRecursivePreorderTravesalResult()); - string expectedResult = "50 30 60"; - - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(BSTInsertData, RecursivePostorderTest) - { - BinarySearchTree bst; - bst.InsertNode(50); - bst.InsertNode(30); - bst.InsertNode(60); - - string actualResult = unitTestHelper.SerializeVectorToString(bst.GetRecursivePostorderTravesalResult()); - string expectedResult = "30 60 50"; - - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(BSTInsertData, MorrisInorderTest) - { - BinarySearchTree bst; - bst.InsertNode(50); - bst.InsertNode(30); - bst.InsertNode(60); - - - string actualResult = unitTestHelper.SerializeVectorToString(bst.GetMorrisInorderTraversalResult()); - string expectedResult = "30 50 60"; - - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(BSTInsertData, MorrisPreorderTest) - { - BinarySearchTree bst; - bst.InsertNode(50); - bst.InsertNode(30); - bst.InsertNode(60); - - - string actualResult = unitTestHelper.SerializeVectorToString(bst.GetMorrisPreorderTraversalResult()); - string expectedResult = "50 30 60"; - - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(BSTInsertData, MorrisPostorderTest) - { - BinarySearchTree bst; - bst.InsertNode(50); - bst.InsertNode(30); - bst.InsertNode(60); - - - string actualResult = unitTestHelper.SerializeVectorToString(bst.GetMorrisPostorderTraversalResult()); - string expectedResult = "30 60 50"; - - EXPECT_EQ(actualResult, expectedResult); - } -} \ No newline at end of file diff --git a/tests/0002_tree/0001_binary_search_tree_test.cc b/tests/0002_tree/0001_binary_search_tree_test.cc new file mode 100644 index 0000000..2906786 --- /dev/null +++ b/tests/0002_tree/0001_binary_search_tree_test.cc @@ -0,0 +1,91 @@ +#include +#include +#include "0001_binary_search_tree.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::binary_search_tree +{ + UnitTestHelper unitTestHelper; + + TEST(binarySearchTree, recursiveInorderTest) + { + BinarySearchTree bst; + bst.insertNode(50); + bst.insertNode(30); + bst.insertNode(60); + + + string actualResult = unitTestHelper.serializeVectorToString(bst.recursiveInorderTraversal()); + string expectedResult = "30 50 60"; + + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(binarySearchTree, recursivePreorderTest) + { + BinarySearchTree bst; + bst.insertNode(50); + bst.insertNode(30); + bst.insertNode(60); + + string actualResult = unitTestHelper.serializeVectorToString(bst.recursivePreorderTravesal()); + string expectedResult = "50 30 60"; + + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(binarySearchTree, recursivePostorderTest) + { + BinarySearchTree bst; + bst.insertNode(50); + bst.insertNode(30); + bst.insertNode(60); + + string actualResult = unitTestHelper.serializeVectorToString(bst.recursivePostorderTravesal()); + string expectedResult = "30 60 50"; + + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(binarySearchTree, morrisInorderTest) + { + BinarySearchTree bst; + bst.insertNode(50); + bst.insertNode(30); + bst.insertNode(60); + + + string actualResult = unitTestHelper.serializeVectorToString(bst.morrisInorderTraversal()); + string expectedResult = "30 50 60"; + + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(binarySearchTree, morrisPreorderTest) + { + BinarySearchTree bst; + bst.insertNode(50); + bst.insertNode(30); + bst.insertNode(60); + + + string actualResult = unitTestHelper.serializeVectorToString(bst.morrisPreorderTraversal()); + string expectedResult = "50 30 60"; + + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(binarySearchTree, morrisPostorderTest) + { + BinarySearchTree bst; + bst.insertNode(50); + bst.insertNode(30); + bst.insertNode(60); + + + string actualResult = unitTestHelper.serializeVectorToString(bst.morrisPostorderTraversal()); + string expectedResult = "30 60 50"; + + EXPECT_EQ(actualResult, expectedResult); + } +} \ No newline at end of file diff --git a/tests/0001_Basics/CMakeLists.txt b/tests/0002_tree/CMakeLists.txt similarity index 70% rename from tests/0001_Basics/CMakeLists.txt rename to tests/0002_tree/CMakeLists.txt index efa1008..b289d25 100644 --- a/tests/0001_Basics/CMakeLists.txt +++ b/tests/0002_tree/CMakeLists.txt @@ -5,27 +5,28 @@ FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip ) + # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(googletest) - enable_testing() add_executable( - 0001BasicsTests - NodeTest.cc) + 0002_TreeTests + 0001_binary_search_tree_test.cc +) target_link_libraries( - 0001BasicsTests + 0002_TreeTests GTest::gtest_main - 0001BASICS + 0002_Tree ) # Add .clang-tidy configuration to this library. if(CLANG_TIDY_EXE) - set_target_properties(0001BASICS PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") + set_target_properties(0002_Tree PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") endif() include(GoogleTest) -gtest_discover_tests(0001BasicsTests DISCOVERY_TIMEOUT 30) \ No newline at end of file +gtest_discover_tests(0002_TreeTests DISCOVERY_TIMEOUT 30) \ No newline at end of file diff --git a/tests/0003_Graph/0001_BreadthFirstSearchTest.cc b/tests/0003_Graph/0001_BreadthFirstSearchTest.cc deleted file mode 100644 index ed66cb7..0000000 --- a/tests/0003_Graph/0001_BreadthFirstSearchTest.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include <0003_Graph/0001_BreadthFirstSearch.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace BreadthFirstSearch -{ - UnitTestHelper unitTestHelper; - - - TEST(BFSTesting, ShowBFSResultTest01) - { - Graph graph; - - graph.PushUndirectedEdge(1, 2); - graph.PushUndirectedEdge(1, 3); - graph.PushUndirectedEdge(2, 4); - graph.PushUndirectedEdge(3, 5); - graph.PushUndirectedEdge(3, 6); - graph.PushUndirectedEdge(5, 6); - graph.PushUndirectedEdge(5, 7); - graph.PushUndirectedEdge(6, 7); - graph.PushUndirectedEdge(6, 8); - graph.PushUndirectedEdge(7, 8); - - graph.BFS(1); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowBFSResult()); - string expectedResult = "1(0) 2(1) 3(1) 4(2) 5(2) 6(2) 7(3) 8(3)"; - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(BFSTesting, ShowBFSResultTest02) - { - Graph graph; - - graph.PushUndirectedEdge(1, 2); - - graph.BFS(1); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowBFSResult()); - string expectedResult = "1(0) 2(1)"; - EXPECT_EQ(actualResult, expectedResult); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0002_DepthFirstSearchTest.cc b/tests/0003_Graph/0002_DepthFirstSearchTest.cc deleted file mode 100644 index d1179b3..0000000 --- a/tests/0003_Graph/0002_DepthFirstSearchTest.cc +++ /dev/null @@ -1,177 +0,0 @@ -#include -#include <0003_Graph/0002_DepthFirstSearch.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace DepthFirstSearch -{ - UnitTestHelper unitTestHelper; - - TEST(DFSTesting, ShowDFSResultTest01) - { - Graph graph; - - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(1, 4); - graph.PushDirectedEdge(2, 5); - graph.PushDirectedEdge(3, 5); - graph.PushDirectedEdge(3, 6); - graph.PushDirectedEdge(4, 2); - graph.PushDirectedEdge(5, 4); - graph.PushDirectedEdge(6, 6); - - graph.DFS(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); - string expectedResult = "1(1,8) 2(2,7) 3(9,12) 4(4,5) 5(3,6) 6(10,11)"; - EXPECT_EQ(actualResult, expectedResult); - } - - - TEST(DFSTesting, ShowDFSResultTest_SingleVertex) - { - Graph graph; - - graph.PushDirectedEdge(1, 1); - - graph.DFS(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); - string expectedResult = "1(1,2)"; - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(DFSTesting, ShowDFSResultTest_DisconnectedGraph) - { - Graph graph; - - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(3, 4); - - graph.DFS(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); - string expectedResult = "1(1,4) 2(2,3) 3(5,8) 4(6,7)"; - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(DFSTesting, ShowDFSResultTest_CyclicGraph) - { - Graph graph; - - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(3, 1); - - graph.DFS(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); - string expectedResult = "1(1,6) 2(2,5) 3(3,4)"; - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(DFSTesting, ShowDFSResultTest_LargeGraph) - { - Graph graph; - - // Adding 15 nodes with several edges - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(1, 3); - graph.PushDirectedEdge(2, 4); - graph.PushDirectedEdge(4, 5); - graph.PushDirectedEdge(5, 6); - graph.PushDirectedEdge(6, 7); - graph.PushDirectedEdge(7, 8); - graph.PushDirectedEdge(8, 9); - graph.PushDirectedEdge(9, 10); - graph.PushDirectedEdge(10, 11); - graph.PushDirectedEdge(11, 12); - graph.PushDirectedEdge(12, 13); - graph.PushDirectedEdge(13, 14); - graph.PushDirectedEdge(14, 15); - graph.PushDirectedEdge(15, 16); - - graph.DFS(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); - string expectedResult = "1(1,32) 2(2,29) 3(30,31) 4(3,28) 5(4,27) 6(5,26) 7(6,25) 8(7,24) 9(8,23) 10(9,22) 11(10,21) 12(11,20) 13(12,19) 14(13,18) 15(14,17) 16(15,16)"; - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(DFSTesting, ShowDFSResultTest_NoEdges) - { - Graph graph; - - // Adding isolated nodes - graph.PushDirectedEdge(1, 1); - graph.PushDirectedEdge(2, 2); - graph.PushDirectedEdge(3, 3); - - graph.DFS(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); - string expectedResult = "1(1,2) 2(3,4) 3(5,6)"; - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(DFSTesting, ShowDFSResultTest_CyclicGraphWithBackEdges) - { - Graph graph; - - // Creating a cycle with back edges - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(3, 1); // Cycle back to 'a' - graph.PushDirectedEdge(2, 4); // Back edge - - graph.DFS(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); - string expectedResult = "1(1,8) 2(2,7) 3(3,4) 4(5,6)"; - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(DFSTesting, ShowDFSResultTest_DenseGraph) - { - Graph graph; - - // Complete graph of 4 nodes - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(1, 3); - graph.PushDirectedEdge(1, 4); - graph.PushDirectedEdge(2, 1); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(2, 4); - graph.PushDirectedEdge(3, 1); - graph.PushDirectedEdge(3, 2); - graph.PushDirectedEdge(3, 4); - graph.PushDirectedEdge(4, 1); - graph.PushDirectedEdge(4, 2); - graph.PushDirectedEdge(4, 3); - - graph.DFS(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); - string expectedResult = "1(1,8) 2(2,7) 3(3,6) 4(4,5)"; - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(DFSTesting, ShowDFSResultTest_SelfLoopsAndParallelEdges) - { - Graph graph; - - // Adding self-loops and parallel edges - graph.PushDirectedEdge(1, 1); - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(2, 2); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(2, 3); // Parallel edge - graph.PushDirectedEdge(3, 3); // Self-loop - - graph.DFS(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); - string expectedResult = "1(1,6) 2(2,5) 3(3,4)"; - EXPECT_EQ(actualResult, expectedResult); - } - -} \ No newline at end of file diff --git a/tests/0003_Graph/0003_TopologicalSortTest.cc b/tests/0003_Graph/0003_TopologicalSortTest.cc deleted file mode 100644 index a1812e0..0000000 --- a/tests/0003_Graph/0003_TopologicalSortTest.cc +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include <0003_Graph/0003_TopologicalSort.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace TopologicalSort -{ - UnitTestHelper unitTestHelper; - - TEST(TopoSortTesting, ShowTopoSortResult) - { - Graph graph; - - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(1, 4); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(4, 3); - graph.PushSingleNode(5); - graph.PushDirectedEdge(6, 7); - graph.PushDirectedEdge(6, 8); - graph.PushDirectedEdge(7, 4); - graph.PushDirectedEdge(7, 8); - graph.PushDirectedEdge(9, 8); - - graph.TopologicalSort(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); - string expectedResult = "9(17,18) 6(11,16) 7(12,15) 8(13,14) 5(9,10) 1(1,8) 4(6,7) 2(2,5) 3(3,4)"; - - EXPECT_EQ(actualResult, expectedResult); - } - - // Test with a larger graph and multiple paths between nodes - TEST(TopoSortTesting, LargeGraphMultiplePaths) - { - Graph graph; - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(1, 3); - graph.PushDirectedEdge(2, 4); - graph.PushDirectedEdge(3, 4); - graph.PushDirectedEdge(4, 5); - graph.PushDirectedEdge(5, 6); - graph.PushDirectedEdge(6, 7); - - graph.TopologicalSort(); - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); - string expectedResult = "1(1,14) 3(12,13) 2(2,11) 4(3,10) 5(4,9) 6(5,8) 7(6,7)"; - - EXPECT_EQ(actualResult, expectedResult); - } - - // Test with a graph containing disconnected components - TEST(TopoSortTesting, DisconnectedGraph) - { - Graph graph; - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(3, 4); - graph.PushDirectedEdge(5, 6); - - graph.TopologicalSort(); - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); - string expectedResult = "5(9,12) 6(10,11) 3(5,8) 4(6,7) 1(1,4) 2(2,3)"; - - EXPECT_EQ(actualResult, expectedResult); - } - - // Test with a graph that has multiple nodes pointing to the same node - TEST(TopoSortTesting, MultipleIncomingEdges) - { - Graph graph; - graph.PushDirectedEdge(1, 3); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(3, 4); - - graph.TopologicalSort(); - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); - string expectedResult = "2(7,8) 1(1,6) 3(2,5) 4(3,4)"; - - EXPECT_EQ(actualResult, expectedResult); - } - - // Test for a single-node graph to check the base case - TEST(TopoSortTesting, SingleNodeGraph) - { - Graph graph; - graph.PushSingleNode(1); - - graph.TopologicalSort(); - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); - string expectedResult = "1(1,2)"; - - EXPECT_EQ(actualResult, expectedResult); - } - - TEST(TopoSortTesting, ShowTopoSortResultUsingKahnAlgorithm) - { - Graph graph; - - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(1, 4); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(4, 3); - graph.PushSingleNode(5); - graph.PushDirectedEdge(6, 7); - graph.PushDirectedEdge(6, 8); - graph.PushDirectedEdge(7, 4); - graph.PushDirectedEdge(7, 8); - graph.PushDirectedEdge(9, 8); - - graph.KahnTopologicalSort(); - - string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); - string expectedResult = "1(1,5) 5(2,7) 6(3,8) 9(4,10) 2(6,11) 7(9,12) 4(13,15) 8(14,17) 3(16,18)"; - - EXPECT_EQ(actualResult, expectedResult); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0004_StronglyConnectedComponentsTest.cc b/tests/0003_Graph/0004_StronglyConnectedComponentsTest.cc deleted file mode 100644 index f881993..0000000 --- a/tests/0003_Graph/0004_StronglyConnectedComponentsTest.cc +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include <0003_Graph/0004_StronglyConnectedComponents.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace StronglyConnectedComponents -{ - UnitTestHelper unitTestHelper; - - // Test case: Testing with a simple graph. - TEST(StronglyConnectedComponentsTesting, SimpleGraphTest) - { - Graph graph; - - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(1, 5); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(2, 4); - graph.PushDirectedEdge(3, 2); - graph.PushDirectedEdge(4, 4); - graph.PushDirectedEdge(5, 1); - graph.PushDirectedEdge(5, 4); - graph.PushDirectedEdge(6, 1); - graph.PushDirectedEdge(6, 3); - graph.PushDirectedEdge(6, 7); - graph.PushDirectedEdge(7, 3); - graph.PushDirectedEdge(7, 8); - graph.PushDirectedEdge(8, 6); - - auto actualResult = graph.FindAllStronglyConnectedComponents(); - vector> expectedResult = { {6, 8, 7},{1, 5},{2, 3},{4} }; - EXPECT_EQ(unitTestHelper.SortVectorOfVectors(actualResult), unitTestHelper.SortVectorOfVectors(expectedResult)); - } - - // Test case: Single Node. - TEST(StronglyConnectedComponentsTesting, SingleNodeTest) - { - Graph graph; - graph.PushSingleNode(1); - - auto actualResult = graph.FindAllStronglyConnectedComponents(); - vector> expectedResult = { {1} }; - EXPECT_EQ(unitTestHelper.SortVectorOfVectors(actualResult), unitTestHelper.SortVectorOfVectors(expectedResult)); - } - - // Test case: Disconnected Graph. - TEST(StronglyConnectedComponentsTesting, DisconnectedGraphTest) - { - Graph graph; - graph.PushSingleNode(1); - graph.PushSingleNode(2); - graph.PushSingleNode(3); - - auto actualResult = graph.FindAllStronglyConnectedComponents(); - vector> expectedResult = { {1},{3},{2} }; - EXPECT_EQ(unitTestHelper.SortVectorOfVectors(actualResult), unitTestHelper.SortVectorOfVectors(expectedResult)); - } - - // Test case: Chain of Nodes. - TEST(StronglyConnectedComponentsTesting, ChainOfNodesTest) - { - Graph graph; - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(3, 4); - - auto actualResult = graph.FindAllStronglyConnectedComponents(); - vector> expectedResult = { {2},{1},{3},{4} }; - EXPECT_EQ(unitTestHelper.SortVectorOfVectors(actualResult), unitTestHelper.SortVectorOfVectors(expectedResult)); - } - - // Test case: Bidirectional Edge. - TEST(StronglyConnectedComponentsTesting, BidirectionalEdgeTest) - { - Graph graph; - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(2, 1); - - auto actualResult = graph.FindAllStronglyConnectedComponents(); - vector> expectedResult = { {2, 1} }; - EXPECT_EQ(unitTestHelper.SortVectorOfVectors(actualResult), unitTestHelper.SortVectorOfVectors(expectedResult)); - } - - // Test case: Complex Graph. - TEST(StronglyConnectedComponentsTesting, ComplexGraphTest) - { - Graph graph; - - // Graph structure with multiple SCCs and isolated nodes. - graph.PushDirectedEdge(1, 2); - graph.PushDirectedEdge(2, 3); - graph.PushDirectedEdge(3, 1); // Cycle: 1 -> 2 -> 3 -> 1 - graph.PushDirectedEdge(4, 5); - graph.PushDirectedEdge(5, 6); - graph.PushDirectedEdge(6, 4); // Cycle: 4 -> 5 -> 6 -> 4 - graph.PushDirectedEdge(7, 8); // Single direction: 7 -> 8 - graph.PushSingleNode(9); // Isolated node. - - auto actualResult = graph.FindAllStronglyConnectedComponents(); - vector> expectedResult = { {4, 6, 5},{7}, { 2, 3, 1},{8}, {9} }; - EXPECT_EQ(unitTestHelper.SortVectorOfVectors(actualResult), unitTestHelper.SortVectorOfVectors(expectedResult)); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc b/tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc deleted file mode 100644 index 44f4f94..0000000 --- a/tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include <0003_Graph/0005_HamiltonianPathAndCycle.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace HamiltonianPathAndCycle -{ - UnitTestHelper unitTestHelper; - - TEST(HamiltonianCycleAndPathTest, ShowResult) - { - Graph graph; - - graph.PushUndirectedEdge(0, 1); - graph.PushUndirectedEdge(0, 3); - graph.PushUndirectedEdge(1, 2); - graph.PushUndirectedEdge(1, 3); - graph.PushUndirectedEdge(1, 4); - graph.PushUndirectedEdge(2, 4); - graph.PushUndirectedEdge(3, 4); - - graph.FindHamiltonianCycleAndPath(); - - bool isHamiltonianCyclePresent = graph.IsHamiltonianCyclePresent(); - bool isHamiltonianPathPresent = graph.IsHamiltonianPathPresent(); - - vector hamiltonianPathActualResult = graph.GetHamiltonianPath(); - vector hamiltonianPathExpectedResult = { 4, 3, 0, 1, 2 }; - - ASSERT_TRUE(isHamiltonianCyclePresent); - ASSERT_TRUE(isHamiltonianPathPresent); - ASSERT_TRUE(unitTestHelper.NormalizeCyclesAndCompare(hamiltonianPathActualResult, hamiltonianPathExpectedResult)); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0006_EulerianPathAndCircuitTest.cc b/tests/0003_Graph/0006_EulerianPathAndCircuitTest.cc deleted file mode 100644 index 9ff5df4..0000000 --- a/tests/0003_Graph/0006_EulerianPathAndCircuitTest.cc +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include <0003_Graph/0006_EulerianPathAndCircuit.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace EulerianPathAndCircuit -{ - UnitTestHelper unitTestHelper; - - TEST(EulerianPathAndCycle, Test1) - { - Graph graph; - - graph.PushUndirectedEdge(1, 0); - graph.PushUndirectedEdge(0, 2); - graph.PushUndirectedEdge(2, 1); - graph.PushUndirectedEdge(0, 3); - graph.PushUndirectedEdge(3, 4); - graph.PushUndirectedEdge(4, 0); - - graph.FindEulerianPathAndCircuit(); - - bool isEulerianPathPresent = graph.IsEulerianPathPresent(); - bool isEulerianCircuitPresent = graph.IsEulerianCircuitPresent(); - - vector actualEulerianPath = graph.UndirectedGraphGetEulerianPath(); - vector expectedEulerianPath = { 0, 1, 2, 0, 3, 4, 0}; - - ASSERT_TRUE(isEulerianPathPresent); - ASSERT_TRUE(isEulerianCircuitPresent); - EXPECT_EQ(expectedEulerianPath, actualEulerianPath); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithmTest.cc b/tests/0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithmTest.cc deleted file mode 100644 index a8b1d27..0000000 --- a/tests/0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithmTest.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include <0003_Graph/0007_MinimumSpanningTreeKruskalAlgorithm.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace MinimumSpanningTreeKruskalAlgorithm -{ - UnitTestHelper unitTestHelper; - - TEST(MST, Kruskal) - { - Graph graph; - - graph.PushUndirectedEdge(1, 2, 4); - graph.PushUndirectedEdge(1, 8, 8); - graph.PushUndirectedEdge(2, 8, 11); - graph.PushUndirectedEdge(2, 3, 8); - graph.PushUndirectedEdge(3, 4, 7); - graph.PushUndirectedEdge(3, 9, 2); - graph.PushUndirectedEdge(3, 6, 4); - graph.PushUndirectedEdge(4, 5, 9); - graph.PushUndirectedEdge(4, 6, 14); - graph.PushUndirectedEdge(5, 6, 10); - graph.PushUndirectedEdge(6, 7, 2); - graph.PushUndirectedEdge(7, 8, 1); - graph.PushUndirectedEdge(7, 9, 6); - graph.PushUndirectedEdge(8, 9, 7); - - graph.FindMinimumSpanningTreeKruskalAlgorithm(); - - vector, int>> actualMST = graph.GetMinimumSpanningTree(); - vector, int>> expectedMST = - { - {{7, 8}, 1}, - {{3, 9}, 2}, - {{6, 7}, 2}, - {{2, 1}, 4}, - {{3, 6}, 4}, - {{3, 4}, 7}, - {{8, 1}, 8}, - {{4, 5}, 9} - }; - - ASSERT_EQ(unitTestHelper.SortVectorOfPair(actualMST), unitTestHelper.SortVectorOfPair(expectedMST)); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0008_MinimumSpanningTreePrimAlgorithmTest.cc b/tests/0003_Graph/0008_MinimumSpanningTreePrimAlgorithmTest.cc deleted file mode 100644 index a159546..0000000 --- a/tests/0003_Graph/0008_MinimumSpanningTreePrimAlgorithmTest.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include <0003_Graph/0008_MinimumSpanningTreePrimAlgorithm.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace MinimumSpanningTreePrimAlgorithm -{ - UnitTestHelper unitTestHelper; - - TEST(MST, Prim) - { - Graph graph; - - graph.PushUndirectedEdge(1, 2, 4); - graph.PushUndirectedEdge(1, 8, 8); - graph.PushUndirectedEdge(2, 8, 11); - graph.PushUndirectedEdge(2, 3, 8); - graph.PushUndirectedEdge(3, 4, 7); - graph.PushUndirectedEdge(3, 9, 2); - graph.PushUndirectedEdge(3, 6, 4); - graph.PushUndirectedEdge(4, 5, 9); - graph.PushUndirectedEdge(4, 6, 14); - graph.PushUndirectedEdge(5, 6, 10); - graph.PushUndirectedEdge(6, 7, 2); - graph.PushUndirectedEdge(7, 8, 1); - graph.PushUndirectedEdge(7, 9, 6); - graph.PushUndirectedEdge(8, 9, 7); - - graph.FindMinimumSpanningTreePrimAlgorithm(); - - vector, int>> actualMST = graph.GetMinimumSpanningTree(); - vector, int>> expectedMST = - { - {{7, 8}, 1}, - {{3, 9}, 2}, - {{6, 7}, 2}, - {{2, 1}, 4}, - {{3, 6}, 4}, - {{3, 4}, 7}, - {{8, 1}, 8}, - {{4, 5}, 9} - }; - - ASSERT_EQ(unitTestHelper.SortVectorOfPair(actualMST), unitTestHelper.SortVectorOfPair(expectedMST)); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0009_SingleSourceShortestPathBellmanFordTest.cc b/tests/0003_Graph/0009_SingleSourceShortestPathBellmanFordTest.cc deleted file mode 100644 index fa3d41c..0000000 --- a/tests/0003_Graph/0009_SingleSourceShortestPathBellmanFordTest.cc +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include <0003_Graph/0009_SingleSourceShortestPathBellmanFord.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace SingleSourceShortestPathBellmanFord -{ - UnitTestHelper unitTestHelper; - - // Test for Simple Graph - TEST(BellmanFordTest, SimpleTest) - { - Graph graph; - - graph.PushDirectedEdge(0, 1, 6); - graph.PushDirectedEdge(0, 3, 7); - graph.PushDirectedEdge(1, 2, 5); - graph.PushDirectedEdge(1, 3, 8); - graph.PushDirectedEdge(1, 4, -4); - graph.PushDirectedEdge(2, 1, -2); - graph.PushDirectedEdge(3, 2, -3); - graph.PushDirectedEdge(3, 4, 9); - graph.PushDirectedEdge(3, 4, 9); - graph.PushDirectedEdge(4, 2, 7); - graph.PushDirectedEdge(4, 0, 2); - - string expectedResult = "0 3 2 1 4"; - ASSERT_TRUE(graph.FindSingleSourceShortestPathBellmanFord(0)); - ASSERT_EQ(unitTestHelper.SerializeVectorToString(graph.GetShortestPathBellmanFord(4)), expectedResult); - } - - // Test for Single Node Graph - TEST(BellmanFordTest, SingleNodeTest) - { - Graph graph; - graph.PushDirectedEdge(0, 0, 0); // Self-loop - - string expectedResult = "0"; - ASSERT_TRUE(graph.FindSingleSourceShortestPathBellmanFord(0)); - ASSERT_EQ(unitTestHelper.SerializeVectorToString(graph.GetShortestPathBellmanFord(0)), expectedResult); - } - - // Test for Negative Weight Cycle - TEST(BellmanFordTest, NegativeWeightCycleTest) - { - Graph graph; - graph.PushDirectedEdge(0, 1, 1); - graph.PushDirectedEdge(1, 2, -1); - graph.PushDirectedEdge(2, 0, -1); // Negative weight cycle - - ASSERT_FALSE(graph.FindSingleSourceShortestPathBellmanFord(0)); - } - - // Test for Multiple Shortest Paths - TEST(BellmanFordTest, MultipleShortestPathsTest) - { - Graph graph; - graph.PushDirectedEdge(0, 1, 5); - graph.PushDirectedEdge(0, 2, 5); - graph.PushDirectedEdge(1, 3, 1); - graph.PushDirectedEdge(2, 3, 1); - - string expectedResult = "0 1 3"; - ASSERT_TRUE(graph.FindSingleSourceShortestPathBellmanFord(0)); - ASSERT_EQ(unitTestHelper.SerializeVectorToString(graph.GetShortestPathBellmanFord(3)), expectedResult); - } - - // Test for All Negative Weights - TEST(BellmanFordTest, AllNegativeWeightsTest) - { - Graph graph; - graph.PushDirectedEdge(0, 1, -5); - graph.PushDirectedEdge(1, 2, -3); - graph.PushDirectedEdge(2, 3, -2); - graph.PushDirectedEdge(3, 4, -1); - - string expectedResult = "0 1 2 3 4"; - ASSERT_TRUE(graph.FindSingleSourceShortestPathBellmanFord(0)); - ASSERT_EQ(unitTestHelper.SerializeVectorToString(graph.GetShortestPathBellmanFord(4)), expectedResult); - } - - // Test for Large Graph - TEST(BellmanFordTest, LargeGraphTest) - { - Graph graph; - for (int i = 0; i < 100; ++i) { - graph.PushDirectedEdge(i, i + 1, 1); - } - - string expectedResult = "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20"; - ASSERT_TRUE(graph.FindSingleSourceShortestPathBellmanFord(0)); - ASSERT_EQ(unitTestHelper.SerializeVectorToString(graph.GetShortestPathBellmanFord(20)), expectedResult); - } - - // Test for Self-Loop Edge - TEST(BellmanFordTest, SelfLoopTest) - { - Graph graph; - graph.PushDirectedEdge(0, 0, 10); // Self-loop with weight 10 - - string expectedResult = "0"; - ASSERT_TRUE(graph.FindSingleSourceShortestPathBellmanFord(0)); - ASSERT_EQ(unitTestHelper.SerializeVectorToString(graph.GetShortestPathBellmanFord(0)), expectedResult); - } -} diff --git a/tests/0003_Graph/0010_DirectedAcyclicGraphShortestPathTest.cc b/tests/0003_Graph/0010_DirectedAcyclicGraphShortestPathTest.cc deleted file mode 100644 index 8f5da5e..0000000 --- a/tests/0003_Graph/0010_DirectedAcyclicGraphShortestPathTest.cc +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include <0003_Graph/0010_DirectedAcyclicGraphShortestPath.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace DirectedAcyclicGraphShortestPath -{ - UnitTestHelper unitTestHelper; - - // Test for Simple Graph - TEST(DAGTest, SimpleGraph) - { - Graph graph; - - graph.PushDirectedEdge(0, 1, 5); - graph.PushDirectedEdge(0, 2, 3); - graph.PushDirectedEdge(1, 2, 2); - graph.PushDirectedEdge(1, 3, 6); - graph.PushDirectedEdge(2, 3, 7); - graph.PushDirectedEdge(2, 4, 4); - graph.PushDirectedEdge(2, 5, 2); - graph.PushDirectedEdge(3, 4, -1); - graph.PushDirectedEdge(3, 5, 1); - graph.PushDirectedEdge(4, 5, -2); - - graph.FindDAGShortestPath(1); - string expectedPath = "1 3 4 5"; - ASSERT_EQ(unitTestHelper.SerializeVectorToString(graph.GetDAGShortestPath(5)), expectedPath); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0011_SingleSourceShortestPathDijkstraTest.cc b/tests/0003_Graph/0011_SingleSourceShortestPathDijkstraTest.cc deleted file mode 100644 index 01c9012..0000000 --- a/tests/0003_Graph/0011_SingleSourceShortestPathDijkstraTest.cc +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include <0003_Graph/0011_SingleSourceShortestPathDijkstra.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace SingleSourceShortestPathDijkstra -{ - UnitTestHelper unitTestHelper; - - // Test for Simple Graph - TEST(DijkstraTest, SimpleGraph) - { - Graph graph; - - graph.PushDirectedEdge(0, 1, 10); - graph.PushDirectedEdge(0, 3, 5); - graph.PushDirectedEdge(1, 2, 1); - graph.PushDirectedEdge(1, 3, 2); - graph.PushDirectedEdge(2, 4, 4); - graph.PushDirectedEdge(3, 1, 3); - graph.PushDirectedEdge(3, 2, 9); - graph.PushDirectedEdge(3, 4, 2); - graph.PushDirectedEdge(4, 2, 6); - graph.PushDirectedEdge(4, 0, 7); - - graph.FindShortestPathDijkstra(0); - - string expectedPath = "0 3 1 2"; - - ASSERT_EQ(unitTestHelper.SerializeVectorToString(graph.GetDijkstraShortestPath(2)), expectedPath); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0013_AllPairsShortestPathsFloydWarshallTest.cc b/tests/0003_Graph/0013_AllPairsShortestPathsFloydWarshallTest.cc deleted file mode 100644 index 8efada0..0000000 --- a/tests/0003_Graph/0013_AllPairsShortestPathsFloydWarshallTest.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include <0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h> -#include"../0000_CommonUtilities/UnitTestHelper.h" -using namespace std; - -namespace AllPairsShortestPathsFloydWarshall -{ - UnitTestHelper unitTestHelper; - - TEST(FloydWarshall, SimpleGraph) - { - // Arrange - Graph graph; - int noOfVertices = 5; - string expectedResult = "[1 5 4 3 2][1 5 4 3][1 5 4][1 5][2 4 1][2 4 3][2 4][2 4 1 5][3 2 4 1][3 2][3 2 4][3 2 4 1 5][4 1][4 3 2][4 3][4 1 5][5 4 1][5 4 3 2][5 4 3][5 4]"; - - // Act - graph.CreateGraph(noOfVertices); - - graph.PushDirectedEdge(1, 2, 3); - graph.PushDirectedEdge(1, 3, 8); - graph.PushDirectedEdge(1, 5, -4); - graph.PushDirectedEdge(2, 4, 1); - graph.PushDirectedEdge(2, 5, 7); - graph.PushDirectedEdge(3, 2, 4); - graph.PushDirectedEdge(4, 3, -5); - graph.PushDirectedEdge(4, 1, 2); - graph.PushDirectedEdge(5, 4, 6); - - graph.FindAllPairsShortestPathsFloydWarshallSolution(); - string actualResult = unitTestHelper.SerializeVectorToString(graph.GetFloydWarshallShortestPath()); - - // Assert - ASSERT_EQ(actualResult, expectedResult); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0014_AllPairsShortestPathsJohnsonTest.cc b/tests/0003_Graph/0014_AllPairsShortestPathsJohnsonTest.cc deleted file mode 100644 index 8f5a84b..0000000 --- a/tests/0003_Graph/0014_AllPairsShortestPathsJohnsonTest.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include <0003_Graph/0014_AllPairsShortestPathsJohnson.h> -#include"../0000_CommonUtilities/UnitTestHelper.h" -using namespace std; - -namespace AllPairsShortestPathsJohnson -{ - UnitTestHelper unitTestHelper; - - TEST(JohnsonAlgorithm, SimpleGraph) - { - // Arrange - Graph graph; - vector> expectedDistanceMatrix = - { - {0, 1, -3, 2, -4}, - {3, 0, -4, 1, -1}, - {7, 4, 0, 5, 3}, - {2, -1, -5, 0, -2}, - {8, 5, 1, 6, 0}, - }; - string expectedPredecessorMatrixesult = "[1 5 4 3 2][1 5 4 3][1 5 4][1 5][2 4 1][2 4 3][2 4][2 4 1 5][3 2 4 1][3 2][3 2 4][3 2 4 1 5][4 1][4 3 2][4 3][4 1 5][5 4 1][5 4 3 2][5 4 3][5 4]"; - - // Act - graph.PushDirectedEdge(1, 2, 3); - graph.PushDirectedEdge(1, 3, 8); - graph.PushDirectedEdge(1, 5, -4); - graph.PushDirectedEdge(2, 4, 1); - graph.PushDirectedEdge(2, 5, 7); - graph.PushDirectedEdge(3, 2, 4); - graph.PushDirectedEdge(4, 3, -5); - graph.PushDirectedEdge(4, 1, 2); - graph.PushDirectedEdge(5, 4, 6); - - bool result = graph.FindAllPairsShortestPathsJohnsonAlgorithm(); - vector> actualDistanceMatrix = graph.GetAllPairsShortestPathsDistanceMatrix(); - string actualPredecessorMatrix = unitTestHelper.SerializeVectorToString(graph.GetAllPairsShortestPathsPathMatrix()); - - // Assert - ASSERT_TRUE(result); - ASSERT_EQ(expectedDistanceMatrix, actualDistanceMatrix); - ASSERT_EQ(expectedPredecessorMatrixesult, actualPredecessorMatrix); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0015_MaximumFlowFordFulkersonTest.cc b/tests/0003_Graph/0015_MaximumFlowFordFulkersonTest.cc deleted file mode 100644 index bd864e5..0000000 --- a/tests/0003_Graph/0015_MaximumFlowFordFulkersonTest.cc +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include <0003_Graph/0015_MaximumFlowFordFulkerson.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace MaximumFlowFordFulkerson -{ - UnitTestHelper unitTestHelper; - - TEST(MaximumFlowFordFulkerson, GraphWithNoParallelEdges) - { - // Arrange - Graph graph; - int noOfVertices = 6; - int expectedMaximumFlow = 23; - - - // Act - graph.CreateGraph(noOfVertices); - - graph.PushDirectedEdge(0, 1, 16); - graph.PushDirectedEdge(0, 2, 13); - graph.PushDirectedEdge(1, 3, 12); - graph.PushDirectedEdge(2, 1, 4); - graph.PushDirectedEdge(2, 4, 14); - graph.PushDirectedEdge(3, 2, 9); - graph.PushDirectedEdge(3, 5, 20); - graph.PushDirectedEdge(4, 3, 7); - graph.PushDirectedEdge(4, 5, 4); - - int actualMaximumFlow = graph.FindMaximumFlowFordFulkerson(); - - // Assert - ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); - } - - TEST(MaximumFlowFordFulkerson, GraphWithParallelEdges) - { - // Arrange - Graph graph; - int noOfVertices = 6; - int expectedMaximumFlow = 24; - - - // Act - graph.CreateGraph(noOfVertices); - - graph.PushDirectedEdge(0, 1, 16); - graph.PushDirectedEdge(0, 2, 13); - graph.PushDirectedEdge(1, 3, 12); - graph.PushDirectedEdge(1, 2, 6); - graph.PushDirectedEdge(2, 1, 10); - graph.PushDirectedEdge(2, 4, 14); - graph.PushDirectedEdge(2, 3, 2); - graph.PushDirectedEdge(3, 2, 11); - graph.PushDirectedEdge(3, 5, 20); - graph.PushDirectedEdge(4, 3, 7); - graph.PushDirectedEdge(4, 5, 4); - - int actualMaximumFlow = graph.FindMaximumFlowFordFulkerson(); - - // Assert - ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0016_MaximumFlowEdmondsKarpTest.cc b/tests/0003_Graph/0016_MaximumFlowEdmondsKarpTest.cc deleted file mode 100644 index c9d8175..0000000 --- a/tests/0003_Graph/0016_MaximumFlowEdmondsKarpTest.cc +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include <0003_Graph/0016_MaximumFlowEdmondsKarp.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace MaximumFlowEdmondsKarp -{ - UnitTestHelper unitTestHelper; - - TEST(MaximumFlowEdmondsKarp, GraphWithNoParallelEdges) - { - // Arrange - Graph graph; - int noOfVertices = 6; - int expectedMaximumFlow = 23; - - - // Act - graph.CreateGraph(noOfVertices); - - graph.PushDirectedEdge(0, 1, 16); - graph.PushDirectedEdge(0, 2, 13); - graph.PushDirectedEdge(1, 3, 12); - graph.PushDirectedEdge(2, 1, 4); - graph.PushDirectedEdge(2, 4, 14); - graph.PushDirectedEdge(3, 2, 9); - graph.PushDirectedEdge(3, 5, 20); - graph.PushDirectedEdge(4, 3, 7); - graph.PushDirectedEdge(4, 5, 4); - - int actualMaximumFlow = graph.FindMaximumFlowEdmondsKarp(); - - // Assert - ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); - } - - TEST(MaximumFlowEdmondsKarp, GraphWithParallelEdges) - { - // Arrange - Graph graph; - int noOfVertices = 6; - int expectedMaximumFlow = 24; - - - // Act - graph.CreateGraph(noOfVertices); - - graph.PushDirectedEdge(0, 1, 16); - graph.PushDirectedEdge(0, 2, 13); - graph.PushDirectedEdge(1, 3, 12); - graph.PushDirectedEdge(1, 2, 6); - graph.PushDirectedEdge(2, 1, 10); - graph.PushDirectedEdge(2, 4, 14); - graph.PushDirectedEdge(2, 3, 2); - graph.PushDirectedEdge(3, 2, 11); - graph.PushDirectedEdge(3, 5, 20); - graph.PushDirectedEdge(4, 3, 7); - graph.PushDirectedEdge(4, 5, 4); - - int actualMaximumFlow = graph.FindMaximumFlowEdmondsKarp(); - - // Assert - ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0017_MaximumBipartiteMatchingTest.cc b/tests/0003_Graph/0017_MaximumBipartiteMatchingTest.cc deleted file mode 100644 index 0149332..0000000 --- a/tests/0003_Graph/0017_MaximumBipartiteMatchingTest.cc +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include <0003_Graph/0017_MaximumBipartiteMatching.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace MaximumBipartiteMatching -{ - TEST(MaximumBipartiteMatching, SimpleGraph) - { - // Arrange - Graph graph; - UnitTestHelper unitTestHelper; - int noOfVertices = 9; - int expectedMaximumMatching = 3; - string expectedMatchings = "[0 1][2 6][3 5]"; - - // Act - graph.CreateGraph(noOfVertices); - - graph.PushDirectedEdge(0, 1); - graph.PushDirectedEdge(2, 1); - graph.PushDirectedEdge(2, 6); - graph.PushDirectedEdge(3, 5); - graph.PushDirectedEdge(3, 6); - graph.PushDirectedEdge(3, 7); - graph.PushDirectedEdge(4, 6); - graph.PushDirectedEdge(8, 6); - - int actualMaximumMatching = graph.FindMaximumBipartiteMatching(); - vector> actualMatchings = graph.GetMatchings(); - - // Assert - ASSERT_EQ(expectedMaximumMatching, actualMaximumMatching); - ASSERT_EQ(expectedMatchings, unitTestHelper.SerializeVectorToString(actualMatchings)); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabelTest.cc b/tests/0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabelTest.cc deleted file mode 100644 index 814ed74..0000000 --- a/tests/0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabelTest.cc +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include <0003_Graph/0018_MaximumFlowGoldbergGenericPushRelabel.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" - -namespace MaximumFlowGoldbergGenericPushRelabel -{ - UnitTestHelper unitTestHelper; - - TEST(MaximumFlowGoldbergGenericPushRelabel, GraphWithNoParallelEdges) - { - // Arrange - Graph graph; - int noOfVertices = 6; - int expectedMaximumFlow = 23; - - - // Act - graph.CreateGraph(noOfVertices); - - graph.PushDirectedEdge(0, 1, 16); - graph.PushDirectedEdge(0, 2, 13); - graph.PushDirectedEdge(1, 3, 12); - graph.PushDirectedEdge(2, 1, 4); - graph.PushDirectedEdge(2, 4, 14); - graph.PushDirectedEdge(3, 2, 9); - graph.PushDirectedEdge(3, 5, 20); - graph.PushDirectedEdge(4, 3, 7); - graph.PushDirectedEdge(4, 5, 4); - - int actualMaximumFlow = graph.FindMaximumFlowGoldbergGenericPushRelabel(); - - // Assert - ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/0019_MaximumFlowRelabelToFrontTest.cc b/tests/0003_Graph/0019_MaximumFlowRelabelToFrontTest.cc deleted file mode 100644 index bbd3e4b..0000000 --- a/tests/0003_Graph/0019_MaximumFlowRelabelToFrontTest.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include <0003_Graph/0019_MaximumFlowRelabelToFront.h> -#include "../0000_CommonUtilities/UnitTestHelper.h" -using namespace std; - -namespace MaximumFlowRelabelToFront -{ - UnitTestHelper unitTestHelper; - - TEST(MaximumFlowRelabelToFront, SimpleGraph) - { - // Arrange - Graph graph; - int noOfVertices = 6; - int expectedMaximumFlow = 23; - - - // Act - graph.CreateGraph(noOfVertices); - - graph.PushDirectedEdge(0, 1, 16); - graph.PushDirectedEdge(0, 2, 13); - graph.PushDirectedEdge(1, 3, 12); - graph.PushDirectedEdge(2, 1, 4); - graph.PushDirectedEdge(2, 4, 14); - graph.PushDirectedEdge(3, 2, 9); - graph.PushDirectedEdge(3, 5, 20); - graph.PushDirectedEdge(4, 3, 7); - graph.PushDirectedEdge(4, 5, 4); - - int actualMaximumFlow = graph.FindMaximumFlowRelabelToFront(); - - // Assert - ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); - } -} \ No newline at end of file diff --git a/tests/0003_Graph/CMakeLists.txt b/tests/0003_Graph/CMakeLists.txt deleted file mode 100644 index 275d4a8..0000000 --- a/tests/0003_Graph/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -cmake_policy(SET CMP0135 NEW) - -include(FetchContent) -FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip -) - -# For Windows: Prevent overriding the parent project's compiler/linker settings -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -FetchContent_MakeAvailable(googletest) - -enable_testing() - -add_executable( - 0003GraphTests - 0001_BreadthFirstSearchTest.cc - 0002_DepthFirstSearchTest.cc - 0003_TopologicalSortTest.cc - 0004_StronglyConnectedComponentsTest.cc - 0005_HamiltonianPathAndCycleTest.cc - 0006_EulerianPathAndCircuitTest.cc - 0007_MinimumSpanningTreeKruskalAlgorithmTest.cc - 0008_MinimumSpanningTreePrimAlgorithmTest.cc - 0009_SingleSourceShortestPathBellmanFordTest.cc - 0010_DirectedAcyclicGraphShortestPathTest.cc - 0011_SingleSourceShortestPathDijkstraTest.cc - 0012_DifferenceConstraintsShortestPathsTest.cc - 0013_AllPairsShortestPathsFloydWarshallTest.cc - 0014_AllPairsShortestPathsJohnsonTest.cc - 0015_MaximumFlowFordFulkersonTest.cc - 0016_MaximumFlowEdmondsKarpTest.cc - 0017_MaximumBipartiteMatchingTest.cc - 0018_MaximumFlowGoldbergGenericPushRelabelTest.cc - 0019_MaximumFlowRelabelToFrontTest.cc -) - -target_link_libraries( - 0003GraphTests - GTest::gtest_main - 0003GRAPH -) - -# Add .clang-tidy configuration to this library. -if(CLANG_TIDY_EXE) - set_target_properties(0003GRAPH PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") -endif() - -include(GoogleTest) -gtest_discover_tests(0003GraphTests DISCOVERY_TIMEOUT 30) \ No newline at end of file diff --git a/tests/0003_graph/0001_breadth_first_search_test.cc b/tests/0003_graph/0001_breadth_first_search_test.cc new file mode 100644 index 0000000..9c095da --- /dev/null +++ b/tests/0003_graph/0001_breadth_first_search_test.cc @@ -0,0 +1,45 @@ +#include +#include +#include "../../src/0003_graph/headers/0001_breadth_first_search.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::breadth_first_search +{ + UnitTestHelper unitTestHelper; + + + TEST(breadthFirstSearch, showBFSResultTest01) + { + Graph graph; + + graph.pushUndirectedEdge(1, 2); + graph.pushUndirectedEdge(1, 3); + graph.pushUndirectedEdge(2, 4); + graph.pushUndirectedEdge(3, 5); + graph.pushUndirectedEdge(3, 6); + graph.pushUndirectedEdge(5, 6); + graph.pushUndirectedEdge(5, 7); + graph.pushUndirectedEdge(6, 7); + graph.pushUndirectedEdge(6, 8); + graph.pushUndirectedEdge(7, 8); + + graph.bfs(1); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showBFSResult()); + string expectedResult = "1(0) 2(1) 3(1) 4(2) 5(2) 6(2) 7(3) 8(3)"; + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(breadthFirstSearch, showBFSResultTest02) + { + Graph graph; + + graph.pushUndirectedEdge(1, 2); + + graph.bfs(1); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showBFSResult()); + string expectedResult = "1(0) 2(1)"; + EXPECT_EQ(actualResult, expectedResult); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0002_depth_first_search_test.cc b/tests/0003_graph/0002_depth_first_search_test.cc new file mode 100644 index 0000000..4678867 --- /dev/null +++ b/tests/0003_graph/0002_depth_first_search_test.cc @@ -0,0 +1,177 @@ +#include +#include "0002_depth_first_search.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::depth_first_search +{ + UnitTestHelper unitTestHelper; + + TEST(depthFirstSearch, showDFSResultTest01) + { + Graph graph; + + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(1, 4); + graph.pushDirectedEdge(2, 5); + graph.pushDirectedEdge(3, 5); + graph.pushDirectedEdge(3, 6); + graph.pushDirectedEdge(4, 2); + graph.pushDirectedEdge(5, 4); + graph.pushDirectedEdge(6, 6); + + graph.dfs(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showDFSResult()); + string expectedResult = "1(1,8) 2(2,7) 3(9,12) 4(4,5) 5(3,6) 6(10,11)"; + EXPECT_EQ(actualResult, expectedResult); + } + + + TEST(depthFirstSearch, showDFSResultTestSingleVertex) + { + Graph graph; + + graph.pushDirectedEdge(1, 1); + + graph.dfs(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showDFSResult()); + string expectedResult = "1(1,2)"; + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(depthFirstSearch, showDFSResultTestDisconnectedGraph) + { + Graph graph; + + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(3, 4); + + graph.dfs(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showDFSResult()); + string expectedResult = "1(1,4) 2(2,3) 3(5,8) 4(6,7)"; + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(depthFirstSearch, showDFSResultTestCyclicGraph) + { + Graph graph; + + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(3, 1); + + graph.dfs(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showDFSResult()); + string expectedResult = "1(1,6) 2(2,5) 3(3,4)"; + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(depthFirstSearch, showDFSResultTestLargeGraph) + { + Graph graph; + + // adding 15 nodes with several edges + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(1, 3); + graph.pushDirectedEdge(2, 4); + graph.pushDirectedEdge(4, 5); + graph.pushDirectedEdge(5, 6); + graph.pushDirectedEdge(6, 7); + graph.pushDirectedEdge(7, 8); + graph.pushDirectedEdge(8, 9); + graph.pushDirectedEdge(9, 10); + graph.pushDirectedEdge(10, 11); + graph.pushDirectedEdge(11, 12); + graph.pushDirectedEdge(12, 13); + graph.pushDirectedEdge(13, 14); + graph.pushDirectedEdge(14, 15); + graph.pushDirectedEdge(15, 16); + + graph.dfs(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showDFSResult()); + string expectedResult = "1(1,32) 2(2,29) 3(30,31) 4(3,28) 5(4,27) 6(5,26) 7(6,25) 8(7,24) 9(8,23) 10(9,22) 11(10,21) 12(11,20) 13(12,19) 14(13,18) 15(14,17) 16(15,16)"; + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(depthFirstSearch, showDFSResultTestNoEdges) + { + Graph graph; + + // adding isolated nodes + graph.pushDirectedEdge(1, 1); + graph.pushDirectedEdge(2, 2); + graph.pushDirectedEdge(3, 3); + + graph.dfs(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showDFSResult()); + string expectedResult = "1(1,2) 2(3,4) 3(5,6)"; + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(depthFirstSearch, showDFSResultTest_CyclicGraphWithBackEdges) + { + Graph graph; + + // creating a cycle with back edges + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(3, 1); // cycle back to 'a' + graph.pushDirectedEdge(2, 4); // back edge + + graph.dfs(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showDFSResult()); + string expectedResult = "1(1,8) 2(2,7) 3(3,4) 4(5,6)"; + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(depthFirstSearch, showDFSResultTestDenseGraph) + { + Graph graph; + + // complete graph of 4 nodes + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(1, 3); + graph.pushDirectedEdge(1, 4); + graph.pushDirectedEdge(2, 1); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(2, 4); + graph.pushDirectedEdge(3, 1); + graph.pushDirectedEdge(3, 2); + graph.pushDirectedEdge(3, 4); + graph.pushDirectedEdge(4, 1); + graph.pushDirectedEdge(4, 2); + graph.pushDirectedEdge(4, 3); + + graph.dfs(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showDFSResult()); + string expectedResult = "1(1,8) 2(2,7) 3(3,6) 4(4,5)"; + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(depthFirstSearch, showDFSResultTestSelfLoopsAndParallelEdges) + { + Graph graph; + + // adding self-loops and parallel edges + graph.pushDirectedEdge(1, 1); + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(2, 2); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(2, 3); // parallel edge + graph.pushDirectedEdge(3, 3); // self-loop + + graph.dfs(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showDFSResult()); + string expectedResult = "1(1,6) 2(2,5) 3(3,4)"; + EXPECT_EQ(actualResult, expectedResult); + } + +} \ No newline at end of file diff --git a/tests/0003_graph/0003_topological_sort_test.cc b/tests/0003_graph/0003_topological_sort_test.cc new file mode 100644 index 0000000..911e3c9 --- /dev/null +++ b/tests/0003_graph/0003_topological_sort_test.cc @@ -0,0 +1,116 @@ +#include +#include "0003_topological_sort.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::topological_sort +{ + UnitTestHelper unitTestHelper; + + TEST(topoSortTesting, showTopoSortResult) + { + Graph graph; + + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(1, 4); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(4, 3); + graph.pushSingleNode(5); + graph.pushDirectedEdge(6, 7); + graph.pushDirectedEdge(6, 8); + graph.pushDirectedEdge(7, 4); + graph.pushDirectedEdge(7, 8); + graph.pushDirectedEdge(9, 8); + + graph.topologicalSort(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showTopologicalSortResult()); + string expectedResult = "9(17,18) 6(11,16) 7(12,15) 8(13,14) 5(9,10) 1(1,8) 4(6,7) 2(2,5) 3(3,4)"; + + EXPECT_EQ(actualResult, expectedResult); + } + + // Test with a larger graph and multiple paths between nodes + TEST(topoSortTesting, largeGraphMultiplePaths) + { + Graph graph; + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(1, 3); + graph.pushDirectedEdge(2, 4); + graph.pushDirectedEdge(3, 4); + graph.pushDirectedEdge(4, 5); + graph.pushDirectedEdge(5, 6); + graph.pushDirectedEdge(6, 7); + + graph.topologicalSort(); + string actualResult = unitTestHelper.serializeVectorToString(graph.showTopologicalSortResult()); + string expectedResult = "1(1,14) 3(12,13) 2(2,11) 4(3,10) 5(4,9) 6(5,8) 7(6,7)"; + + EXPECT_EQ(actualResult, expectedResult); + } + + // Test with a graph containing disconnected components + TEST(topoSortTesting, disconnectedGraph) + { + Graph graph; + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(3, 4); + graph.pushDirectedEdge(5, 6); + + graph.topologicalSort(); + string actualResult = unitTestHelper.serializeVectorToString(graph.showTopologicalSortResult()); + string expectedResult = "5(9,12) 6(10,11) 3(5,8) 4(6,7) 1(1,4) 2(2,3)"; + + EXPECT_EQ(actualResult, expectedResult); + } + + // Test with a graph that has multiple nodes pointing to the same node + TEST(topoSortTesting, multipleIncomingEdges) + { + Graph graph; + graph.pushDirectedEdge(1, 3); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(3, 4); + + graph.topologicalSort(); + string actualResult = unitTestHelper.serializeVectorToString(graph.showTopologicalSortResult()); + string expectedResult = "2(7,8) 1(1,6) 3(2,5) 4(3,4)"; + + EXPECT_EQ(actualResult, expectedResult); + } + + // Test for a single-node graph to check the base case + TEST(topoSortTesting, singleNodeGraph) + { + Graph graph; + graph.pushSingleNode(1); + + graph.topologicalSort(); + string actualResult = unitTestHelper.serializeVectorToString(graph.showTopologicalSortResult()); + string expectedResult = "1(1,2)"; + + EXPECT_EQ(actualResult, expectedResult); + } + + TEST(topoSortTesting, showTopoSortResultUsingKahnAlgorithm) + { + Graph graph; + + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(1, 4); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(4, 3); + graph.pushSingleNode(5); + graph.pushDirectedEdge(6, 7); + graph.pushDirectedEdge(6, 8); + graph.pushDirectedEdge(7, 4); + graph.pushDirectedEdge(7, 8); + graph.pushDirectedEdge(9, 8); + + graph.kahnTopologicalSort(); + + string actualResult = unitTestHelper.serializeVectorToString(graph.showTopologicalSortResult()); + string expectedResult = "1(1,5) 5(2,7) 6(3,8) 9(4,10) 2(6,11) 7(9,12) 4(13,15) 8(14,17) 3(16,18)"; + + EXPECT_EQ(actualResult, expectedResult); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0004_strongly_connected_components_test.cc b/tests/0003_graph/0004_strongly_connected_components_test.cc new file mode 100644 index 0000000..00e0ee5 --- /dev/null +++ b/tests/0003_graph/0004_strongly_connected_components_test.cc @@ -0,0 +1,102 @@ +#include +#include "0004_strongly_connected_components.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::strongly_connected_components +{ + UnitTestHelper unitTestHelper; + + // Test case: testing with a simple graph. + TEST(stronglyConnectedComponentsTesting, simpleGraphTest) + { + Graph graph; + + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(1, 5); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(2, 4); + graph.pushDirectedEdge(3, 2); + graph.pushDirectedEdge(4, 4); + graph.pushDirectedEdge(5, 1); + graph.pushDirectedEdge(5, 4); + graph.pushDirectedEdge(6, 1); + graph.pushDirectedEdge(6, 3); + graph.pushDirectedEdge(6, 7); + graph.pushDirectedEdge(7, 3); + graph.pushDirectedEdge(7, 8); + graph.pushDirectedEdge(8, 6); + + auto actualResult = graph.findAllStronglyConnectedComponents(); + vector> expectedResult = { {6, 8, 7},{1, 5},{2, 3},{4} }; + EXPECT_EQ(unitTestHelper.sortVectorOfVectors(actualResult), unitTestHelper.sortVectorOfVectors(expectedResult)); + } + + // Test case: single Node. + TEST(stronglyConnectedComponentsTesting, singleNodeTest) + { + Graph graph; + graph.pushSingleNode(1); + + auto actualResult = graph.findAllStronglyConnectedComponents(); + vector> expectedResult = { {1} }; + EXPECT_EQ(unitTestHelper.sortVectorOfVectors(actualResult), unitTestHelper.sortVectorOfVectors(expectedResult)); + } + + // Test case: disconnected Graph. + TEST(stronglyConnectedComponentsTesting, disconnectedGraphTest) + { + Graph graph; + graph.pushSingleNode(1); + graph.pushSingleNode(2); + graph.pushSingleNode(3); + + auto actualResult = graph.findAllStronglyConnectedComponents(); + vector> expectedResult = { {1},{3},{2} }; + EXPECT_EQ(unitTestHelper.sortVectorOfVectors(actualResult), unitTestHelper.sortVectorOfVectors(expectedResult)); + } + + // Test case: chain of nodes. + TEST(stronglyConnectedComponentsTesting, chainOfNodesTest) + { + Graph graph; + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(3, 4); + + auto actualResult = graph.findAllStronglyConnectedComponents(); + vector> expectedResult = { {2},{1},{3},{4} }; + EXPECT_EQ(unitTestHelper.sortVectorOfVectors(actualResult), unitTestHelper.sortVectorOfVectors(expectedResult)); + } + + // Test case: bidirectional Edge. + TEST(stronglyConnectedComponentsTesting, bidirectionalEdgeTest) + { + Graph graph; + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(2, 1); + + auto actualResult = graph.findAllStronglyConnectedComponents(); + vector> expectedResult = { {2, 1} }; + EXPECT_EQ(unitTestHelper.sortVectorOfVectors(actualResult), unitTestHelper.sortVectorOfVectors(expectedResult)); + } + + // Test case: complex Graph. + TEST(stronglyConnectedComponentsTesting, complexGraphTest) + { + Graph graph; + + // Graph structure with multiple sCCs and isolated nodes. + graph.pushDirectedEdge(1, 2); + graph.pushDirectedEdge(2, 3); + graph.pushDirectedEdge(3, 1); // cycle: 1 -> 2 -> 3 -> 1 + graph.pushDirectedEdge(4, 5); + graph.pushDirectedEdge(5, 6); + graph.pushDirectedEdge(6, 4); // cycle: 4 -> 5 -> 6 -> 4 + graph.pushDirectedEdge(7, 8); // single direction: 7 -> 8 + graph.pushSingleNode(9); // isolated node. + + auto actualResult = graph.findAllStronglyConnectedComponents(); + vector> expectedResult = { {4, 6, 5},{7}, { 2, 3, 1},{8}, {9} }; + EXPECT_EQ(unitTestHelper.sortVectorOfVectors(actualResult), unitTestHelper.sortVectorOfVectors(expectedResult)); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0005_hamiltonian_path_and_cycle_test.cc b/tests/0003_graph/0005_hamiltonian_path_and_cycle_test.cc new file mode 100644 index 0000000..3ce1b50 --- /dev/null +++ b/tests/0003_graph/0005_hamiltonian_path_and_cycle_test.cc @@ -0,0 +1,33 @@ +#include +#include "0005_hamiltonian_path_and_cycle.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::hamiltonian_path_and_cycle +{ + UnitTestHelper unitTestHelper; + + TEST(hamiltonianCycleAndPathTest, showResult) + { + Graph graph; + + graph.pushUndirectedEdge(0, 1); + graph.pushUndirectedEdge(0, 3); + graph.pushUndirectedEdge(1, 2); + graph.pushUndirectedEdge(1, 3); + graph.pushUndirectedEdge(1, 4); + graph.pushUndirectedEdge(2, 4); + graph.pushUndirectedEdge(3, 4); + + graph.findHamiltonianCycleAndPath(); + + bool isHamiltonianCyclePresent = graph.isHamiltonianCyclePresent(); + bool isHamiltonianPathPresent = graph.isHamiltonianPathPresent(); + + vector hamiltonianPathActualResult = graph.getHamiltonianPath(); + vector hamiltonianPathExpectedResult = { 4, 3, 0, 1, 2 }; + + ASSERT_TRUE(isHamiltonianCyclePresent); + ASSERT_TRUE(isHamiltonianPathPresent); + ASSERT_TRUE(unitTestHelper.normalizeCyclesAndCompare(hamiltonianPathActualResult, hamiltonianPathExpectedResult)); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0006_eulerian_path_and_circuit_test.cc b/tests/0003_graph/0006_eulerian_path_and_circuit_test.cc new file mode 100644 index 0000000..351df33 --- /dev/null +++ b/tests/0003_graph/0006_eulerian_path_and_circuit_test.cc @@ -0,0 +1,32 @@ +#include +#include "0006_eulerian_path_and_circuit.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::eulerian_path_and_circuit +{ + UnitTestHelper unitTestHelper; + + TEST(eulerianPathAndCycle, test1) + { + Graph graph; + + graph.pushUndirectedEdge(1, 0); + graph.pushUndirectedEdge(0, 2); + graph.pushUndirectedEdge(2, 1); + graph.pushUndirectedEdge(0, 3); + graph.pushUndirectedEdge(3, 4); + graph.pushUndirectedEdge(4, 0); + + graph.findEulerianPathAndCircuit(); + + bool isEulerianPathPresent = graph.isEulerianPathPresent(); + bool isEulerianCircuitPresent = graph.isEulerianCircuitPresent(); + + vector actualEulerianPath = graph.undirectedGraphGetEulerianPath(); + vector expectedEulerianPath = { 0, 1, 2, 0, 3, 4, 0}; + + ASSERT_TRUE(isEulerianPathPresent); + ASSERT_TRUE(isEulerianCircuitPresent); + EXPECT_EQ(expectedEulerianPath, actualEulerianPath); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0007_minimum_spanning_tree_kruskal_algorithm_test.cc b/tests/0003_graph/0007_minimum_spanning_tree_kruskal_algorithm_test.cc new file mode 100644 index 0000000..2b71270 --- /dev/null +++ b/tests/0003_graph/0007_minimum_spanning_tree_kruskal_algorithm_test.cc @@ -0,0 +1,45 @@ +#include +#include "0007_minimum_spanning_tree_kruskal_algorithm.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::minimum_spanning_tree_kruskal_algorithm +{ + UnitTestHelper unitTestHelper; + + TEST(minimumSpanningTreeKruskal, getMinimumSpanningTreeKruskal) + { + Graph graph; + + graph.pushUndirectedEdge(1, 2, 4); + graph.pushUndirectedEdge(1, 8, 8); + graph.pushUndirectedEdge(2, 8, 11); + graph.pushUndirectedEdge(2, 3, 8); + graph.pushUndirectedEdge(3, 4, 7); + graph.pushUndirectedEdge(3, 9, 2); + graph.pushUndirectedEdge(3, 6, 4); + graph.pushUndirectedEdge(4, 5, 9); + graph.pushUndirectedEdge(4, 6, 14); + graph.pushUndirectedEdge(5, 6, 10); + graph.pushUndirectedEdge(6, 7, 2); + graph.pushUndirectedEdge(7, 8, 1); + graph.pushUndirectedEdge(7, 9, 6); + graph.pushUndirectedEdge(8, 9, 7); + + graph.findMinimumSpanningTreeKruskalAlgorithm(); + + vector, int>> actualMST = graph.getMinimumSpanningTree(); + vector, int>> expectedMST = + { + {{7, 8}, 1}, + {{3, 9}, 2}, + {{6, 7}, 2}, + {{2, 1}, 4}, + {{3, 6}, 4}, + {{3, 4}, 7}, + {{8, 1}, 8}, + {{4, 5}, 9} + }; + + ASSERT_EQ(unitTestHelper.sortVectorOfPair(actualMST), unitTestHelper.sortVectorOfPair(expectedMST)); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0008_minimum_spanning_tree_prim_algorithm_test.cc b/tests/0003_graph/0008_minimum_spanning_tree_prim_algorithm_test.cc new file mode 100644 index 0000000..6adb394 --- /dev/null +++ b/tests/0003_graph/0008_minimum_spanning_tree_prim_algorithm_test.cc @@ -0,0 +1,45 @@ +#include +#include "0008_minimum_spanning_tree_prim_algorithm.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::minimum_spanning_tree_prim_algorithm +{ + UnitTestHelper unitTestHelper; + + TEST(minimumSpanningTreePrim, getMinimumSpanningTreePrim) + { + Graph graph; + + graph.pushUndirectedEdge(1, 2, 4); + graph.pushUndirectedEdge(1, 8, 8); + graph.pushUndirectedEdge(2, 8, 11); + graph.pushUndirectedEdge(2, 3, 8); + graph.pushUndirectedEdge(3, 4, 7); + graph.pushUndirectedEdge(3, 9, 2); + graph.pushUndirectedEdge(3, 6, 4); + graph.pushUndirectedEdge(4, 5, 9); + graph.pushUndirectedEdge(4, 6, 14); + graph.pushUndirectedEdge(5, 6, 10); + graph.pushUndirectedEdge(6, 7, 2); + graph.pushUndirectedEdge(7, 8, 1); + graph.pushUndirectedEdge(7, 9, 6); + graph.pushUndirectedEdge(8, 9, 7); + + graph.findMinimumSpanningTreePrimAlgorithm(); + + vector, int>> actualMST = graph.getMinimumSpanningTree(); + vector, int>> expectedMST = + { + {{7, 8}, 1}, + {{3, 9}, 2}, + {{6, 7}, 2}, + {{2, 1}, 4}, + {{3, 6}, 4}, + {{3, 4}, 7}, + {{8, 1}, 8}, + {{4, 5}, 9} + }; + + ASSERT_EQ(unitTestHelper.sortVectorOfPair(actualMST), unitTestHelper.sortVectorOfPair(expectedMST)); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0009_single_source_shortest_path_bellman_ford_test.cc b/tests/0003_graph/0009_single_source_shortest_path_bellman_ford_test.cc new file mode 100644 index 0000000..cefa263 --- /dev/null +++ b/tests/0003_graph/0009_single_source_shortest_path_bellman_ford_test.cc @@ -0,0 +1,104 @@ +#include +#include "0009_single_source_shortest_path_bellman_ford.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::single_source_shortest_path_bellman_ford +{ + UnitTestHelper unitTestHelper; + + // Test for simple Graph + TEST(bellmanFordTest, simpleTest) + { + Graph graph; + + graph.pushDirectedEdge(0, 1, 6); + graph.pushDirectedEdge(0, 3, 7); + graph.pushDirectedEdge(1, 2, 5); + graph.pushDirectedEdge(1, 3, 8); + graph.pushDirectedEdge(1, 4, -4); + graph.pushDirectedEdge(2, 1, -2); + graph.pushDirectedEdge(3, 2, -3); + graph.pushDirectedEdge(3, 4, 9); + graph.pushDirectedEdge(3, 4, 9); + graph.pushDirectedEdge(4, 2, 7); + graph.pushDirectedEdge(4, 0, 2); + + string expectedResult = "0 3 2 1 4"; + ASSERT_TRUE(graph.findSingleSourceShortestPathBellmanFord(0)); + ASSERT_EQ(unitTestHelper.serializeVectorToString(graph.getShortestPathBellmanFord(4)), expectedResult); + } + + // Test for single Node Graph + TEST(bellmanFordTest, singleNodeTest) + { + Graph graph; + graph.pushDirectedEdge(0, 0, 0); // self-loop + + string expectedResult = "0"; + ASSERT_TRUE(graph.findSingleSourceShortestPathBellmanFord(0)); + ASSERT_EQ(unitTestHelper.serializeVectorToString(graph.getShortestPathBellmanFord(0)), expectedResult); + } + + // Test for negative weight cycle + TEST(bellmanFordTest, negativeWeightCycleTest) + { + Graph graph; + graph.pushDirectedEdge(0, 1, 1); + graph.pushDirectedEdge(1, 2, -1); + graph.pushDirectedEdge(2, 0, -1); // negative weight cycle + + ASSERT_FALSE(graph.findSingleSourceShortestPathBellmanFord(0)); + } + + // Test for multiple shortest paths + TEST(bellmanFordTest, multipleShortestPathsTest) + { + Graph graph; + graph.pushDirectedEdge(0, 1, 5); + graph.pushDirectedEdge(0, 2, 5); + graph.pushDirectedEdge(1, 3, 1); + graph.pushDirectedEdge(2, 3, 1); + + string expectedResult = "0 1 3"; + ASSERT_TRUE(graph.findSingleSourceShortestPathBellmanFord(0)); + ASSERT_EQ(unitTestHelper.serializeVectorToString(graph.getShortestPathBellmanFord(3)), expectedResult); + } + + // Test for all negative weights + TEST(bellmanFordTest, allNegativeWeightsTest) + { + Graph graph; + graph.pushDirectedEdge(0, 1, -5); + graph.pushDirectedEdge(1, 2, -3); + graph.pushDirectedEdge(2, 3, -2); + graph.pushDirectedEdge(3, 4, -1); + + string expectedResult = "0 1 2 3 4"; + ASSERT_TRUE(graph.findSingleSourceShortestPathBellmanFord(0)); + ASSERT_EQ(unitTestHelper.serializeVectorToString(graph.getShortestPathBellmanFord(4)), expectedResult); + } + + // Test for large Graph + TEST(bellmanFordTest, largeGraphTest) + { + Graph graph; + for (int i = 0; i < 100; ++i) { + graph.pushDirectedEdge(i, i + 1, 1); + } + + string expectedResult = "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20"; + ASSERT_TRUE(graph.findSingleSourceShortestPathBellmanFord(0)); + ASSERT_EQ(unitTestHelper.serializeVectorToString(graph.getShortestPathBellmanFord(20)), expectedResult); + } + + // Test for self-loop Edge + TEST(bellmanFordTest, selfLoopTest) + { + Graph graph; + graph.pushDirectedEdge(0, 0, 10); // self-loop with weight 10 + + string expectedResult = "0"; + ASSERT_TRUE(graph.findSingleSourceShortestPathBellmanFord(0)); + ASSERT_EQ(unitTestHelper.serializeVectorToString(graph.getShortestPathBellmanFord(0)), expectedResult); + } +} diff --git a/tests/0003_graph/0010_directed_acyclic_graph_shortest_path_test.cc b/tests/0003_graph/0010_directed_acyclic_graph_shortest_path_test.cc new file mode 100644 index 0000000..9e1b3a1 --- /dev/null +++ b/tests/0003_graph/0010_directed_acyclic_graph_shortest_path_test.cc @@ -0,0 +1,29 @@ +#include +#include "0010_directed_acyclic_graph_shortest_path.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::directed_acyclic_graph_shortest_path +{ + UnitTestHelper unitTestHelper; + + // Test for simple Graph + TEST(directedAcyclicGraphShortestPath, shortestPath) + { + Graph graph; + + graph.pushDirectedEdge(0, 1, 5); + graph.pushDirectedEdge(0, 2, 3); + graph.pushDirectedEdge(1, 2, 2); + graph.pushDirectedEdge(1, 3, 6); + graph.pushDirectedEdge(2, 3, 7); + graph.pushDirectedEdge(2, 4, 4); + graph.pushDirectedEdge(2, 5, 2); + graph.pushDirectedEdge(3, 4, -1); + graph.pushDirectedEdge(3, 5, 1); + graph.pushDirectedEdge(4, 5, -2); + + graph.findDAGShortestPath(1); + string expectedPath = "1 3 4 5"; + ASSERT_EQ(unitTestHelper.serializeVectorToString(graph.getDAGShortestPath(5)), expectedPath); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0011_single_source_shortest_path_dijkstra_test.cc b/tests/0003_graph/0011_single_source_shortest_path_dijkstra_test.cc new file mode 100644 index 0000000..a634ef7 --- /dev/null +++ b/tests/0003_graph/0011_single_source_shortest_path_dijkstra_test.cc @@ -0,0 +1,31 @@ +#include +#include "0011_single_source_shortest_path_dijkstra.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::single_source_shortest_path_dijkstra +{ + UnitTestHelper unitTestHelper; + + // Test for simple Graph + TEST(dijkstraTest, simpleGraph) + { + Graph graph; + + graph.pushDirectedEdge(0, 1, 10); + graph.pushDirectedEdge(0, 3, 5); + graph.pushDirectedEdge(1, 2, 1); + graph.pushDirectedEdge(1, 3, 2); + graph.pushDirectedEdge(2, 4, 4); + graph.pushDirectedEdge(3, 1, 3); + graph.pushDirectedEdge(3, 2, 9); + graph.pushDirectedEdge(3, 4, 2); + graph.pushDirectedEdge(4, 2, 6); + graph.pushDirectedEdge(4, 0, 7); + + graph.findShortestPathDijkstra(0); + + string expectedPath = "0 3 1 2"; + + ASSERT_EQ(unitTestHelper.serializeVectorToString(graph.getDijkstraShortestPath(2)), expectedPath); + } +} \ No newline at end of file diff --git a/tests/0003_Graph/0012_DifferenceConstraintsShortestPathsTest.cc b/tests/0003_graph/0012_difference_constraints_shortest_paths_test.cc similarity index 57% rename from tests/0003_Graph/0012_DifferenceConstraintsShortestPathsTest.cc rename to tests/0003_graph/0012_difference_constraints_shortest_paths_test.cc index 256def7..7b45734 100644 --- a/tests/0003_Graph/0012_DifferenceConstraintsShortestPathsTest.cc +++ b/tests/0003_graph/0012_difference_constraints_shortest_paths_test.cc @@ -1,13 +1,13 @@ #include -#include <0003_Graph/0012_DifferenceConstraintsShortestPaths.h> -#include"../0000_CommonUtilities/UnitTestHelper.h" +#include "0012_difference_constraints_shortest_paths.h" +#include"../0000_common_utilities/unit_test_helper.h" using namespace std; -namespace DifferenceConstraintsShortestPaths +namespace dsa::difference_constraints_shortest_paths { UnitTestHelper unitTestHelper; - TEST(DifferenceConstraints, SimpleGraph) + TEST(differenceConstraints, simpleGraph) { Graph graph; @@ -32,9 +32,9 @@ namespace DifferenceConstraintsShortestPaths {"v4", -1}, {"v3", 0}, }; - graph.PushAllDirectedEdges(vectorA, vectorX, vectorB); + graph.pushAllDirectedEdges(vectorA, vectorX, vectorB); - ASSERT_TRUE(graph.FindDifferenceConstraintsSolutionBellmanFord()); - ASSERT_EQ(unitTestHelper.SortVectorOfPairAndSerialize(graph.GetDifferenceConstrtaintsSolution()), unitTestHelper.SortVectorOfPairAndSerialize(expectedSolution)); + ASSERT_TRUE(graph.findDifferenceConstraintsSolutionBellmanFord()); + ASSERT_EQ(unitTestHelper.sortVectorOfPairAndSerialize(graph.getDifferenceConstrtaintsSolution()), unitTestHelper.sortVectorOfPairAndSerialize(expectedSolution)); } } \ No newline at end of file diff --git a/tests/0003_graph/0013_all_pairs_shortest_paths_floyd_warshall_test.cc b/tests/0003_graph/0013_all_pairs_shortest_paths_floyd_warshall_test.cc new file mode 100644 index 0000000..06bae14 --- /dev/null +++ b/tests/0003_graph/0013_all_pairs_shortest_paths_floyd_warshall_test.cc @@ -0,0 +1,36 @@ +#include +#include "0013_all_pairs_shortest_paths_floyd_warshall.h" +#include "../0000_common_utilities/unit_test_helper.h" +using namespace std; + +namespace dsa::all_pairs_shortest_paths_floyd_warshall +{ + UnitTestHelper unitTestHelper; + + TEST(floydWarshall, simpleGraph) + { + // arrange + Graph graph; + int noOfVertices = 5; + string expectedResult = "[1 5 4 3 2][1 5 4 3][1 5 4][1 5][2 4 1][2 4 3][2 4][2 4 1 5][3 2 4 1][3 2][3 2 4][3 2 4 1 5][4 1][4 3 2][4 3][4 1 5][5 4 1][5 4 3 2][5 4 3][5 4]"; + + // act + graph.createGraph(noOfVertices); + + graph.pushDirectedEdge(1, 2, 3); + graph.pushDirectedEdge(1, 3, 8); + graph.pushDirectedEdge(1, 5, -4); + graph.pushDirectedEdge(2, 4, 1); + graph.pushDirectedEdge(2, 5, 7); + graph.pushDirectedEdge(3, 2, 4); + graph.pushDirectedEdge(4, 3, -5); + graph.pushDirectedEdge(4, 1, 2); + graph.pushDirectedEdge(5, 4, 6); + + graph.findAllPairsShortestPathsFloydWarshallSolution(); + string actualResult = unitTestHelper.serializeVectorToString(graph.getFloydWarshallShortestPath()); + + // assert + ASSERT_EQ(actualResult, expectedResult); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0014_all_pairs_shortest_paths_johnson_test.cc b/tests/0003_graph/0014_all_pairs_shortest_paths_johnson_test.cc new file mode 100644 index 0000000..574a5d3 --- /dev/null +++ b/tests/0003_graph/0014_all_pairs_shortest_paths_johnson_test.cc @@ -0,0 +1,44 @@ +#include +#include "0014_all_pairs_shortest_paths_johnson.h" +#include"../0000_common_utilities/unit_test_helper.h" +using namespace std; + +namespace dsa::all_pairs_shortest_paths_johnson +{ + UnitTestHelper unitTestHelper; + + TEST(johnsonAlgorithm, simpleGraph) + { + // arrange + Graph graph; + vector> expectedDistanceMatrix = + { + {0, 1, -3, 2, -4}, + {3, 0, -4, 1, -1}, + {7, 4, 0, 5, 3}, + {2, -1, -5, 0, -2}, + {8, 5, 1, 6, 0}, + }; + string expectedPredecessorMatrixesult = "[1 5 4 3 2][1 5 4 3][1 5 4][1 5][2 4 1][2 4 3][2 4][2 4 1 5][3 2 4 1][3 2][3 2 4][3 2 4 1 5][4 1][4 3 2][4 3][4 1 5][5 4 1][5 4 3 2][5 4 3][5 4]"; + + // act + graph.pushDirectedEdge(1, 2, 3); + graph.pushDirectedEdge(1, 3, 8); + graph.pushDirectedEdge(1, 5, -4); + graph.pushDirectedEdge(2, 4, 1); + graph.pushDirectedEdge(2, 5, 7); + graph.pushDirectedEdge(3, 2, 4); + graph.pushDirectedEdge(4, 3, -5); + graph.pushDirectedEdge(4, 1, 2); + graph.pushDirectedEdge(5, 4, 6); + + bool result = graph.findAllPairsShortestPathsJohnsonAlgorithm(); + vector> actualDistanceMatrix = graph.getAllPairsShortestPathsDistanceMatrix(); + string actualPredecessorMatrix = unitTestHelper.serializeVectorToString(graph.getAllPairsShortestPathsPathMatrix()); + + // assert + ASSERT_TRUE(result); + ASSERT_EQ(expectedDistanceMatrix, actualDistanceMatrix); + ASSERT_EQ(expectedPredecessorMatrixesult, actualPredecessorMatrix); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0015_maximum_flow_ford_fulkerson_test.cc b/tests/0003_graph/0015_maximum_flow_ford_fulkerson_test.cc new file mode 100644 index 0000000..5efa4cb --- /dev/null +++ b/tests/0003_graph/0015_maximum_flow_ford_fulkerson_test.cc @@ -0,0 +1,64 @@ +#include +#include "0015_maximum_flow_ford_fulkerson.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::maximum_flow_ford_fulkerson +{ + UnitTestHelper unitTestHelper; + + TEST(maximumFlowFordFulkerson, graphWithNoParallelEdges) + { + // arrange + Graph graph; + int noOfVertices = 6; + int expectedMaximumFlow = 23; + + + // act + graph.createGraph(noOfVertices); + + graph.pushDirectedEdge(0, 1, 16); + graph.pushDirectedEdge(0, 2, 13); + graph.pushDirectedEdge(1, 3, 12); + graph.pushDirectedEdge(2, 1, 4); + graph.pushDirectedEdge(2, 4, 14); + graph.pushDirectedEdge(3, 2, 9); + graph.pushDirectedEdge(3, 5, 20); + graph.pushDirectedEdge(4, 3, 7); + graph.pushDirectedEdge(4, 5, 4); + + int actualMaximumFlow = graph.findMaximumFlowFordFulkerson(); + + // assert + ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); + } + + TEST(maximumFlowFordFulkerson, graphWithParallelEdges) + { + // arrange + Graph graph; + int noOfVertices = 6; + int expectedMaximumFlow = 24; + + + // act + graph.createGraph(noOfVertices); + + graph.pushDirectedEdge(0, 1, 16); + graph.pushDirectedEdge(0, 2, 13); + graph.pushDirectedEdge(1, 3, 12); + graph.pushDirectedEdge(1, 2, 6); + graph.pushDirectedEdge(2, 1, 10); + graph.pushDirectedEdge(2, 4, 14); + graph.pushDirectedEdge(2, 3, 2); + graph.pushDirectedEdge(3, 2, 11); + graph.pushDirectedEdge(3, 5, 20); + graph.pushDirectedEdge(4, 3, 7); + graph.pushDirectedEdge(4, 5, 4); + + int actualMaximumFlow = graph.findMaximumFlowFordFulkerson(); + + // assert + ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0016_maximum_flow_edmonds_karp_test.cc b/tests/0003_graph/0016_maximum_flow_edmonds_karp_test.cc new file mode 100644 index 0000000..28605db --- /dev/null +++ b/tests/0003_graph/0016_maximum_flow_edmonds_karp_test.cc @@ -0,0 +1,64 @@ +#include +#include "0016_maximum_flow_edmonds_karp.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::maximum_flow_edmonds_karp +{ + UnitTestHelper unitTestHelper; + + TEST(maximumFlowEdmondsKarp, graphWithNoParallelEdges) + { + // arrange + Graph graph; + int noOfVertices = 6; + int expectedMaximumFlow = 23; + + + // act + graph.createGraph(noOfVertices); + + graph.pushDirectedEdge(0, 1, 16); + graph.pushDirectedEdge(0, 2, 13); + graph.pushDirectedEdge(1, 3, 12); + graph.pushDirectedEdge(2, 1, 4); + graph.pushDirectedEdge(2, 4, 14); + graph.pushDirectedEdge(3, 2, 9); + graph.pushDirectedEdge(3, 5, 20); + graph.pushDirectedEdge(4, 3, 7); + graph.pushDirectedEdge(4, 5, 4); + + int actualMaximumFlow = graph.findMaximumFlowEdmondsKarp(); + + // assert + ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); + } + + TEST(maximumFlowEdmondsKarp, graphWithParallelEdges) + { + // arrange + Graph graph; + int noOfVertices = 6; + int expectedMaximumFlow = 24; + + + // act + graph.createGraph(noOfVertices); + + graph.pushDirectedEdge(0, 1, 16); + graph.pushDirectedEdge(0, 2, 13); + graph.pushDirectedEdge(1, 3, 12); + graph.pushDirectedEdge(1, 2, 6); + graph.pushDirectedEdge(2, 1, 10); + graph.pushDirectedEdge(2, 4, 14); + graph.pushDirectedEdge(2, 3, 2); + graph.pushDirectedEdge(3, 2, 11); + graph.pushDirectedEdge(3, 5, 20); + graph.pushDirectedEdge(4, 3, 7); + graph.pushDirectedEdge(4, 5, 4); + + int actualMaximumFlow = graph.findMaximumFlowEdmondsKarp(); + + // assert + ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0017_maximum_bipartite_matching_test.cc b/tests/0003_graph/0017_maximum_bipartite_matching_test.cc new file mode 100644 index 0000000..1c303af --- /dev/null +++ b/tests/0003_graph/0017_maximum_bipartite_matching_test.cc @@ -0,0 +1,35 @@ +#include +#include "0017_maximum_bipartite_matching.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::maximum_bipartite_matching +{ + TEST(maximumBipartiteMatching, simpleGraph) + { + // arrange + Graph graph; + UnitTestHelper unitTestHelper; + int noOfVertices = 9; + int expectedMaximumMatching = 3; + string expectedMatchings = "[0 1][2 6][3 5]"; + + // act + graph.createGraph(noOfVertices); + + graph.pushDirectedEdge(0, 1); + graph.pushDirectedEdge(2, 1); + graph.pushDirectedEdge(2, 6); + graph.pushDirectedEdge(3, 5); + graph.pushDirectedEdge(3, 6); + graph.pushDirectedEdge(3, 7); + graph.pushDirectedEdge(4, 6); + graph.pushDirectedEdge(8, 6); + + int actualMaximumMatching = graph.findMaximumBipartiteMatching(); + vector> actualMatchings = graph.getMatchings(); + + // assert + ASSERT_EQ(expectedMaximumMatching, actualMaximumMatching); + ASSERT_EQ(expectedMatchings, unitTestHelper.serializeVectorToString(actualMatchings)); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0018_maximum_flow_goldberg_generic_push_relabel_test.cc b/tests/0003_graph/0018_maximum_flow_goldberg_generic_push_relabel_test.cc new file mode 100644 index 0000000..71e9acb --- /dev/null +++ b/tests/0003_graph/0018_maximum_flow_goldberg_generic_push_relabel_test.cc @@ -0,0 +1,35 @@ +#include +#include "0018_maximum_flow_goldberg_generic_push_relabel.h" +#include "../0000_common_utilities/unit_test_helper.h" + +namespace dsa::maximum_flow_goldberg_generic_push_relabel +{ + UnitTestHelper unitTestHelper; + + TEST(maximumFlowGoldbergGenericPushRelabel, graphWithNoParallelEdges) + { + // arrange + Graph graph; + int noOfVertices = 6; + int expectedMaximumFlow = 23; + + + // act + graph.createGraph(noOfVertices); + + graph.pushDirectedEdge(0, 1, 16); + graph.pushDirectedEdge(0, 2, 13); + graph.pushDirectedEdge(1, 3, 12); + graph.pushDirectedEdge(2, 1, 4); + graph.pushDirectedEdge(2, 4, 14); + graph.pushDirectedEdge(3, 2, 9); + graph.pushDirectedEdge(3, 5, 20); + graph.pushDirectedEdge(4, 3, 7); + graph.pushDirectedEdge(4, 5, 4); + + int actualMaximumFlow = graph.findMaximumFlowGoldbergGenericPushRelabel(); + + // assert + ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); + } +} \ No newline at end of file diff --git a/tests/0003_graph/0019_maximum_flow_relabel_to_front_test.cc b/tests/0003_graph/0019_maximum_flow_relabel_to_front_test.cc new file mode 100644 index 0000000..a2780b8 --- /dev/null +++ b/tests/0003_graph/0019_maximum_flow_relabel_to_front_test.cc @@ -0,0 +1,36 @@ +#include +#include "0019_maximum_flow_relabel_to_front.h" +#include "../0000_common_utilities/unit_test_helper.h" +using namespace std; + +namespace dsa::maximum_flow_relabel_to_front +{ + UnitTestHelper unitTestHelper; + + TEST(maximumFlowRelabelToFront, simpleGraph) + { + // arrange + Graph graph; + int noOfVertices = 6; + int expectedMaximumFlow = 23; + + + // act + graph.createGraph(noOfVertices); + + graph.pushDirectedEdge(0, 1, 16); + graph.pushDirectedEdge(0, 2, 13); + graph.pushDirectedEdge(1, 3, 12); + graph.pushDirectedEdge(2, 1, 4); + graph.pushDirectedEdge(2, 4, 14); + graph.pushDirectedEdge(3, 2, 9); + graph.pushDirectedEdge(3, 5, 20); + graph.pushDirectedEdge(4, 3, 7); + graph.pushDirectedEdge(4, 5, 4); + + int actualMaximumFlow = graph.findMaximumFlowRelabelToFront(); + + // assert + ASSERT_EQ(expectedMaximumFlow, actualMaximumFlow); + } +} \ No newline at end of file diff --git a/tests/0003_graph/CMakeLists.txt b/tests/0003_graph/CMakeLists.txt new file mode 100644 index 0000000..da86fde --- /dev/null +++ b/tests/0003_graph/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_policy(SET CMP0135 NEW) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) + +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_executable( + 0003_GraphTests + + 0001_breadth_first_search_test.cc + 0002_depth_first_search_test.cc + 0003_topological_sort_test.cc + 0004_strongly_connected_components_test.cc + 0005_hamiltonian_path_and_cycle_test.cc + 0006_eulerian_path_and_circuit_test.cc + 0007_minimum_spanning_tree_kruskal_algorithm_test.cc + 0008_minimum_spanning_tree_prim_algorithm_test.cc + 0009_single_source_shortest_path_bellman_ford_test.cc + 0010_directed_acyclic_graph_shortest_path_test.cc + 0011_single_source_shortest_path_dijkstra_test.cc + 0012_difference_constraints_shortest_paths_test.cc + 0013_all_pairs_shortest_paths_floyd_warshall_test.cc + 0014_all_pairs_shortest_paths_johnson_test.cc + 0015_maximum_flow_ford_fulkerson_test.cc + 0016_maximum_flow_edmonds_karp_test.cc + 0017_maximum_bipartite_matching_test.cc + 0018_maximum_flow_goldberg_generic_push_relabel_test.cc + 0019_maximum_flow_relabel_to_front_test.cc +) + +target_link_libraries( + 0003_GraphTests + GTest::gtest_main + 0003_Graph +) + +# Add .clang-tidy configuration to this library. +if(CLANG_TIDY_EXE) + set_target_properties(0003_Graph PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") +endif() + +include(GoogleTest) +gtest_discover_tests(0003_GraphTests DISCOVERY_TIMEOUT 30) \ No newline at end of file diff --git a/tests/0004_GreedyAlgorithms/CMakeLists.txt b/tests/0004_GreedyAlgorithms/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tests/0004_dynamic_programming/0001_fibonacci_number_test.cc b/tests/0004_dynamic_programming/0001_fibonacci_number_test.cc new file mode 100644 index 0000000..15ed85b --- /dev/null +++ b/tests/0004_dynamic_programming/0001_fibonacci_number_test.cc @@ -0,0 +1,34 @@ +#include +#include "0001_fibonacci_number.h" +using namespace std; + +namespace dsa::fibonacci_number +{ + TEST(fibonacciNumber, recursiveTest) + { + // arrange + DynamicProgramming dp; + int n = 5; + int expectedFib = 5; + + // act + int actualFib = dp.recursiveNthFibonacci(n); + + // assert + ASSERT_EQ(expectedFib, actualFib); + } + + TEST(fibonacciNumber, dpTest) + { + // arrange + DynamicProgramming dp; + int n = 5; + int expectedFib = 5; + + // act + int actualFib = dp.dpNthFibonacci(n); + + // assert + ASSERT_EQ(expectedFib, actualFib); + } +} \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0002_tribonacci_number_test.cc b/tests/0004_dynamic_programming/0002_tribonacci_number_test.cc new file mode 100644 index 0000000..af11642 --- /dev/null +++ b/tests/0004_dynamic_programming/0002_tribonacci_number_test.cc @@ -0,0 +1,34 @@ +#include +#include "0002_tribonacci_number.h" +using namespace std; + +namespace dsa::tribonacci_number +{ + TEST(tribonacciNumber, recursiveTest) + { + // arrange + DynamicProgramming dp; + int n = 5; + int expectedFib = 2; + + // act + int actualFib = dp.recursiveNthTribonacci(n); + + // assert + ASSERT_EQ(expectedFib, actualFib); + } + + TEST(tribonacciNumber, dpTest) + { + // arrange + DynamicProgramming dp; + int n = 10; + int expectedFib = 44; + + // act + int actualFib = dp.dpNthTribonacci(n); + + // assert + ASSERT_EQ(expectedFib, actualFib); + } +} \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0003_climbing_stairs_test.cc b/tests/0004_dynamic_programming/0003_climbing_stairs_test.cc new file mode 100644 index 0000000..33e5930 --- /dev/null +++ b/tests/0004_dynamic_programming/0003_climbing_stairs_test.cc @@ -0,0 +1,33 @@ +#include +#include "0003_climbing_stairs.h" + +namespace dsa::climbing_stairs +{ + TEST(climbingStairs, recursiveTest) + { + // arrange + DynamicProgramming dp; + int n = 4; + int expectedCount = 5; + + // act + int actualCount = dp.recursiveCountWays(n); + + // assert + ASSERT_EQ(expectedCount, actualCount); + } + + TEST(climbingStairs, dpTest) + { + // arrange + DynamicProgramming dp; + int n = 4; + int expectedCount = 5; + + // act + int actualCount = dp.dpCountWays(n); + + // assert + ASSERT_EQ(expectedCount, actualCount); + } +} \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0004_minimum_cost_climbing_stairs_test.cc b/tests/0004_dynamic_programming/0004_minimum_cost_climbing_stairs_test.cc new file mode 100644 index 0000000..ce36d4c --- /dev/null +++ b/tests/0004_dynamic_programming/0004_minimum_cost_climbing_stairs_test.cc @@ -0,0 +1,33 @@ +#include +#include "0004_minimum_cost_climbing_stairs.h" + +namespace dsa::minimum_cost_climbing_stairs +{ + TEST(minimumCostClimbingStairs, recursionTest) + { + // arrange + DynamicProgramming dp; + vector cost = { 16, 19, 10, 12, 18 }; + int expectedCost = 31; + + // act + int actualCost = dp.recursiveMinimumCostClimbingStairs(cost); + + // assert + ASSERT_EQ(expectedCost, actualCost); + } + + TEST(minimumCostClimbingStairs, dpTest) + { + // arrange + DynamicProgramming dp; + vector cost = { 16, 19, 10, 12, 18 }; + int expectedCost = 31; + + // act + int actualCost = dp.dpMinimumCostClimbingStairs(cost); + + // assert + ASSERT_EQ(expectedCost, actualCost); + } +} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0005_HouseRobber1Test.cc b/tests/0004_dynamic_programming/0005_house_robber1_test.cc similarity index 52% rename from tests/0005_DynamicProgramming/0005_HouseRobber1Test.cc rename to tests/0004_dynamic_programming/0005_house_robber1_test.cc index 71c0af8..da817dd 100644 --- a/tests/0005_DynamicProgramming/0005_HouseRobber1Test.cc +++ b/tests/0004_dynamic_programming/0005_house_robber1_test.cc @@ -1,33 +1,33 @@ #include -#include <0005_DynamicProgramming/0005_HouseRobber1.h> +#include "0005_house_robber1.h" -namespace HouseRobber1 +namespace dsa::house_robber1 { - TEST(HouseRobber1, RecursionTest) + TEST(houseRobber1, recursionTest) { - // Arrange + // arrange DynamicProgramming dp; vector houseValues = { 6, 7, 1, 3, 8, 2, 4 }; int expectedMaximumLoot = 19; - // Act - int actualMaximumLoot = dp.RecursiveMaximumLoot(houseValues); + // act + int actualMaximumLoot = dp.recursiveMaximumLoot(houseValues); - // Assert + // assert ASSERT_EQ(expectedMaximumLoot, actualMaximumLoot); } - TEST(HouseRobber1, DpTest) + TEST(houseRobber1, dpTest) { - // Arrange + // arrange DynamicProgramming dp; vector houseValues = { 6, 7, 1, 3, 8, 2, 4 }; int expectedMaximumLoot = 19; - // Act - int actualMaximumLoot = dp.DpMaximumLoot(houseValues); + // act + int actualMaximumLoot = dp.dpMaximumLoot(houseValues); - // Assert + // assert ASSERT_EQ(expectedMaximumLoot, actualMaximumLoot); } } \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0006_HouseRobber2Test.cc b/tests/0004_dynamic_programming/0006_house_robber2_test.cc similarity index 53% rename from tests/0005_DynamicProgramming/0006_HouseRobber2Test.cc rename to tests/0004_dynamic_programming/0006_house_robber2_test.cc index c485d4c..22fea25 100644 --- a/tests/0005_DynamicProgramming/0006_HouseRobber2Test.cc +++ b/tests/0004_dynamic_programming/0006_house_robber2_test.cc @@ -1,47 +1,47 @@ #include -#include <0005_DynamicProgramming/0006_HouseRobber2.h> +#include "0006_house_robber2.h" -namespace HouseRobber2 +namespace dsa::house_robber2 { - TEST(HouseRobber2, RecursionTest01) + TEST(houseRobber2, recursionTest01) { - // Arrange + // arrange DynamicProgramming dp; vector houseValues = { 2, 2, 3, 1, 2 }; int expectedMaximumLoot = 5; - // Act - int actualMaximumLoot = dp.RecursiveMaximumLoot(houseValues); + // act + int actualMaximumLoot = dp.recursiveMaximumLoot(houseValues); - // Assert + // assert ASSERT_EQ(expectedMaximumLoot, actualMaximumLoot); } - TEST(HouseRobber2, DpTest01) + TEST(houseRobber2, dpTest01) { - // Arrange + // arrange DynamicProgramming dp; vector houseValues = { 2, 2, 3, 1, 2 }; int expectedMaximumLoot = 5; - // Act - int actualMaximumLoot = dp.DpMaximumLoot(houseValues); + // act + int actualMaximumLoot = dp.dpMaximumLoot(houseValues); - // Assert + // assert ASSERT_EQ(expectedMaximumLoot, actualMaximumLoot); } - TEST(HouseRobber2, DpTest02) + TEST(houseRobber2, dpTest02) { - // Arrange + // arrange DynamicProgramming dp; vector houseValues = { 9, 1, 8, 2 }; int expectedMaximumLoot = 17; - // Act - int actualMaximumLoot = dp.DpMaximumLoot(houseValues); + // act + int actualMaximumLoot = dp.dpMaximumLoot(houseValues); - // Assert + // assert ASSERT_EQ(expectedMaximumLoot, actualMaximumLoot); } diff --git a/tests/0005_DynamicProgramming/0007_DecodeWaysTest.cc b/tests/0004_dynamic_programming/0007_decode_ways_test.cc similarity index 50% rename from tests/0005_DynamicProgramming/0007_DecodeWaysTest.cc rename to tests/0004_dynamic_programming/0007_decode_ways_test.cc index 2cd183b..2cedff2 100644 --- a/tests/0005_DynamicProgramming/0007_DecodeWaysTest.cc +++ b/tests/0004_dynamic_programming/0007_decode_ways_test.cc @@ -1,47 +1,47 @@ #include -#include <0005_DynamicProgramming/0007_DecodeWays.h> +#include "0007_decode_ways.h" -namespace DecodeWays +namespace dsa::decode_ways { - TEST(DecodeWays, RecursionTest01) + TEST(decodeWays, recursionTest01) { - // Arrange + // arrange DynamicProgramming dp; string digits = "121"; int expectedWaysCount = 3; - // Act - int actualWaysCount = dp.RecursiveCountWays(digits); + // act + int actualWaysCount = dp.recursiveCountWays(digits); - // Assert + // assert ASSERT_EQ(expectedWaysCount, actualWaysCount); } - TEST(DecodeWays, DpTest01) + TEST(decodeWays, dpTest01) { - // Arrange + // arrange DynamicProgramming dp; string digits = "121"; int expectedWaysCount = 3; - // Act - int actualWaysCount = dp.DpCountways(digits); + // act + int actualWaysCount = dp.dpCountways(digits); - // Assert + // assert ASSERT_EQ(expectedWaysCount, actualWaysCount); } - TEST(DecodeWays, DpTestInvalidInput) + TEST(decodeWays, dpTestInvalidInput) { - // Arrange + // arrange DynamicProgramming dp; string digits = "230"; int expectedWaysCount = 0; - // Act - int actualWaysCount = dp.DpCountways(digits); + // act + int actualWaysCount = dp.dpCountways(digits); - // Assert + // assert ASSERT_EQ(expectedWaysCount, actualWaysCount); } } \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0008_tiling_problem_test.cc b/tests/0004_dynamic_programming/0008_tiling_problem_test.cc new file mode 100644 index 0000000..2ec9d03 --- /dev/null +++ b/tests/0004_dynamic_programming/0008_tiling_problem_test.cc @@ -0,0 +1,33 @@ +#include +#include "0008_tiling_problem.h" + +namespace dsa::tiling_problem +{ + TEST(tilingProblem, recursionTest01) + { + // arrange + DynamicProgramming dp; + int nummberOfRows = 4; + int expectedNumberOfWays = 5; + + // act + int actualNumberOfWays = dp.recursiveNumberOfWays(nummberOfRows); + + // assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } + + TEST(tilingProblem, dpTest01) + { + // arrange + DynamicProgramming dp; + int nummberOfRows = 4; + int expectedNumberOfWays = 5; + + // act + int actualNumberOfWays = dp.dpNumberOfWays(nummberOfRows); + + // assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } +} \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0009_friends_pairing_problem_test.cc b/tests/0004_dynamic_programming/0009_friends_pairing_problem_test.cc new file mode 100644 index 0000000..5d47716 --- /dev/null +++ b/tests/0004_dynamic_programming/0009_friends_pairing_problem_test.cc @@ -0,0 +1,91 @@ +#include +#include "0009_friends_pairing_problem.h" + +namespace dsa::friends_pairing_problem +{ + TEST(friendsPairingProblemDynamicProgrammingTest, recursiveCountFriendsPairingsTest1) + { + // arrange + DynamicProgramming dp; + int numberOfFriends = 3; + int expectedPairings = 4; + + // act + int actualPairings = dp.recursiveCountFriendsPairings(numberOfFriends); + + // assert + ASSERT_EQ(expectedPairings, actualPairings); + EXPECT_EQ(dp.recursiveCountFriendsPairings(4), 10); + EXPECT_EQ(dp.recursiveCountFriendsPairings(5), 26); + } + + TEST(friendsPairingProblemDynamicProgrammingTest, recursiveCountFriendsPairingsTest2) + { + // arrange + DynamicProgramming dp; + int numberOfFriends = 4; + int expectedPairings = 10; + + // act + int actualPairings = dp.recursiveCountFriendsPairings(numberOfFriends); + + // assert + ASSERT_EQ(expectedPairings, actualPairings); + } + + TEST(friendsPairingProblemDynamicProgrammingTest, recursiveCountFriendsPairingsTest3) + { + // arrange + DynamicProgramming dp; + int numberOfFriends = 5; + int expectedPairings = 26; + + // act + int actualPairings = dp.recursiveCountFriendsPairings(numberOfFriends); + + // assert + ASSERT_EQ(expectedPairings, actualPairings); + } + + TEST(friendsPairingProblemDynamicProgrammingTest, dpCountFriendsPairingsTest1) + { + // arrange + DynamicProgramming dp; + int numberOfFriends = 3; + int expectedPairings = 4; + + // act + int actualPairings = dp.recursiveCountFriendsPairings(numberOfFriends); + + // assert + ASSERT_EQ(expectedPairings, actualPairings); + } + + TEST(friendsPairingProblemDynamicProgrammingTest, dpCountFriendsPairingsTest2) + { + // arrange + DynamicProgramming dp; + int numberOfFriends = 4; + int expectedPairings = 10; + + // act + int actualPairings = dp.recursiveCountFriendsPairings(numberOfFriends); + + // assert + ASSERT_EQ(expectedPairings, actualPairings); + } + + TEST(friendsPairingProblemDynamicProgrammingTest, dpCountFriendsPairingsTest3) + { + // arrange + DynamicProgramming dp; + int numberOfFriends = 5; + int expectedPairings = 26; + + // act + int actualPairings = dp.recursiveCountFriendsPairings(numberOfFriends); + + // assert + ASSERT_EQ(expectedPairings, actualPairings); + } +} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0010_WaysToCoverDistanceTest.cc b/tests/0004_dynamic_programming/0010_ways_to_cover_distance_test.cc similarity index 55% rename from tests/0005_DynamicProgramming/0010_WaysToCoverDistanceTest.cc rename to tests/0004_dynamic_programming/0010_ways_to_cover_distance_test.cc index fac6df5..e54bfcf 100644 --- a/tests/0005_DynamicProgramming/0010_WaysToCoverDistanceTest.cc +++ b/tests/0004_dynamic_programming/0010_ways_to_cover_distance_test.cc @@ -1,117 +1,117 @@ #include -#include <0005_DynamicProgramming/0010_WaysToCoverDistance.h> +#include "0010_ways_to_cover_distance.h" -namespace WaysToCoverDistance +namespace dsa::ways_to_cover_distance { - TEST(WaysToCoverDistanceTest, RecursiveWaysToCoverDistance1) + TEST(waysToCoverDistanceTest, recursiveWaysToCoverDistance1) { - // Arrange + // arrange DynamicProgramming dp; int distance = 3; int expectedNumberOfWaysToCoverDistance = 4; - // Act - int actualNumberOfWaysToCoverDistance = dp.RecursiveWaysToCoverDistance(distance); + // act + int actualNumberOfWaysToCoverDistance = dp.recursiveWaysToCoverDistance(distance); - // Assert + // assert ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); } - TEST(WaysToCoverDistanceTest, RecursiveWaysToCoverDistance2) + TEST(waysToCoverDistanceTest, recursiveWaysToCoverDistance2) { - // Arrange + // arrange DynamicProgramming dp; int distance = 4; int expectedNumberOfWaysToCoverDistance = 7; - // Act - int actualNumberOfWaysToCoverDistance = dp.RecursiveWaysToCoverDistance(distance); + // act + int actualNumberOfWaysToCoverDistance = dp.recursiveWaysToCoverDistance(distance); - // Assert + // assert ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); } - TEST(WaysToCoverDistanceTest, RecursiveWaysToCoverDistanc3) + TEST(waysToCoverDistanceTest, recursiveWaysToCoverDistanc3) { - // Arrange + // arrange DynamicProgramming dp; int distance = 5; int expectedNumberOfWaysToCoverDistance = 13; - // Act - int actualNumberOfWaysToCoverDistance = dp.RecursiveWaysToCoverDistance(distance); + // act + int actualNumberOfWaysToCoverDistance = dp.recursiveWaysToCoverDistance(distance); - // Assert + // assert ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); } - TEST(WaysToCoverDistanceTest, RecursiveWaysToCoverDistanc4) + TEST(waysToCoverDistanceTest, recursiveWaysToCoverDistanc4) { - // Arrange + // arrange DynamicProgramming dp; int distance = 6; int expectedNumberOfWaysToCoverDistance = 24; - // Act - int actualNumberOfWaysToCoverDistance = dp.RecursiveWaysToCoverDistance(distance); + // act + int actualNumberOfWaysToCoverDistance = dp.recursiveWaysToCoverDistance(distance); - // Assert + // assert ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); } - TEST(WaysToCoverDistanceTest, DpWaysToCoverDistance1) + TEST(waysToCoverDistanceTest, dpWaysToCoverDistance1) { - // Arrange + // arrange DynamicProgramming dp; int distance = 3; int expectedNumberOfWaysToCoverDistance = 4; - // Act - int actualNumberOfWaysToCoverDistance = dp.DpWaysToCoverDistance(distance); + // act + int actualNumberOfWaysToCoverDistance = dp.dpWaysToCoverDistance(distance); - // Assert + // assert ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); } - TEST(WaysToCoverDistanceTest, DpWaysToCoverDistance2) + TEST(waysToCoverDistanceTest, dpWaysToCoverDistance2) { - // Arrange + // arrange DynamicProgramming dp; int distance = 4; int expectedNumberOfWaysToCoverDistance = 7; - // Act - int actualNumberOfWaysToCoverDistance = dp.DpWaysToCoverDistance(distance); + // act + int actualNumberOfWaysToCoverDistance = dp.dpWaysToCoverDistance(distance); - // Assert + // assert ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); } - TEST(WaysToCoverDistanceTest, DpWaysToCoverDistance3) + TEST(waysToCoverDistanceTest, dpWaysToCoverDistance3) { - // Arrange + // arrange DynamicProgramming dp; int distance = 5; int expectedNumberOfWaysToCoverDistance = 13; - // Act - int actualNumberOfWaysToCoverDistance = dp.DpWaysToCoverDistance(distance); + // act + int actualNumberOfWaysToCoverDistance = dp.dpWaysToCoverDistance(distance); - // Assert + // assert ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); } - TEST(WaysToCoverDistanceTest, DpWaysToCoverDistance4) + TEST(waysToCoverDistanceTest, dpWaysToCoverDistance4) { - // Arrange + // arrange DynamicProgramming dp; int distance = 6; int expectedNumberOfWaysToCoverDistance = 24; - // Act - int actualNumberOfWaysToCoverDistance = dp.DpWaysToCoverDistance(distance); + // act + int actualNumberOfWaysToCoverDistance = dp.dpWaysToCoverDistance(distance); - // Assert + // assert ASSERT_EQ(expectedNumberOfWaysToCoverDistance, actualNumberOfWaysToCoverDistance); } } \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0011_count_ways_to_reach_nth_stair_include_order_test.cc b/tests/0004_dynamic_programming/0011_count_ways_to_reach_nth_stair_include_order_test.cc new file mode 100644 index 0000000..2e5b8c8 --- /dev/null +++ b/tests/0004_dynamic_programming/0011_count_ways_to_reach_nth_stair_include_order_test.cc @@ -0,0 +1,33 @@ +#include +#include "0011_count_ways_to_reach_nth_stair_include_order.h" + +namespace dsa::count_ways_to_reach_nth_stair_include_order +{ + TEST(countWaysToReachNthStairIncludeOrderTest, recursiveCountWaysToReachNthStairIncludeOrder1) + { + // arrange + DynamicProgramming dp; + int n = 4; + int expectedNumberOfWays = 5; + + // act + int actualNumberOfWays = dp.recursiveCountWays(n); + + // assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } + + TEST(countWaysToReachNthStairIncludeOrderTest, dpCountWaysToReachNthStairIncludeOrder1) + { + // arrange + DynamicProgramming dp; + int n = 4; + int expectedNumberOfWays = 5; + + // act + int actualNumberOfWays = dp.dpCountWays(n); + + // assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } +} \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0012_count_ways_to_reach_nth_stair_exclude_order_test.cc b/tests/0004_dynamic_programming/0012_count_ways_to_reach_nth_stair_exclude_order_test.cc new file mode 100644 index 0000000..301f771 --- /dev/null +++ b/tests/0004_dynamic_programming/0012_count_ways_to_reach_nth_stair_exclude_order_test.cc @@ -0,0 +1,33 @@ +#include +#include "0012_count_ways_to_reach_nth_stair_exclude_order.h" + +namespace dsa::count_ways_to_reach_nth_stair_exclude_order +{ + TEST(countWaysToReachNthStairExcludeOrderTest, recursiveCountWaysToReachNthStairExcludeOrder1) + { + // arrange + DynamicProgramming dp; + int n = 4; + int expectedNumberOfWays = 3; + + // act + int actualNumberOfWays = dp.recursiveCountWays(n); + + // assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } + + TEST(countWaysToReachNthStairExcludeOrderTest, dpCountWaysToReachNthStairExcludeOrder1) + { + // arrange + DynamicProgramming dp; + int n = 4; + int expectedNumberOfWays = 3; + + // act + int actualNumberOfWays = dp.dpCountWays(n); + + // assert + ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); + } +} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0013_KnapsackProblemTest.cc b/tests/0004_dynamic_programming/0013_knapsack_problem_test.cc similarity index 56% rename from tests/0005_DynamicProgramming/0013_KnapsackProblemTest.cc rename to tests/0004_dynamic_programming/0013_knapsack_problem_test.cc index 5a8b870..f114a8a 100644 --- a/tests/0005_DynamicProgramming/0013_KnapsackProblemTest.cc +++ b/tests/0004_dynamic_programming/0013_knapsack_problem_test.cc @@ -1,53 +1,53 @@ #include -#include <0005_DynamicProgramming/0013_KnapsackProblem.h> +#include "0013_knapsack_problem.h" -namespace KnapsackProblem +namespace dsa::knapsack_problem { - TEST(KnapsackProblemTest, RecursiveKnapsackProblemTest01) + TEST(knapsackProblemTest, recursiveKnapsackProblemTest01) { - // Arrange + // arrange DynamicProgramming dp; int capacity = 4; vector weight = { 4,5,1 }; vector profit = { 1,2,3 }; int expectedMaximumProfit = 3; - // Act - int actualMaximumProfit = dp.RecursiveKnapsack(capacity, weight, profit); + // act + int actualMaximumProfit = dp.recursiveKnapsack(capacity, weight, profit); - // Assert + // assert ASSERT_EQ(expectedMaximumProfit, actualMaximumProfit); } - TEST(KnapsackProblemTest, DpKnapsackProblemTest01) + TEST(knapsackProblemTest, dpKnapsackProblemTest01) { - // Arrange + // arrange DynamicProgramming dp; int capacity = 4; vector weight = { 4,5,1 }; vector profit = { 1,2,3 }; int expectedMaximumProfit = 3; - // Act - int actualMaximumProfit = dp.DpKnapsack(capacity, weight, profit); + // act + int actualMaximumProfit = dp.dpKnapsack(capacity, weight, profit); - // Assert + // assert ASSERT_EQ(expectedMaximumProfit, actualMaximumProfit); } - TEST(KnapsackProblemTest, DpKnapsackProblemTest02) + TEST(knapsackProblemTest, dpKnapsackProblemTest02) { - // Arrange + // arrange DynamicProgramming dp; int capacity = 4; vector weight = { 4,5,1 }; vector profit = { 1,2,3 }; int expectedMaximumProfit = 3; - // Act - int actualMaximumProfit = dp.DpKnapsackSpaceOptimized(capacity, weight, profit); + // act + int actualMaximumProfit = dp.dpKnapsackSpaceOptimized(capacity, weight, profit); - // Assert + // assert ASSERT_EQ(expectedMaximumProfit, actualMaximumProfit); } } \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0014_SubsetSumProblemTest.cc b/tests/0004_dynamic_programming/0014_subset_sum_problem_test.cc similarity index 50% rename from tests/0005_DynamicProgramming/0014_SubsetSumProblemTest.cc rename to tests/0004_dynamic_programming/0014_subset_sum_problem_test.cc index fb6e4b6..d1e8c0c 100644 --- a/tests/0005_DynamicProgramming/0014_SubsetSumProblemTest.cc +++ b/tests/0004_dynamic_programming/0014_subset_sum_problem_test.cc @@ -1,35 +1,35 @@ #include -#include <0005_DynamicProgramming/0014_SubsetSumProblem.h> +#include "0014_subset_sum_problem.h" -namespace SubsetSumProblem +namespace dsa::subset_sum_problem { - TEST(SubsetSumProblemTest, RecursiveSubsetSumTest) + TEST(subsetSumProblemTest, recursiveSubsetSumTest) { - // Arrange + // arrange DynamicProgramming dp; vector nums = { 3, 34, 4, 12, 5, 2 }; int sum = 9; bool expectedResult = true; - // Act - bool actualResult = dp.RecursiveSubsetSum(nums, sum); + // act + bool actualResult = dp.recursiveSubsetSum(nums, sum); - // Assert + // assert ASSERT_EQ(expectedResult, actualResult); } - TEST(SubsetSumProblemTest, DpSubsetSumTest) + TEST(subsetSumProblemTest, dpSubsetSumTest) { - // Arrange + // arrange DynamicProgramming dp; vector nums = { 3, 34, 4, 12, 5, 2 }; int sum = 9; bool expectedResult = true; - // Act - bool actualResult = dp.DpIsSubsetSum(nums, sum); + // act + bool actualResult = dp.dpIsSubsetSum(nums, sum); - // Assert + // assert ASSERT_EQ(expectedResult, actualResult); } } \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0015_count_subsets_for_sum_test.cc b/tests/0004_dynamic_programming/0015_count_subsets_for_sum_test.cc new file mode 100644 index 0000000..26450ef --- /dev/null +++ b/tests/0004_dynamic_programming/0015_count_subsets_for_sum_test.cc @@ -0,0 +1,35 @@ +#include +#include "0015_count_subsets_for_sum.h" + +namespace dsa::count_subsets_for_sum +{ + TEST(countSubsetsForSum, recursiveCountSubsetSum) + { + // arrange + DynamicProgramming dp; + vector nums = { 1, 2, 3, 3 }; + int sum = 6; + int expectedCount = 3; + + // act + int actualCount = dp.recursiveCountSubsets(nums, sum); + + // assert + ASSERT_EQ(expectedCount, actualCount); + } + + TEST(countSubsetsForSum, dpCountSubsetSum) + { + // arrange + DynamicProgramming dp; + vector nums = { 1, 2, 3, 3 }; + int sum = 6; + int expectedCount = 3; + + // act + int actualCount = dp.dpCountSubsets(nums, sum); + + // assert + ASSERT_EQ(expectedCount, actualCount); + } +} \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0016_partition_equal_subset_sum_test.cc b/tests/0004_dynamic_programming/0016_partition_equal_subset_sum_test.cc new file mode 100644 index 0000000..cf7092b --- /dev/null +++ b/tests/0004_dynamic_programming/0016_partition_equal_subset_sum_test.cc @@ -0,0 +1,33 @@ +#include +#include "0016_partition_equal_subset_sum.h" + +namespace dsa::partition_equal_subset_sum +{ + TEST(partitionEqualSubsetSum, recursivePartitionEqualSubsetSum) + { + // arrange + DynamicProgramming dp; + vector nums = { 1, 5, 11, 5 }; + bool expectedResult = true; + + // act + bool actualResult = dp.recursivePartitionEqualSubsets(nums); + + // assert + ASSERT_EQ(expectedResult, actualResult); + } + + TEST(partitionEqualSubsetSum, dpPartitionEqualSubsetSum) + { + // arrange + DynamicProgramming dp; + vector nums = { 1, 5, 11, 5 }; + bool expectedResult = true; + + // act + bool actualResult = dp.dpPartitionEqualSubsets(nums); + + // assert + ASSERT_EQ(expectedResult, actualResult); + } +} \ No newline at end of file diff --git a/tests/0004_dynamic_programming/0017_target_sum_test.cc b/tests/0004_dynamic_programming/0017_target_sum_test.cc new file mode 100644 index 0000000..32cd6b3 --- /dev/null +++ b/tests/0004_dynamic_programming/0017_target_sum_test.cc @@ -0,0 +1,50 @@ +#include +#include "0017_target_sum.h" + +namespace dsa::target_sum +{ + TEST(targetSum, recursiveSolutionTest_ValidInput_ReturnsCorrectResult) + { + // arrange + DynamicProgramming dp; + vector nums = { 1, 1, 1, 1, 1 }; + int target = 3; + int expectedResult = 5; + + // act + int actualResult = dp.recursiveFindTotalWays(nums, target); + + // assert + ASSERT_EQ(expectedResult, actualResult); + } + + TEST(targetSum, dpSolutionTest_ValidInput_ReturnsCorrectResult) + { + // arrange + DynamicProgramming dp; + vector nums = { 1, 1, 1, 1, 1 }; + int target = 3; + int expectedResult = 5; + + // act + int actualResult = dp.dpFindTotalWays(nums, target); + + // assert + ASSERT_EQ(expectedResult, actualResult); + } + + TEST(targetSum, dpSolutionTest_TargetGreaterThanTotalSum_ReturnsZero) + { + // arrange + DynamicProgramming dp; + vector nums = { 1, 1, 1, 1, 1 }; + int target = -1000; + int expectedResult = 0; + + // act + int actualResult = dp.dpFindTotalWays(nums, target); + + // assert + ASSERT_EQ(expectedResult, actualResult); + } +} \ No newline at end of file diff --git a/tests/0004_dynamic_programming/CMakeLists.txt b/tests/0004_dynamic_programming/CMakeLists.txt new file mode 100644 index 0000000..a655df7 --- /dev/null +++ b/tests/0004_dynamic_programming/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_policy(SET CMP0135 NEW) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) + +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_executable( + 0005_DynamicProgrammingTests + + 0001_fibonacci_number_test.cc + 0002_tribonacci_number_test.cc + 0003_climbing_stairs_test.cc + 0004_minimum_cost_climbing_stairs_test.cc + 0005_house_robber1_test.cc + 0006_house_robber2_test.cc + 0007_decode_ways_test.cc + 0008_tiling_problem_test.cc + 0009_friends_pairing_problem_test.cc + 0010_ways_to_cover_distance_test.cc + 0011_count_ways_to_reach_nth_stair_include_order_test.cc + 0012_count_ways_to_reach_nth_stair_exclude_order_test.cc + 0013_knapsack_problem_test.cc + 0014_subset_sum_problem_test.cc + 0015_count_subsets_for_sum_test.cc + 0016_partition_equal_subset_sum_test.cc + 0017_target_sum_test.cc + +) + +target_link_libraries( + 0005_DynamicProgrammingTests + GTest::gtest_main + 0005_DynamicProgramming +) + +# Add .clang-tidy configuration to this library. +if(CLANG_TIDY_EXE) + set_target_properties(0005_DynamicProgramming PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") +endif() + +include(GoogleTest) +gtest_discover_tests(0005_DynamicProgrammingTests DISCOVERY_TIMEOUT 30) \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0001_FibonacciNumberTest.cc b/tests/0005_DynamicProgramming/0001_FibonacciNumberTest.cc deleted file mode 100644 index 09f5f83..0000000 --- a/tests/0005_DynamicProgramming/0001_FibonacciNumberTest.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include <0005_DynamicProgramming/0001_FibonacciNumber.h> -using namespace std; - -namespace FibonacciNumber -{ - TEST(FibonacciNumber, RecursiveTest) - { - // Arrange - DynamicProgramming dp; - int n = 5; - int expectedFib = 5; - - // Act - int actualFib = dp.RecursiveNthFibonacci(n); - - // Assert - ASSERT_EQ(expectedFib, actualFib); - } - - TEST(FibonacciNumber, DpTest) - { - // Arrange - DynamicProgramming dp; - int n = 5; - int expectedFib = 5; - - // Act - int actualFib = dp.DpNthFibonacci(n); - - // Assert - ASSERT_EQ(expectedFib, actualFib); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0002_TribonacciNumberTest.cc b/tests/0005_DynamicProgramming/0002_TribonacciNumberTest.cc deleted file mode 100644 index 94ecca5..0000000 --- a/tests/0005_DynamicProgramming/0002_TribonacciNumberTest.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include <0005_DynamicProgramming/0002_TribonacciNumber.h> -using namespace std; - -namespace TribonacciNumber -{ - TEST(TribonacciNumber, RecursiveTest) - { - // Arrange - DynamicProgramming dp; - int n = 5; - int expectedFib = 2; - - // Act - int actualFib = dp.RecursiveNthTribonacci(n); - - // Assert - ASSERT_EQ(expectedFib, actualFib); - } - - TEST(TribonacciNumber, DpTest) - { - // Arrange - DynamicProgramming dp; - int n = 10; - int expectedFib = 44; - - // Act - int actualFib = dp.DpNthTribonacci(n); - - // Assert - ASSERT_EQ(expectedFib, actualFib); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0003_ClimbingStairsTest.cc b/tests/0005_DynamicProgramming/0003_ClimbingStairsTest.cc deleted file mode 100644 index f992682..0000000 --- a/tests/0005_DynamicProgramming/0003_ClimbingStairsTest.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include <0005_DynamicProgramming/0003_ClimbingStairs.h> - -namespace ClimbingStairs -{ - TEST(ClimbingStairs, RecursiveTest) - { - // Arrange - DynamicProgramming dp; - int n = 4; - int expectedCount = 5; - - // Act - int actualCount = dp.RecursiveCountWays(n); - - // Assert - ASSERT_EQ(expectedCount, actualCount); - } - - TEST(ClimbingStairs, DpTest) - { - // Arrange - DynamicProgramming dp; - int n = 4; - int expectedCount = 5; - - // Act - int actualCount = dp.DpCountWays(n); - - // Assert - ASSERT_EQ(expectedCount, actualCount); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0004_MinimumCostClimbingStairsTest.cc b/tests/0005_DynamicProgramming/0004_MinimumCostClimbingStairsTest.cc deleted file mode 100644 index acfb98b..0000000 --- a/tests/0005_DynamicProgramming/0004_MinimumCostClimbingStairsTest.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include <0005_DynamicProgramming/0004_MinimumCostClimbingStairs.h> - -namespace MinimumCostClimbingStairs -{ - TEST(MinimumCostClimbingStairs, RecursionTest) - { - // Arrange - DynamicProgramming dp; - vector cost = { 16, 19, 10, 12, 18 }; - int expectedCost = 31; - - // Act - int actualCost = dp.RecursiveMinimumCostClimbingStairs(cost); - - // Assert - ASSERT_EQ(expectedCost, actualCost); - } - - TEST(MinimumCostClimbingStairs, DpTest) - { - // Arrange - DynamicProgramming dp; - vector cost = { 16, 19, 10, 12, 18 }; - int expectedCost = 31; - - // Act - int actualCost = dp.DpMinimumCostClimbingStairs(cost); - - // Assert - ASSERT_EQ(expectedCost, actualCost); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0008_TilingProblemTest.cc b/tests/0005_DynamicProgramming/0008_TilingProblemTest.cc deleted file mode 100644 index fa5c504..0000000 --- a/tests/0005_DynamicProgramming/0008_TilingProblemTest.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include <0005_DynamicProgramming/0008_TilingProblem.h> - -namespace TilingProblem -{ - TEST(TilingProblem, RecursionTest01) - { - // Arrange - DynamicProgramming dp; - int nummberOfRows = 4; - int expectedNumberOfWays = 5; - - // Act - int actualNumberOfWays = dp.RecursiveNumberOfWays(nummberOfRows); - - // Assert - ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); - } - - TEST(TilingProblem, DpTest01) - { - // Arrange - DynamicProgramming dp; - int nummberOfRows = 4; - int expectedNumberOfWays = 5; - - // Act - int actualNumberOfWays = dp.DpNumberOfWays(nummberOfRows); - - // Assert - ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0009_FriendsPairingProblemTest.cc b/tests/0005_DynamicProgramming/0009_FriendsPairingProblemTest.cc deleted file mode 100644 index b1d2332..0000000 --- a/tests/0005_DynamicProgramming/0009_FriendsPairingProblemTest.cc +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include <0005_DynamicProgramming/0009_FriendsPairingProblem.h> - -namespace FriendsPairingProblem -{ - TEST(FriendsPairingProblemDynamicProgrammingTest, RecursiveCountFriendsPairingsTest1) - { - // Arrange - DynamicProgramming dp; - int numberOfFriends = 3; - int expectedPairings = 4; - - // Act - int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); - - // Assert - ASSERT_EQ(expectedPairings, actualPairings); - EXPECT_EQ(dp.RecursiveCountFriendsPairings(4), 10); - EXPECT_EQ(dp.RecursiveCountFriendsPairings(5), 26); - } - - TEST(FriendsPairingProblemDynamicProgrammingTest, RecursiveCountFriendsPairingsTest2) - { - // Arrange - DynamicProgramming dp; - int numberOfFriends = 4; - int expectedPairings = 10; - - // Act - int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); - - // Assert - ASSERT_EQ(expectedPairings, actualPairings); - } - - TEST(FriendsPairingProblemDynamicProgrammingTest, RecursiveCountFriendsPairingsTest3) - { - // Arrange - DynamicProgramming dp; - int numberOfFriends = 5; - int expectedPairings = 26; - - // Act - int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); - - // Assert - ASSERT_EQ(expectedPairings, actualPairings); - } - - TEST(FriendsPairingProblemDynamicProgrammingTest, DpCountFriendsPairingsTest1) - { - // Arrange - DynamicProgramming dp; - int numberOfFriends = 3; - int expectedPairings = 4; - - // Act - int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); - - // Assert - ASSERT_EQ(expectedPairings, actualPairings); - } - - TEST(FriendsPairingProblemDynamicProgrammingTest, DpCountFriendsPairingsTest2) - { - // Arrange - DynamicProgramming dp; - int numberOfFriends = 4; - int expectedPairings = 10; - - // Act - int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); - - // Assert - ASSERT_EQ(expectedPairings, actualPairings); - } - - TEST(FriendsPairingProblemDynamicProgrammingTest, DpCountFriendsPairingsTest3) - { - // Arrange - DynamicProgramming dp; - int numberOfFriends = 5; - int expectedPairings = 26; - - // Act - int actualPairings = dp.RecursiveCountFriendsPairings(numberOfFriends); - - // Assert - ASSERT_EQ(expectedPairings, actualPairings); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrderTest.cc b/tests/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrderTest.cc deleted file mode 100644 index 82c49be..0000000 --- a/tests/0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrderTest.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include <0005_DynamicProgramming/0011_CountWaysToReachNthStairIncludeOrder.h> - -namespace CountWaysToReachNthStairIncludeOrder -{ - TEST(CountWaysToReachNthStairIncludeOrderTest, RecursiveCountWaysToReachNthStairIncludeOrder1) - { - // Arrange - DynamicProgramming dp; - int n = 4; - int expectedNumberOfWays = 5; - - // Act - int actualNumberOfWays = dp.RecursiveCountWaysToReachNthStairIncludeOrder(n); - - // Assert - ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); - } - - TEST(CountWaysToReachNthStairIncludeOrderTest, DpCountWaysToReachNthStairIncludeOrder1) - { - // Arrange - DynamicProgramming dp; - int n = 4; - int expectedNumberOfWays = 5; - - // Act - int actualNumberOfWays = dp.DpCountWaysToReachNthStairIncludeOrder(n); - - // Assert - ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrderTest.cc b/tests/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrderTest.cc deleted file mode 100644 index 63aaf6d..0000000 --- a/tests/0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrderTest.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include <0005_DynamicProgramming/0012_CountWaysToReachNthStairExcludeOrder.h> - -namespace CountWaysToReachNthStairExcludeOrder -{ - TEST(CountWaysToReachNthStairExcludeOrderTest, RecursiveCountWaysToReachNthStairExcludeOrder1) - { - // Arrange - DynamicProgramming dp; - int n = 4; - int expectedNumberOfWays = 3; - - // Act - int actualNumberOfWays = dp.RecursiveCountWaysToReachNthStairExcludeOrder(n); - - // Assert - ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); - } - - TEST(CountWaysToReachNthStairExcludeOrderTest, DpCountWaysToReachNthStairExcludeOrder1) - { - // Arrange - DynamicProgramming dp; - int n = 4; - int expectedNumberOfWays = 3; - - // Act - int actualNumberOfWays = dp.DpCountWaysToReachNthStairExcludeOrder(n); - - // Assert - ASSERT_EQ(expectedNumberOfWays, actualNumberOfWays); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0015_CountSubsetsForSumTest.cc b/tests/0005_DynamicProgramming/0015_CountSubsetsForSumTest.cc deleted file mode 100644 index 6b110d1..0000000 --- a/tests/0005_DynamicProgramming/0015_CountSubsetsForSumTest.cc +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include<0005_DynamicProgramming/0015_CountSubsetsForSum.h> - -namespace CountSubsetsForSum -{ - TEST(CountSubsetsForSum, RecursiveCountSubsetSum) - { - // Arrange - DynamicProgramming dp; - vector nums = { 1, 2, 3, 3 }; - int sum = 6; - int expectedCount = 3; - - // Act - int actualCount = dp.RecursiveCountSubsets(nums, sum); - - // Assert - ASSERT_EQ(expectedCount, actualCount); - } - - TEST(CountSubsetsForSum, DpCountSubsetSum) - { - // Arrange - DynamicProgramming dp; - vector nums = { 1, 2, 3, 3 }; - int sum = 6; - int expectedCount = 3; - - // Act - int actualCount = dp.DpCountSubsets(nums, sum); - - // Assert - ASSERT_EQ(expectedCount, actualCount); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0016_PartitionEqualSubsetSumTest.cc b/tests/0005_DynamicProgramming/0016_PartitionEqualSubsetSumTest.cc deleted file mode 100644 index 026b05f..0000000 --- a/tests/0005_DynamicProgramming/0016_PartitionEqualSubsetSumTest.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include <0005_DynamicProgramming/0016_PartitionEqualSubsetSum.h> - -namespace PartitionEqualSubsetSum -{ - TEST(PartitionEqualSubsetSum, RecursivePartitionEqualSubsetSum) - { - // Arrange - DynamicProgramming dp; - vector nums = { 1, 5, 11, 5 }; - bool expectedResult = true; - - // Act - bool actualResult = dp.RecursivePartitionEqualSubsets(nums); - - // Assert - ASSERT_EQ(expectedResult, actualResult); - } - - TEST(PartitionEqualSubsetSum, DpPartitionEqualSubsetSum) - { - // Arrange - DynamicProgramming dp; - vector nums = { 1, 5, 11, 5 }; - bool expectedResult = true; - - // Act - bool actualResult = dp.DpPartitionEqualSubsets(nums); - - // Assert - ASSERT_EQ(expectedResult, actualResult); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/0017_TargetSumTest.cc b/tests/0005_DynamicProgramming/0017_TargetSumTest.cc deleted file mode 100644 index 242b1d2..0000000 --- a/tests/0005_DynamicProgramming/0017_TargetSumTest.cc +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include <0005_DynamicProgramming/0017_TargetSum.h> - -namespace TargetSum -{ - TEST(TargetSum, RecursiveSolutionTest_ValidInput_ReturnsCorrectResult) - { - // Arrange - DynamicProgramming dp; - vector nums = { 1, 1, 1, 1, 1 }; - int target = 3; - int expectedResult = 5; - - // Act - int actualResult = dp.RecursiveFindTotalWays(nums, target); - - // Assert - ASSERT_EQ(expectedResult, actualResult); - } - - TEST(TargetSum, DpSolutionTest_ValidInput_ReturnsCorrectResult) - { - // Arrange - DynamicProgramming dp; - vector nums = { 1, 1, 1, 1, 1 }; - int target = 3; - int expectedResult = 5; - - // Act - int actualResult = dp.DpFindTotalWays(nums, target); - - // Assert - ASSERT_EQ(expectedResult, actualResult); - } - - TEST(TargetSum, DpSolutionTest_TargetGreaterThanTotalSum_ReturnsZero) - { - // Arrange - DynamicProgramming dp; - vector nums = { 1, 1, 1, 1, 1 }; - int target = -1000; - int expectedResult = 0; - - // Act - int actualResult = dp.DpFindTotalWays(nums, target); - - // Assert - ASSERT_EQ(expectedResult, actualResult); - } -} \ No newline at end of file diff --git a/tests/0005_DynamicProgramming/CMakeLists.txt b/tests/0005_DynamicProgramming/CMakeLists.txt deleted file mode 100644 index 4ef67b0..0000000 --- a/tests/0005_DynamicProgramming/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -cmake_policy(SET CMP0135 NEW) - -include(FetchContent) -FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip -) - -# For Windows: Prevent overriding the parent project's compiler/linker settings -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -FetchContent_MakeAvailable(googletest) - -enable_testing() - -add_executable( - 0005DynamicProgrammingTests - 0001_FibonacciNumberTest.cc - 0002_TribonacciNumberTest.cc - 0003_ClimbingStairsTest.cc - 0004_MinimumCostClimbingStairsTest.cc - 0005_HouseRobber1Test.cc - 0006_HouseRobber2Test.cc - 0007_DecodeWaysTest.cc - 0008_TilingProblemTest.cc - 0009_FriendsPairingProblemTest.cc - 0010_WaysToCoverDistanceTest.cc - 0011_CountWaysToReachNthStairIncludeOrderTest.cc - 0012_CountWaysToReachNthStairExcludeOrderTest.cc - 0013_KnapsackProblemTest.cc - 0014_SubsetSumProblemTest.cc - 0015_CountSubsetsForSumTest.cc - 0016_PartitionEqualSubsetSumTest.cc - 0017_TargetSumTest.cc - -) - -target_link_libraries( - 0005DynamicProgrammingTests - GTest::gtest_main - 0005DYNAMICPROGRAMMING -) - -# Add .clang-tidy configuration to this library. -if(CLANG_TIDY_EXE) - set_target_properties(0005DYNAMICPROGRAMMING PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") -endif() - -include(GoogleTest) -gtest_discover_tests(0005DynamicProgrammingTests DISCOVERY_TIMEOUT 30) \ No newline at end of file diff --git a/include/0004_GreedyAlgorithms/CMakeLists.txt b/tests/0005_greedy_algorithms/CMakeLists.txt similarity index 100% rename from include/0004_GreedyAlgorithms/CMakeLists.txt rename to tests/0005_greedy_algorithms/CMakeLists.txt diff --git a/tests/0006_BitwiseAlgorithms/CMakeLists.txt b/tests/0006_BitwiseAlgorithms/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/include/0005_DynamicProgramming/CMakeLists.txt b/tests/0006_bitwise_algorithms/CMakeLists.txt similarity index 100% rename from include/0005_DynamicProgramming/CMakeLists.txt rename to tests/0006_bitwise_algorithms/CMakeLists.txt diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 82c38df..41d781c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,7 @@ -add_subdirectory(0000_CommonUtilities) -add_subdirectory(0001_Basics) -add_subdirectory(0002_Tree) -add_subdirectory(0003_Graph) -add_subdirectory(0004_GreedyAlgorithms) -add_subdirectory(0005_DynamicProgramming) -add_subdirectory(0006_BitwiseAlgorithms) \ No newline at end of file +add_subdirectory(0000_common_utilities) +add_subdirectory(0001_basics) +add_subdirectory(0002_tree) +add_subdirectory(0003_graph) +add_subdirectory(0004_dynamic_programming) +add_subdirectory(0005_greedy_algorithms) +add_subdirectory(0006_bitwise_algorithms) \ No newline at end of file