diff --git a/Headers/0002_Tree/0001_BinarySearchTree.h b/Headers/0002_Tree/0001_BinarySearchTree.h index 5fac6bb..a66c568 100644 --- a/Headers/0002_Tree/0001_BinarySearchTree.h +++ b/Headers/0002_Tree/0001_BinarySearchTree.h @@ -3,43 +3,47 @@ #include #include using namespace std; -class Node + +namespace BinarySearchTree { -public: - int data; - Node* parent; - Node* left; - Node* right; + class Node + { + public: + int data; + Node* parent; + Node* left; + Node* right; - Node(int data, Node* parent, Node* left, Node* right); -}; + Node(int data, Node* parent, Node* left, Node* right); + }; -class BinarySearchTree -{ -private: - Node* _root; - void _InsertNode(Node* node); - Node* _FindNode(int value); - Node* _FindMinimumValueNode(Node* node); - Node* _FindMaximumValueNode(Node* node); - Node* _FindSuccessorNode(Node* node); - Node* _FindPredecessorNode(Node* node); - void _Transplant(Node* nodeU, Node* nodeV); - void _DeleteNode(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 + class BinarySearchTree + { + private: + Node* _root; + void _InsertNode(Node* node); + Node* _FindNode(int value); + Node* _FindMinimumValueNode(Node* node); + Node* _FindMaximumValueNode(Node* node); + Node* _FindSuccessorNode(Node* node); + Node* _FindPredecessorNode(Node* node); + void _Transplant(Node* nodeU, Node* nodeV); + void _DeleteNode(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/Headers/0003_Graph/0001_BreadthFirstSearch.h b/Headers/0003_Graph/0001_BreadthFirstSearch.h index 05324d8..5ce4bd7 100644 --- a/Headers/0003_Graph/0001_BreadthFirstSearch.h +++ b/Headers/0003_Graph/0001_BreadthFirstSearch.h @@ -6,27 +6,30 @@ #include #include using namespace std; -enum color { WHITE, GRAY, BLACK }; -class BFSNode +namespace BreadthFirstSearch { -public: - int data; - int distance; - int color; - BFSNode* parent; - BFSNode(int value); -}; + enum color { WHITE, GRAY, BLACK }; + class Node + { + public: + int data; + int distance; + int color; + Node* parent; + Node(int value); + }; -class BFSGraph -{ -private: - map> _adjlist; - map _nodeMap; - BFSNode* MakeOrFindNode(int value); - void BreadthFirstSearch(BFSNode* node); -public: - void PushUndirectedEdge(int valueU, int valueV); - void BFS(int value); - vector> ShowBFSResult(); -}; \ No newline at end of file + class Graph + { + private: + map> _adjlist; + map _nodeMap; + Node* MakeOrFindNode(int value); + void BreadthFirstSearch(Node* node); + public: + void PushUndirectedEdge(int valueU, int valueV); + void BFS(int value); + vector> ShowBFSResult(); + }; +} \ No newline at end of file diff --git a/Headers/0003_Graph/0002_DepthFirstSearch.h b/Headers/0003_Graph/0002_DepthFirstSearch.h index b53c9ad..957d4ad 100644 --- a/Headers/0003_Graph/0002_DepthFirstSearch.h +++ b/Headers/0003_Graph/0002_DepthFirstSearch.h @@ -5,29 +5,33 @@ #include #include using namespace std; -enum color { WHITE, GRAY, BLACK }; -class DFSNode +namespace DepthFirstSearch { -public: - int data; - int color; - int discoveredTime; - int finishingTime; - DFSNode* parent; - DFSNode(int value); -}; + enum color { WHITE, GRAY, BLACK }; -class DFSGraph -{ -private: - int time; - map> _adjlist; - map _nodeMap; - DFSNode* MakeOrFindNode(int value); - void DepthFirstSearch(DFSNode* DFSNode); -public: - void PushDirectedEdge(int valueU, int valueV); - void DFS(); - vector>> ShowDFSResult(); -}; \ No newline at end of file + class Node + { + public: + int data; + int color; + int discoveredTime; + int finishingTime; + Node* parent; + Node(int value); + }; + + class Graph + { + private: + int time; + map> _adjlist; + map _nodeMap; + Node* MakeOrFindNode(int value); + void DepthFirstSearch(Node* Node); + public: + void PushDirectedEdge(int valueU, int valueV); + void DFS(); + vector>> ShowDFSResult(); + }; +} \ No newline at end of file diff --git a/Headers/0003_Graph/0003_TopologicalSort.h b/Headers/0003_Graph/0003_TopologicalSort.h index b8d6d36..f3cac62 100644 --- a/Headers/0003_Graph/0003_TopologicalSort.h +++ b/Headers/0003_Graph/0003_TopologicalSort.h @@ -5,32 +5,36 @@ #include #include using namespace std; -enum color { WHITE, GRAY, BLACK }; -class TopologicalSortNode +namespace TopologicalSort { -public: - int data; - int color; - int discoveryTime; - int finishingTime; - TopologicalSortNode* parent; - TopologicalSortNode(int value); -}; + enum color { WHITE, GRAY, BLACK }; -class TopologicalSortGraph -{ -private: - int time; - bool hasCycle; - map> _adjlist; - map _nodeMap; - list _topologicalSortedNodeList; - TopologicalSortNode* MakeOrFindNode(int value); - void DepthFirstSearch(TopologicalSortNode* DFSNode); -public: - void PushDirectedEdge(int valueU, int valueV); - void PushSingleNode(int valueU); - void TopologicalSort(); - vector>> ShowTopologicalSortResult(); -}; \ No newline at end of file + class Node + { + public: + int data; + int color; + int discoveryTime; + int finishingTime; + Node* parent; + Node(int value); + }; + + class Graph + { + private: + int time; + bool hasCycle; + map> _adjlist; + map _nodeMap; + list _topologicalSortedNodeList; + Node* MakeOrFindNode(int value); + void DepthFirstSearch(Node* DFSNode); + public: + void PushDirectedEdge(int valueU, int valueV); + void PushSingleNode(int valueU); + void TopologicalSort(); + vector>> ShowTopologicalSortResult(); + }; +} \ No newline at end of file diff --git a/Headers/0003_Graph/0004_StronglyConnectedComponents.h b/Headers/0003_Graph/0004_StronglyConnectedComponents.h index 5993123..b5ebd91 100644 --- a/Headers/0003_Graph/0004_StronglyConnectedComponents.h +++ b/Headers/0003_Graph/0004_StronglyConnectedComponents.h @@ -5,35 +5,39 @@ #include #include using namespace std; -enum color { WHITE, GRAY, BLACK }; -class SCCNode +namespace StronglyConnectedComponents { -public: - int data; - int color; - int discoveryTime; - int finishingTime; - SCCNode* parent; - SCCNode(int value); -}; + enum color { WHITE, GRAY, BLACK }; -class StronglyConnectedComponentsGraph -{ -private: - int time; - map> _adjlistG; - map> _adjlistT; - map _nodeMap; - list _nodesFinishingTimeOrder; - vector> _allConnectedComponents; - SCCNode* MakeOrFindNode(int value); - void DepthFirstSearchOnGraphG(SCCNode* DFSNode); - void DepthFirstSearchOnGraphT(SCCNode* DFSNode, vector& connectedComponents); -public: - void PushDirectedEdge(int valueU, int valueV); - void PushSingleNode(int valueU); - void DFSOnGraphG(); - void DFSOnGraphT(); - vector> FindAllStronglyConnectedComponents(); -}; \ No newline at end of file + class Node + { + public: + int data; + int color; + int discoveryTime; + int finishingTime; + Node* parent; + Node(int value); + }; + + class Graph + { + private: + int time; + map> _adjlistG; + map> _adjlistT; + map _nodeMap; + list _nodesFinishingTimeOrder; + vector> _allConnectedComponents; + 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(); + }; +} \ No newline at end of file diff --git a/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h new file mode 100644 index 0000000..3cc6b09 --- /dev/null +++ b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include +using namespace std; + +namespace HamiltonianPathAndCycle +{ + class Node + { + public: + int data; + bool isVisited; + Node(int value); + }; + + class Graph + { + private: + bool _isHamiltonianCyclePresent; + bool _isHamiltonianPathPresent; + int _visitedNodeCount; + Node* _startingNode; + map> _adjlist; + map _nodeMap; + vector _hamiltonianPath; + 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(); + }; +} \ No newline at end of file diff --git a/SourceCodes/0002_Tree/0001_BinarySearchTree.cc b/SourceCodes/0002_Tree/0001_BinarySearchTree.cc index 8b4924f..ffb5624 100644 --- a/SourceCodes/0002_Tree/0001_BinarySearchTree.cc +++ b/SourceCodes/0002_Tree/0001_BinarySearchTree.cc @@ -3,345 +3,347 @@ #include using namespace std; - -Node::Node(int data, Node* parent, Node* left, Node* right) -{ - this->data = data; - this->parent = parent; - this->left = left; - this->right = right; -} - -BinarySearchTree::BinarySearchTree() -{ - this->_root = nullptr; -} - - -void BinarySearchTree::_InsertNode(Node* node) +namespace BinarySearchTree { - Node* nodeY = nullptr; - Node* nodeX = this->_root; - while (nodeX != nullptr) - { - nodeY = nodeX; - if (node->data < nodeX->data) - { - nodeX = nodeX->left; - } - else - { - nodeX = nodeX->right; - } - } - node->parent = nodeY; - if (nodeY == nullptr) - { - this->_root = node; - } - else if (node->data < nodeY->data) + Node::Node(int data, Node* parent, Node* left, Node* right) { - nodeY->left = node; + this->data = data; + this->parent = parent; + this->left = left; + this->right = right; } - else + + BinarySearchTree::BinarySearchTree() { - nodeY->right = node; + this->_root = nullptr; } -} -Node* BinarySearchTree::_FindNode(int value) -{ - Node* node = this->_root; - while (node != nullptr) + + void BinarySearchTree::_InsertNode(Node* node) { - if (value < node->data) + Node* nodeY = nullptr; + Node* nodeX = this->_root; + while (nodeX != nullptr) { - node = node->left; + nodeY = nodeX; + if (node->data < nodeX->data) + { + nodeX = nodeX->left; + } + else + { + nodeX = nodeX->right; + } } - else if(value > node->data) + node->parent = nodeY; + if (nodeY == nullptr) { - node = node->right; + this->_root = node; + } + else if (node->data < nodeY->data) + { + nodeY->left = node; } else { - break; + nodeY->right = node; } } - return node; -} -Node* BinarySearchTree::_FindMinimumValueNode(Node* node) -{ - while (node->left != nullptr) + Node* BinarySearchTree::_FindNode(int value) { - node = node->left; + Node* node = this->_root; + while (node != nullptr) + { + if (value < node->data) + { + node = node->left; + } + else if (value > node->data) + { + node = node->right; + } + else + { + break; + } + } + return node; } - return node; -} -Node* BinarySearchTree::_FindMaximumValueNode(Node* node) -{ - while (node->right != nullptr) + Node* BinarySearchTree::_FindMinimumValueNode(Node* node) { - node = node->right; + while (node->left != nullptr) + { + node = node->left; + } + return node; } - return node; -} -Node* BinarySearchTree::_FindSuccessorNode(Node* node) -{ - if (node->right != nullptr) + Node* BinarySearchTree::_FindMaximumValueNode(Node* node) { - return this->_FindMinimumValueNode(node->right); - } - Node* nodeY = node->parent; - while (nodeY != nullptr && node == nodeY->right) - { - node = nodeY; - nodeY = nodeY->parent; + while (node->right != nullptr) + { + node = node->right; + } + return node; } - return nodeY; -} -Node* BinarySearchTree::_FindPredecessorNode(Node* node) -{ - if (node->left != nullptr) - { - return this->_FindMaximumValueNode(node->left); - } - Node* nodeY = node->parent; - while (nodeY != nullptr && node == nodeY->left) + Node* BinarySearchTree::_FindSuccessorNode(Node* node) { - node = nodeY; - nodeY = nodeY->parent; + if (node->right != nullptr) + { + return this->_FindMinimumValueNode(node->right); + } + Node* nodeY = node->parent; + while (nodeY != nullptr && node == nodeY->right) + { + node = nodeY; + nodeY = nodeY->parent; + } + return nodeY; } - return nodeY; -} -void BinarySearchTree::_Transplant(Node* nodeU, Node* nodeV) -{ - if (nodeU->parent == nullptr) - { - this->_root = nodeV; - } - else if (nodeU == nodeU->parent->left) + Node* BinarySearchTree::_FindPredecessorNode(Node* node) { - nodeU->parent->left = nodeV; - } - else - { - nodeU->parent->right = nodeV; + if (node->left != nullptr) + { + return this->_FindMaximumValueNode(node->left); + } + Node* nodeY = node->parent; + while (nodeY != nullptr && node == nodeY->left) + { + node = nodeY; + nodeY = nodeY->parent; + } + return nodeY; } - if (nodeV != nullptr) + void BinarySearchTree::_Transplant(Node* nodeU, Node* nodeV) { - nodeV->parent = nodeU->parent; - } -} + if (nodeU->parent == nullptr) + { + this->_root = nodeV; + } + else if (nodeU == nodeU->parent->left) + { + nodeU->parent->left = nodeV; + } + else + { + nodeU->parent->right = nodeV; + } -void BinarySearchTree::_DeleteNode(Node* node) -{ - if (node->left == nullptr) - { - this->_Transplant(node, node->right); - } - else if (node->right == nullptr) - { - this->_Transplant(node, node->left); - } - else - { - Node* nodeY = this->_FindMinimumValueNode(node->right); - if (nodeY->parent != node) + if (nodeV != nullptr) { - this->_Transplant(nodeY, nodeY->right); - nodeY->right = node->right; - nodeY->right->parent = nodeY; + nodeV->parent = nodeU->parent; } - this->_Transplant(node, nodeY); - nodeY->left = node->left; - nodeY->left->parent = nodeY; - delete node; } -} -void BinarySearchTree::_RecursiveInorderTraversal(Node* node, vector& result) -{ - if (node == nullptr) + void BinarySearchTree::_DeleteNode(Node* node) { - return; + if (node->left == nullptr) + { + this->_Transplant(node, node->right); + } + else if (node->right == nullptr) + { + this->_Transplant(node, node->left); + } + else + { + Node* nodeY = this->_FindMinimumValueNode(node->right); + if (nodeY->parent != node) + { + this->_Transplant(nodeY, nodeY->right); + nodeY->right = node->right; + nodeY->right->parent = nodeY; + } + this->_Transplant(node, nodeY); + nodeY->left = node->left; + nodeY->left->parent = nodeY; + delete node; + } } - this->_RecursiveInorderTraversal(node->left, result); - result.push_back(node->data); - this->_RecursiveInorderTraversal(node->right, result); -} -void BinarySearchTree::_RecursivePreorderTraversal(Node* node, vector& result) -{ - if (node == nullptr) + void BinarySearchTree::_RecursiveInorderTraversal(Node* node, vector& result) { - return; + if (node == nullptr) + { + return; + } + this->_RecursiveInorderTraversal(node->left, result); + result.push_back(node->data); + this->_RecursiveInorderTraversal(node->right, result); } - result.push_back(node->data); - this->_RecursivePreorderTraversal(node->left, result); - this->_RecursivePreorderTraversal(node->right, result); -} -void BinarySearchTree::_RecursivePostorderTraversal(Node* node, vector& result) -{ - if (node == nullptr) + void BinarySearchTree::_RecursivePreorderTraversal(Node* node, vector& result) { - return; + if (node == nullptr) + { + return; + } + result.push_back(node->data); + this->_RecursivePreorderTraversal(node->left, result); + this->_RecursivePreorderTraversal(node->right, result); } - this->_RecursivePostorderTraversal(node->left, result); - this->_RecursivePostorderTraversal(node->right, result); - result.push_back(node->data); -} -void BinarySearchTree::_MorrisInorderTraversal(Node* node, vector& result) -{ - while (node != nullptr) + void BinarySearchTree::_RecursivePostorderTraversal(Node* node, vector& result) { - if (node->left == nullptr) + if (node == nullptr) { - result.push_back(node->data); - node = node->right; + return; } - else + this->_RecursivePostorderTraversal(node->left, result); + this->_RecursivePostorderTraversal(node->right, result); + result.push_back(node->data); + } + + void BinarySearchTree::_MorrisInorderTraversal(Node* node, vector& result) + { + while (node != nullptr) { - Node* predecessor = node->left; - while (predecessor->right != nullptr && predecessor->right != node) + if (node->left == nullptr) { - predecessor = predecessor->right; - } - if (predecessor->right == nullptr) - { - predecessor->right = node; - node = node->left; + result.push_back(node->data); + node = node->right; } else { - predecessor->right = nullptr; - result.push_back(node->data); - node = node->right; + Node* predecessor = node->left; + while (predecessor->right != nullptr && predecessor->right != node) + { + predecessor = predecessor->right; + } + if (predecessor->right == nullptr) + { + predecessor->right = node; + node = node->left; + } + else + { + predecessor->right = nullptr; + result.push_back(node->data); + node = node->right; + } } } } -} -void BinarySearchTree::_MorrisPreorderTraversal(Node* node, vector & result) -{ - while (node != nullptr) + void BinarySearchTree::_MorrisPreorderTraversal(Node* node, vector& result) { - if (node->left == nullptr) + while (node != nullptr) { - result.push_back(node->data); - node = node->right; - } - else - { - Node* predecessor = node->left; - while (predecessor->right != nullptr && predecessor->right != node) + if (node->left == nullptr) { - predecessor = predecessor->right; - } - if (predecessor->right == nullptr) - { - predecessor->right = node; result.push_back(node->data); - node = node->left; + node = node->right; } else { - predecessor->right = nullptr; - node = node->right; + Node* predecessor = node->left; + while (predecessor->right != nullptr && predecessor->right != node) + { + predecessor = predecessor->right; + } + if (predecessor->right == nullptr) + { + predecessor->right = node; + result.push_back(node->data); + node = node->left; + } + else + { + predecessor->right = nullptr; + node = node->right; + } } } } -} -void BinarySearchTree::_MorrisPostorderTraversal(Node* node, vector& result) -{ - while (node != nullptr) + void BinarySearchTree::_MorrisPostorderTraversal(Node* node, vector& result) { - if (node->right == nullptr) + while (node != nullptr) { - result.push_back(node->data); - node = node->left; - } - else - { - Node* predecessor = node->right; - while (predecessor->left != nullptr && predecessor->left != node) + if (node->right == nullptr) { - predecessor = predecessor->left; - } - if (predecessor->left == nullptr) - { - predecessor->left = node; result.push_back(node->data); - node = node->right; + node = node->left; } else { - predecessor->left = nullptr; - node = node->left; + Node* predecessor = node->right; + while (predecessor->left != nullptr && predecessor->left != node) + { + predecessor = predecessor->left; + } + if (predecessor->left == nullptr) + { + predecessor->left = node; + result.push_back(node->data); + node = node->right; + } + else + { + predecessor->left = nullptr; + node = node->left; + } } } + reverse(result.begin(), result.end()); } - reverse(result.begin(), result.end()); -} -void BinarySearchTree::InsertNode(int value) -{ - Node* node = new Node(value, nullptr, nullptr, nullptr); - this->_InsertNode(node); -} + void BinarySearchTree::InsertNode(int value) + { + Node* node = new Node(value, nullptr, nullptr, nullptr); + this->_InsertNode(node); + } -void BinarySearchTree::DeleteNode(int value) -{ - Node* node = this->_FindNode(value); - this->_DeleteNode(node); -} + void BinarySearchTree::DeleteNode(int value) + { + Node* node = this->_FindNode(value); + this->_DeleteNode(node); + } -vector BinarySearchTree::GetRecursiveInorderTravesalResult() -{ - vector result; - this->_RecursiveInorderTraversal(this->_root, result); - return result; -} + vector BinarySearchTree::GetRecursiveInorderTravesalResult() + { + vector result; + this->_RecursiveInorderTraversal(this->_root, result); + return result; + } -vector BinarySearchTree::GetRecursivePreorderTravesalResult() -{ - vector result; - this->_RecursivePreorderTraversal(this->_root, result); - return result; -} + vector BinarySearchTree::GetRecursivePreorderTravesalResult() + { + vector result; + this->_RecursivePreorderTraversal(this->_root, result); + return result; + } -vector BinarySearchTree::GetRecursivePostorderTravesalResult() -{ - vector result; - this->_RecursivePostorderTraversal(this->_root, result); - return result; -} + vector BinarySearchTree::GetRecursivePostorderTravesalResult() + { + vector result; + this->_RecursivePostorderTraversal(this->_root, result); + return result; + } -vector BinarySearchTree::GetMorrisInorderTraversalResult() -{ - vector result; - this->_MorrisInorderTraversal(this->_root, result); - return result; -} + vector BinarySearchTree::GetMorrisInorderTraversalResult() + { + vector result; + this->_MorrisInorderTraversal(this->_root, result); + return result; + } -vector BinarySearchTree::GetMorrisPreorderTraversalResult() -{ - vector result; - this->_MorrisPreorderTraversal(this->_root, result); - return result; -} + vector BinarySearchTree::GetMorrisPreorderTraversalResult() + { + vector result; + this->_MorrisPreorderTraversal(this->_root, result); + return result; + } -vector BinarySearchTree::GetMorrisPostorderTraversalResult() -{ - vector result; - this->_MorrisPostorderTraversal(this->_root, result); - return result; + vector BinarySearchTree::GetMorrisPostorderTraversalResult() + { + vector result; + this->_MorrisPostorderTraversal(this->_root, result); + return result; + } } \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0001_BreadthFirstSearch.cc b/SourceCodes/0003_Graph/0001_BreadthFirstSearch.cc index e29991b..0374ba2 100644 --- a/SourceCodes/0003_Graph/0001_BreadthFirstSearch.cc +++ b/SourceCodes/0003_Graph/0001_BreadthFirstSearch.cc @@ -7,77 +7,80 @@ #include using namespace std; -BFSNode::BFSNode(int value) +namespace BreadthFirstSearch { - this->data = value; - this->distance = INT_MAX; - this->color = WHITE; - this->parent = nullptr; -} - -BFSNode* BFSGraph::MakeOrFindNode(int value) -{ - BFSNode* node = nullptr; - if (this->_nodeMap.find(value) == this->_nodeMap.end()) + Node::Node(int value) { - node = new BFSNode(value); - this->_nodeMap[value] = node; + this->data = value; + this->distance = INT_MAX; + this->color = WHITE; + this->parent = nullptr; } - else + + Node* Graph::MakeOrFindNode(int value) { - node = this->_nodeMap[value]; + Node* node = nullptr; + if (this->_nodeMap.find(value) == this->_nodeMap.end()) + { + node = new Node(value); + this->_nodeMap[value] = node; + } + else + { + node = this->_nodeMap[value]; + } + return node; } - return node; -} - -void BFSGraph::BreadthFirstSearch(BFSNode* node) -{ - node->color = WHITE; - node->distance = 0; - node->parent = nullptr; - queue nodeQueue; - nodeQueue.push(node); - - while (nodeQueue.empty()!=true) + void Graph::BreadthFirstSearch(Node* node) { - BFSNode* currentNode = nodeQueue.front(); - nodeQueue.pop(); + node->color = WHITE; + node->distance = 0; + node->parent = nullptr; + + queue nodeQueue; + nodeQueue.push(node); - for (auto &adjacentNode : this->_adjlist[currentNode]) + while (nodeQueue.empty() != true) { - if (adjacentNode->color == WHITE) + Node* currentNode = nodeQueue.front(); + nodeQueue.pop(); + + for (auto& adjacentNode : this->_adjlist[currentNode]) { - adjacentNode->color = GRAY; - adjacentNode->parent = currentNode; - adjacentNode->distance = currentNode->distance + 1; - nodeQueue.push(adjacentNode); + if (adjacentNode->color == WHITE) + { + adjacentNode->color = GRAY; + adjacentNode->parent = currentNode; + adjacentNode->distance = currentNode->distance + 1; + nodeQueue.push(adjacentNode); + } } + currentNode->color = BLACK; } - currentNode->color = BLACK; } -} -void BFSGraph::PushUndirectedEdge(int valueU, int valueV) -{ - BFSNode* nodeU = this->MakeOrFindNode(valueU); - BFSNode* nodeV = this->MakeOrFindNode(valueV); + void Graph::PushUndirectedEdge(int valueU, int valueV) + { + Node* nodeU = this->MakeOrFindNode(valueU); + Node* nodeV = this->MakeOrFindNode(valueV); - this->_adjlist[nodeU].push_back(nodeV); - this->_adjlist[nodeV].push_back(nodeU); -} + this->_adjlist[nodeU].push_back(nodeV); + this->_adjlist[nodeV].push_back(nodeU); + } -void BFSGraph::BFS(int value) -{ - this->BreadthFirstSearch(this->_nodeMap[value]); -} + void Graph::BFS(int value) + { + this->BreadthFirstSearch(this->_nodeMap[value]); + } -vector> BFSGraph::ShowBFSResult() -{ - vector> result; - for (auto& node : this->_nodeMap) + vector> Graph::ShowBFSResult() { - result.push_back(make_pair(node.first, node.second->distance)); + vector> result; + for (auto& node : this->_nodeMap) + { + result.push_back(make_pair(node.first, node.second->distance)); + } + return result; } - return result; } \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0002_DepthFirstSearch.cc b/SourceCodes/0003_Graph/0002_DepthFirstSearch.cc index bf0bb4f..2439708 100644 --- a/SourceCodes/0003_Graph/0002_DepthFirstSearch.cc +++ b/SourceCodes/0003_Graph/0002_DepthFirstSearch.cc @@ -4,74 +4,77 @@ #include using namespace std; -DFSNode::DFSNode(int value) +namespace DepthFirstSearch { - this->data = value; - this->discoveredTime = INT_MAX; - this->finishingTime = INT_MAX; - this->color = WHITE; - this->parent = nullptr; -} - -DFSNode* DFSGraph::MakeOrFindNode(int value) -{ - DFSNode* node = nullptr; - if (this->_nodeMap.find(value) == this->_nodeMap.end()) + Node::Node(int value) { - node = new DFSNode(value); - this->_nodeMap[value] = node; + this->data = value; + this->discoveredTime = INT_MAX; + this->finishingTime = INT_MAX; + this->color = WHITE; + this->parent = nullptr; } - else + + Node* Graph::MakeOrFindNode(int value) { - node = this->_nodeMap[value]; + Node* node = nullptr; + if (this->_nodeMap.find(value) == this->_nodeMap.end()) + { + node = new Node(value); + this->_nodeMap[value] = node; + } + else + { + node = this->_nodeMap[value]; + } + return node; } - return node; -} -void DFSGraph::DepthFirstSearch(DFSNode* nodeU) -{ - this->time++; - nodeU->discoveredTime = this->time; - nodeU->color = GRAY; - for (auto nodeV : this->_adjlist[nodeU]) + void Graph::DepthFirstSearch(Node* nodeU) { - if (nodeV->color == WHITE) + this->time++; + nodeU->discoveredTime = this->time; + nodeU->color = GRAY; + for (auto nodeV : this->_adjlist[nodeU]) { - nodeV->parent = nodeU; - this->DepthFirstSearch(nodeV); + if (nodeV->color == WHITE) + { + nodeV->parent = nodeU; + this->DepthFirstSearch(nodeV); + } } + nodeU->color = BLACK; + this->time++; + nodeU->finishingTime = time; } - nodeU->color = BLACK; - this->time++; - nodeU->finishingTime = time; -} -void DFSGraph::PushDirectedEdge(int valueU, int valueV) -{ - DFSNode* nodeU = this->MakeOrFindNode(valueU); - DFSNode* nodeV = this->MakeOrFindNode(valueV); + void Graph::PushDirectedEdge(int valueU, int valueV) + { + Node* nodeU = this->MakeOrFindNode(valueU); + Node* nodeV = this->MakeOrFindNode(valueV); - this->_adjlist[nodeU].push_back(nodeV); -} + this->_adjlist[nodeU].push_back(nodeV); + } -void DFSGraph::DFS() -{ - this->time = 0; - for (auto& iterator:this->_nodeMap) + void Graph::DFS() { - if (iterator.second->color == WHITE) + this->time = 0; + for (auto& iterator : this->_nodeMap) { - this->DepthFirstSearch(iterator.second); + if (iterator.second->color == WHITE) + { + this->DepthFirstSearch(iterator.second); + } } } -} -vector>> DFSGraph::ShowDFSResult() -{ - vector>> result; - for (auto& node : this->_nodeMap) + vector>> Graph::ShowDFSResult() { - result.push_back(make_pair(node.first, make_pair(node.second->discoveredTime, node.second->finishingTime))); + vector>> result; + for (auto& node : this->_nodeMap) + { + result.push_back(make_pair(node.first, make_pair(node.second->discoveredTime, node.second->finishingTime))); + } + return result; } - return result; } \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0003_TopologicalSort.cc b/SourceCodes/0003_Graph/0003_TopologicalSort.cc index c98925e..18dd52a 100644 --- a/SourceCodes/0003_Graph/0003_TopologicalSort.cc +++ b/SourceCodes/0003_Graph/0003_TopologicalSort.cc @@ -5,93 +5,96 @@ #include using namespace std; -TopologicalSortNode::TopologicalSortNode(int value) +namespace TopologicalSort { - this->data = value; - this->discoveryTime = INT_MAX; - this->finishingTime = INT_MAX; - this->color = WHITE; - this->parent = nullptr; -} - -TopologicalSortNode* TopologicalSortGraph::MakeOrFindNode(int value) -{ - TopologicalSortNode* node = nullptr; - if (this->_nodeMap.find(value) == this->_nodeMap.end()) - { - node = new TopologicalSortNode(value); - this->_nodeMap[value] = node; - } - else + Node::Node(int value) { - node = this->_nodeMap[value]; + this->data = value; + this->discoveryTime = INT_MAX; + this->finishingTime = INT_MAX; + this->color = WHITE; + this->parent = nullptr; } - return node; -} -void TopologicalSortGraph::DepthFirstSearch(TopologicalSortNode* nodeU) -{ - this->time++; - nodeU->discoveryTime = this->time; - nodeU->color = GRAY; - for (auto nodeV : this->_adjlist[nodeU]) + Node* Graph::MakeOrFindNode(int value) { - if (nodeV->color == WHITE) + Node* node = nullptr; + if (this->_nodeMap.find(value) == this->_nodeMap.end()) { - nodeV->parent = nodeU; - this->DepthFirstSearch(nodeV); + node = new Node(value); + this->_nodeMap[value] = node; } - else if (nodeV->color == GRAY) + else { - this->hasCycle = true; - return; + node = this->_nodeMap[value]; } + return node; } - nodeU->color = BLACK; - this->time++; - nodeU->finishingTime = time; - this->_topologicalSortedNodeList.push_front(nodeU); -} -void TopologicalSortGraph::PushDirectedEdge(int valueU, int valueV) -{ - TopologicalSortNode* nodeU = this->MakeOrFindNode(valueU); - TopologicalSortNode* nodeV = this->MakeOrFindNode(valueV); + void Graph::DepthFirstSearch(Node* nodeU) + { + this->time++; + nodeU->discoveryTime = this->time; + nodeU->color = GRAY; + for (auto nodeV : this->_adjlist[nodeU]) + { + if (nodeV->color == WHITE) + { + nodeV->parent = nodeU; + this->DepthFirstSearch(nodeV); + } + else if (nodeV->color == GRAY) + { + this->hasCycle = true; + return; + } + } + nodeU->color = BLACK; + this->time++; + nodeU->finishingTime = time; + this->_topologicalSortedNodeList.push_front(nodeU); + } - this->_adjlist[nodeU].push_back(nodeV); -} + void Graph::PushDirectedEdge(int valueU, int valueV) + { + Node* nodeU = this->MakeOrFindNode(valueU); + Node* nodeV = this->MakeOrFindNode(valueV); -void TopologicalSortGraph::PushSingleNode(int valueU) -{ - TopologicalSortNode* nodeU = this->MakeOrFindNode(valueU); -} + this->_adjlist[nodeU].push_back(nodeV); + } -void TopologicalSortGraph::TopologicalSort() -{ - this->time = 0; - for (auto& iterator : this->_nodeMap) + void Graph::PushSingleNode(int valueU) + { + Node* nodeU = this->MakeOrFindNode(valueU); + } + + void Graph::TopologicalSort() { - if (iterator.second->color == WHITE) + this->time = 0; + for (auto& iterator : this->_nodeMap) { - this->DepthFirstSearch(iterator.second); - if (this->hasCycle == true) + if (iterator.second->color == WHITE) { - break; + this->DepthFirstSearch(iterator.second); + if (this->hasCycle == true) + { + break; + } } } } -} -vector>> TopologicalSortGraph::ShowTopologicalSortResult() -{ - if (this->hasCycle == true) - { - throw runtime_error("Cycle Detected"); - } - vector>> result; - for (auto& node : this->_topologicalSortedNodeList) + vector>> Graph::ShowTopologicalSortResult() { - result.push_back(make_pair(node->data, make_pair(node->discoveryTime, node->finishingTime))); + if (this->hasCycle == true) + { + throw runtime_error("Cycle Detected"); + } + vector>> result; + for (auto& node : this->_topologicalSortedNodeList) + { + result.push_back(make_pair(node->data, make_pair(node->discoveryTime, node->finishingTime))); + } + return result; } - return result; } \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0004_StronglyConnectedComponents.cc b/SourceCodes/0003_Graph/0004_StronglyConnectedComponents.cc index 1e2677b..abd218e 100644 --- a/SourceCodes/0003_Graph/0004_StronglyConnectedComponents.cc +++ b/SourceCodes/0003_Graph/0004_StronglyConnectedComponents.cc @@ -4,115 +4,118 @@ #include using namespace std; -SCCNode::SCCNode(int value) +namespace StronglyConnectedComponents { - this->data = value; - this->discoveryTime = INT_MAX; - this->finishingTime = INT_MAX; - this->color = WHITE; - this->parent = nullptr; -} - -SCCNode* StronglyConnectedComponentsGraph::MakeOrFindNode(int value) -{ - SCCNode* node = nullptr; - if (this->_nodeMap.find(value) == this->_nodeMap.end()) + Node::Node(int value) { - node = new SCCNode(value); - this->_nodeMap[value] = node; + this->data = value; + this->discoveryTime = INT_MAX; + this->finishingTime = INT_MAX; + this->color = WHITE; + this->parent = nullptr; } - else + + Node* Graph::MakeOrFindNode(int value) { - node = this->_nodeMap[value]; + Node* node = nullptr; + if (this->_nodeMap.find(value) == this->_nodeMap.end()) + { + node = new Node(value); + this->_nodeMap[value] = node; + } + else + { + node = this->_nodeMap[value]; + } + return node; } - return node; -} -void StronglyConnectedComponentsGraph::DepthFirstSearchOnGraphG(SCCNode* nodeU) -{ - this->time++; - nodeU->discoveryTime = this->time; - nodeU->color = GRAY; - for (auto nodeV : this->_adjlistG[nodeU]) + void Graph::DepthFirstSearchOnGraphG(Node* nodeU) { - if (nodeV->color == WHITE) + this->time++; + nodeU->discoveryTime = this->time; + nodeU->color = GRAY; + for (auto nodeV : this->_adjlistG[nodeU]) { - nodeV->parent = nodeU; - this->DepthFirstSearchOnGraphG(nodeV); + if (nodeV->color == WHITE) + { + nodeV->parent = nodeU; + this->DepthFirstSearchOnGraphG(nodeV); + } } + nodeU->color = BLACK; + this->time++; + nodeU->finishingTime = time; + this->_nodesFinishingTimeOrder.push_front(nodeU); } - nodeU->color = BLACK; - this->time++; - nodeU->finishingTime = time; - this->_nodesFinishingTimeOrder.push_front(nodeU); -} -void StronglyConnectedComponentsGraph::DepthFirstSearchOnGraphT(SCCNode* nodeU, vector& connectedComponents) -{ - nodeU->color = GRAY; - connectedComponents.push_back(nodeU->data); - for (auto nodeV : this->_adjlistT[nodeU]) + void Graph::DepthFirstSearchOnGraphT(Node* nodeU, vector& connectedComponents) { - if (nodeV->color == WHITE) + nodeU->color = GRAY; + connectedComponents.push_back(nodeU->data); + for (auto nodeV : this->_adjlistT[nodeU]) { - nodeV->parent = nodeU; - this->DepthFirstSearchOnGraphT(nodeV, connectedComponents); + if (nodeV->color == WHITE) + { + nodeV->parent = nodeU; + this->DepthFirstSearchOnGraphT(nodeV, connectedComponents); + } } + nodeU->color = BLACK; } - nodeU->color = BLACK; -} -void StronglyConnectedComponentsGraph::PushDirectedEdge(int valueU, int valueV) -{ - SCCNode* nodeU = this->MakeOrFindNode(valueU); - SCCNode* nodeV = this->MakeOrFindNode(valueV); + void Graph::PushDirectedEdge(int valueU, int valueV) + { + Node* nodeU = this->MakeOrFindNode(valueU); + Node* nodeV = this->MakeOrFindNode(valueV); - // Creating the actual graph. - this->_adjlistG[nodeU].push_back(nodeV); + // Creating the actual graph. + this->_adjlistG[nodeU].push_back(nodeV); - // Creating the transpose of the actual graph. - this->_adjlistT[nodeV].push_back(nodeU); -} + // Creating the transpose of the actual graph. + this->_adjlistT[nodeV].push_back(nodeU); + } -void StronglyConnectedComponentsGraph::PushSingleNode(int valueU) -{ - SCCNode* nodeU = this->MakeOrFindNode(valueU); -} + void Graph::PushSingleNode(int valueU) + { + Node* nodeU = this->MakeOrFindNode(valueU); + } -void StronglyConnectedComponentsGraph::DFSOnGraphG() -{ - this->time = 0; - for (auto& iterator : this->_nodeMap) + void Graph::DFSOnGraphG() { - if (iterator.second->color == WHITE) + this->time = 0; + for (auto& iterator : this->_nodeMap) { - this->DepthFirstSearchOnGraphG(iterator.second); + if (iterator.second->color == WHITE) + { + this->DepthFirstSearchOnGraphG(iterator.second); + } } } -} -void StronglyConnectedComponentsGraph::DFSOnGraphT() -{ - for (auto& iterator : this->_nodeMap) + void Graph::DFSOnGraphT() { - iterator.second->color = WHITE; - iterator.second->parent = nullptr; - } + for (auto& iterator : this->_nodeMap) + { + iterator.second->color = WHITE; + iterator.second->parent = nullptr; + } - for (auto& iterator : this->_nodesFinishingTimeOrder) - { - if (iterator->color == WHITE) + for (auto& iterator : this->_nodesFinishingTimeOrder) { - vector connectedComponents; - this->DepthFirstSearchOnGraphT(iterator, connectedComponents); - this->_allConnectedComponents.push_back(connectedComponents); + if (iterator->color == WHITE) + { + vector connectedComponents; + this->DepthFirstSearchOnGraphT(iterator, connectedComponents); + this->_allConnectedComponents.push_back(connectedComponents); + } } } -} -vector> StronglyConnectedComponentsGraph::FindAllStronglyConnectedComponents() -{ - this->DFSOnGraphG(); - this->DFSOnGraphT(); - return this->_allConnectedComponents; + vector> Graph::FindAllStronglyConnectedComponents() + { + this->DFSOnGraphG(); + this->DFSOnGraphT(); + return this->_allConnectedComponents; + } } \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc b/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc new file mode 100644 index 0000000..7385b62 --- /dev/null +++ b/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc @@ -0,0 +1,114 @@ +#include "../Headers/0003_Graph/0005_HamiltonianPathAndCycle.h" + +using namespace std; +namespace HamiltonianPathAndCycle +{ + Node::Node(int value) + { + this->data = value; + this->isVisited = false; + } + + // Graph Private Member Methods + Node* Graph::MakeOrFindNode(int value) + { + Node* node = nullptr; + if (this->_nodeMap.find(value) == this->_nodeMap.end()) + { + node = new Node(value); + this->_nodeMap[value] = node; + } + else + { + node = this->_nodeMap[value]; + } + return node; + } + + bool Graph::IsSafe(Node* nodeU, Node* nodeV) + { + if (this->_adjlist[nodeU].find(nodeV) == this->_adjlist[nodeU].end()) + { + return false; + } + if (nodeV->isVisited == true) + { + return false; + } + return true; + } + + bool Graph::HamiltonianCycleAndPathUtil(Node* nodeU) + { + if (this->_visitedNodeCount == this->_nodeMap.size()) + { + if (this->_adjlist[nodeU].find(this->_startingNode) != this->_adjlist[nodeU].end()) + { + this->_isHamiltonianCyclePresent = true; + this->_isHamiltonianPathPresent = true; + return true; + } + this->_isHamiltonianPathPresent = true; + return false; + } + for (auto& nodeV : this->_adjlist[nodeU]) + { + if (this->IsSafe(nodeU, nodeV)) + { + this->_hamiltonianPath.push_back(nodeV->data); + nodeV->isVisited = true; + this->_visitedNodeCount++; + if (this->HamiltonianCycleAndPathUtil(nodeV)) + { + return true; + } + this->_visitedNodeCount--; + nodeV->isVisited = false; + this->_hamiltonianPath.pop_back(); + } + } + return false; + } + + // Graph Public Member Methods + void Graph::PushUndirectedEdge(int valueU, int 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) + { + Node* nodeU = this->MakeOrFindNode(valueU); + } + + void Graph::FindHamiltonianCycleAndPath() + { + this->_isHamiltonianCyclePresent = false; + this->_isHamiltonianPathPresent = false; + this->_hamiltonianPath = {}; + this->_startingNode = this->_nodeMap[0]; + this->_hamiltonianPath.push_back(this->_startingNode->data); + this->_startingNode->isVisited = true; + this->_visitedNodeCount = 1; + this->HamiltonianCycleAndPathUtil(this->_startingNode); + } + + bool Graph::IsHamiltonianCyclePresent() + { + return this->_isHamiltonianCyclePresent; + } + + bool Graph::IsHamiltonianPathPresent() + { + return this->_isHamiltonianPathPresent; + } + + vector Graph::GetHamiltonianPath() + { + return this->_hamiltonianPath; + } +} \ No newline at end of file diff --git a/SourceCodes/0003_Graph/CMakeLists.txt b/SourceCodes/0003_Graph/CMakeLists.txt index 9df817b..39f75fb 100644 --- a/SourceCodes/0003_Graph/CMakeLists.txt +++ b/SourceCodes/0003_Graph/CMakeLists.txt @@ -4,6 +4,7 @@ set(0003GRAPH_SOURCES 0002_DepthFirstSearch.cc 0003_TopologicalSort.cc 0004_StronglyConnectedComponents.cc + 0005_HamiltonianPathAndCycle.cc ) # Create a library target diff --git a/Tests/0000_CommonUtilities/UnitTestHelper.h b/Tests/0000_CommonUtilities/UnitTestHelper.h index 9ab647a..6faf4e5 100644 --- a/Tests/0000_CommonUtilities/UnitTestHelper.h +++ b/Tests/0000_CommonUtilities/UnitTestHelper.h @@ -3,13 +3,14 @@ #include #include #include +#include using namespace std; class UnitTestHelper { public: template - string VerifyVectorResult(vector vector) + string SerializeVectorToString(vector vector) { string result = ""; for (auto& iterator : vector) @@ -21,7 +22,7 @@ class UnitTestHelper } template - string VerifyVectorResult(vector> vector) + string SerializeVectorToString(vector> vector) { string result = ""; for (auto& iterator : vector) @@ -37,7 +38,7 @@ class UnitTestHelper } template - string VerifyVectorResult(vector>> vector) + string SerializeVectorToString(vector>> vector) { string result = ""; for (auto& iterator : vector) @@ -53,7 +54,7 @@ class UnitTestHelper } template - string VerifyVectorResult(vector> vector) + string SerializeVectorToString(vector> vector) { string result = ""; for (auto& iterator : vector) @@ -71,4 +72,68 @@ 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. + template + vector> SortVectorOfVectors(vector> data) + { + // 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. + sort(data.begin(), data.end(), [](const vector& a, const vector& b) + { + // 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. + if (a.empty()) + return true; + + // Considering non-empty vector as greater than empty vector. + if (b.empty()) + return false; + + // Comparing the first elements of each vector. + return (a[0] < b[0]); + }); + + return data; + } + + template + bool NormalizeCyclesAnCompare(vector data1, vector data2) + { + if (data1.size() != data2.size()) + { + return false; + } + + // 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 + vector normalizedCycle2(data2); + auto minIterator2 = min_element(normalizedCycle2.begin(), normalizedCycle2.end()); + rotate(normalizedCycle2.begin(), minIterator2, normalizedCycle2.end()); + + // Check clock wise + if (normalizedCycle1 == normalizedCycle2) + { + return true; + } + + // Check counter clock wise + reverse(normalizedCycle2.begin() + 1, normalizedCycle2.end()); + return (normalizedCycle1 == normalizedCycle2); + } }; \ No newline at end of file diff --git a/Tests/0002_Tree/0001_BinarySearchTreeTest.cc b/Tests/0002_Tree/0001_BinarySearchTreeTest.cc index 65a5090..7a73afd 100644 --- a/Tests/0002_Tree/0001_BinarySearchTreeTest.cc +++ b/Tests/0002_Tree/0001_BinarySearchTreeTest.cc @@ -3,7 +3,7 @@ #include "../Headers/0002_Tree/0001_BinarySearchTree.h" #include "../0000_CommonUtilities/UnitTestHelper.h" -namespace BinarySearchTreeTest +namespace BinarySearchTree { UnitTestHelper unitTestHelper; @@ -15,7 +15,7 @@ namespace BinarySearchTreeTest bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetRecursiveInorderTravesalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetRecursiveInorderTravesalResult()); string expectedResult = "30 50 60"; EXPECT_EQ(actualResult, expectedResult); @@ -28,7 +28,7 @@ namespace BinarySearchTreeTest bst.InsertNode(30); bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetRecursivePreorderTravesalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetRecursivePreorderTravesalResult()); string expectedResult = "50 30 60"; EXPECT_EQ(actualResult, expectedResult); @@ -41,7 +41,7 @@ namespace BinarySearchTreeTest bst.InsertNode(30); bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetRecursivePostorderTravesalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetRecursivePostorderTravesalResult()); string expectedResult = "30 60 50"; EXPECT_EQ(actualResult, expectedResult); @@ -55,7 +55,7 @@ namespace BinarySearchTreeTest bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetMorrisInorderTraversalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetMorrisInorderTraversalResult()); string expectedResult = "30 50 60"; EXPECT_EQ(actualResult, expectedResult); @@ -69,7 +69,7 @@ namespace BinarySearchTreeTest bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetMorrisPreorderTraversalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetMorrisPreorderTraversalResult()); string expectedResult = "50 30 60"; EXPECT_EQ(actualResult, expectedResult); @@ -83,7 +83,7 @@ namespace BinarySearchTreeTest bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetMorrisPostorderTraversalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetMorrisPostorderTraversalResult()); string expectedResult = "30 60 50"; EXPECT_EQ(actualResult, expectedResult); diff --git a/Tests/0003_Graph/0001_BreadthFirstSearchTest.cc b/Tests/0003_Graph/0001_BreadthFirstSearchTest.cc index e24870f..26c731f 100644 --- a/Tests/0003_Graph/0001_BreadthFirstSearchTest.cc +++ b/Tests/0003_Graph/0001_BreadthFirstSearchTest.cc @@ -3,14 +3,14 @@ #include "../Headers/0003_Graph/0001_BreadthFirstSearch.h" #include "../0000_CommonUtilities/UnitTestHelper.h" -namespace BreadthFirstSearchTest +namespace BreadthFirstSearch { UnitTestHelper unitTestHelper; TEST(BFSTesting, ShowBFSResultTest01) { - BFSGraph graph; + Graph graph; graph.PushUndirectedEdge(1, 2); graph.PushUndirectedEdge(1, 3); @@ -25,20 +25,20 @@ namespace BreadthFirstSearchTest graph.BFS(1); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowBFSResult()); + 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) { - BFSGraph graph; + Graph graph; graph.PushUndirectedEdge(1, 2); graph.BFS(1); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowBFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowBFSResult()); string expectedResult = "1(0) 2(1)"; EXPECT_EQ(actualResult, expectedResult); } diff --git a/Tests/0003_Graph/0002_DepthFirstSearchTest.cc b/Tests/0003_Graph/0002_DepthFirstSearchTest.cc index 3fd7841..9bb257b 100644 --- a/Tests/0003_Graph/0002_DepthFirstSearchTest.cc +++ b/Tests/0003_Graph/0002_DepthFirstSearchTest.cc @@ -2,13 +2,13 @@ #include "../Headers/0003_Graph/0002_DepthFirstSearch.h" #include "../0000_CommonUtilities/UnitTestHelper.h" -namespace DepthFirstSearchTest +namespace DepthFirstSearch { UnitTestHelper unitTestHelper; TEST(DFSTesting, ShowDFSResultTest01) { - DFSGraph graph; + Graph graph; graph.PushDirectedEdge(1, 2); graph.PushDirectedEdge(1, 4); @@ -21,7 +21,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + 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); } @@ -29,34 +29,34 @@ namespace DepthFirstSearchTest TEST(DFSTesting, ShowDFSResultTest_SingleVertex) { - DFSGraph graph; + Graph graph; graph.PushDirectedEdge(1, 1); graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,2)"; EXPECT_EQ(actualResult, expectedResult); } TEST(DFSTesting, ShowDFSResultTest_DisconnectedGraph) { - DFSGraph graph; + Graph graph; graph.PushDirectedEdge(1, 2); graph.PushDirectedEdge(3, 4); graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + 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) { - DFSGraph graph; + Graph graph; graph.PushDirectedEdge(1, 2); graph.PushDirectedEdge(2, 3); @@ -64,14 +64,14 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + 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) { - DFSGraph graph; + Graph graph; // Adding 15 nodes with several edges graph.PushDirectedEdge(1, 2); @@ -92,14 +92,14 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + 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) { - DFSGraph graph; + Graph graph; // Adding isolated nodes graph.PushDirectedEdge(1, 1); @@ -108,14 +108,14 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + 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) { - DFSGraph graph; + Graph graph; // Creating a cycle with back edges graph.PushDirectedEdge(1, 2); @@ -125,14 +125,14 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + 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) { - DFSGraph graph; + Graph graph; // Complete graph of 4 nodes graph.PushDirectedEdge(1, 2); @@ -150,14 +150,14 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + 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) { - DFSGraph graph; + Graph graph; // Adding self-loops and parallel edges graph.PushDirectedEdge(1, 1); @@ -169,7 +169,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,6) 2(2,5) 3(3,4)"; EXPECT_EQ(actualResult, expectedResult); } diff --git a/Tests/0003_Graph/0003_TopologicalSortTest.cc b/Tests/0003_Graph/0003_TopologicalSortTest.cc index 4eea735..b069e2e 100644 --- a/Tests/0003_Graph/0003_TopologicalSortTest.cc +++ b/Tests/0003_Graph/0003_TopologicalSortTest.cc @@ -2,13 +2,13 @@ #include "../Headers/0003_Graph/0003_TopologicalSort.h" #include "../0000_CommonUtilities/UnitTestHelper.h" -namespace TopologicalSortTest +namespace TopologicalSort { UnitTestHelper unitTestHelper; TEST(TopoSortTesting, ShowTopoSortResult) { - TopologicalSortGraph graph; + Graph graph; graph.PushDirectedEdge(1, 2); graph.PushDirectedEdge(1, 4); @@ -23,7 +23,7 @@ namespace TopologicalSortTest graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + 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); @@ -32,7 +32,7 @@ namespace TopologicalSortTest // Test with a larger graph and multiple paths between nodes TEST(TopoSortTesting, LargeGraphMultiplePaths) { - TopologicalSortGraph graph; + Graph graph; graph.PushDirectedEdge(1, 2); graph.PushDirectedEdge(1, 3); graph.PushDirectedEdge(2, 4); @@ -42,7 +42,7 @@ namespace TopologicalSortTest graph.PushDirectedEdge(6, 7); graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + 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); @@ -51,13 +51,13 @@ namespace TopologicalSortTest // Test with a graph containing disconnected components TEST(TopoSortTesting, DisconnectedGraph) { - TopologicalSortGraph graph; + Graph graph; graph.PushDirectedEdge(1, 2); graph.PushDirectedEdge(3, 4); graph.PushDirectedEdge(5, 6); graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + 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); @@ -66,13 +66,13 @@ namespace TopologicalSortTest // Test with a graph that has multiple nodes pointing to the same node TEST(TopoSortTesting, MultipleIncomingEdges) { - TopologicalSortGraph graph; + Graph graph; graph.PushDirectedEdge(1, 3); graph.PushDirectedEdge(2, 3); graph.PushDirectedEdge(3, 4); graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); string expectedResult = "2(7,8) 1(1,6) 3(2,5) 4(3,4)"; EXPECT_EQ(actualResult, expectedResult); @@ -81,11 +81,11 @@ namespace TopologicalSortTest // Test for a single-node graph to check the base case TEST(TopoSortTesting, SingleNodeGraph) { - TopologicalSortGraph graph; + Graph graph; graph.PushSingleNode(1); graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); string expectedResult = "1(1,2)"; EXPECT_EQ(actualResult, expectedResult); @@ -94,7 +94,7 @@ namespace TopologicalSortTest // Test with a cyclic graph to verify it can detect cycles (assuming cycle detection is implemented) TEST(TopoSortTesting, CyclicGraph) { - TopologicalSortGraph graph; + Graph graph; graph.PushDirectedEdge(1, 2); graph.PushDirectedEdge(2, 3); graph.PushDirectedEdge(3, 1); // Cycle: 1 -> 2 -> 3 -> 1 diff --git a/Tests/0003_Graph/0004_StronglyConnectedComponentsTest.cc b/Tests/0003_Graph/0004_StronglyConnectedComponentsTest.cc index cc245e6..0f58496 100644 --- a/Tests/0003_Graph/0004_StronglyConnectedComponentsTest.cc +++ b/Tests/0003_Graph/0004_StronglyConnectedComponentsTest.cc @@ -2,13 +2,14 @@ #include "../Headers/0003_Graph/0004_StronglyConnectedComponents.h" #include "../0000_CommonUtilities/UnitTestHelper.h" -namespace StronglyConnectedComponentsTest +namespace StronglyConnectedComponents { UnitTestHelper unitTestHelper; + // Test case: Testing with a simple graph. TEST(StronglyConnectedComponentsTesting, SimpleGraphTest) { - StronglyConnectedComponentsGraph graph; + Graph graph; graph.PushDirectedEdge(1, 2); graph.PushDirectedEdge(1, 5); @@ -25,8 +26,77 @@ namespace StronglyConnectedComponentsTest graph.PushDirectedEdge(7, 8); graph.PushDirectedEdge(8, 6); - string actualResult = unitTestHelper.VerifyVectorResult(graph.FindAllStronglyConnectedComponents()); - string expectedResult = "[6 8 7][1 5][2 3][4]"; - EXPECT_EQ(actualResult, expectedResult); + 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 new file mode 100644 index 0000000..386825d --- /dev/null +++ b/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc @@ -0,0 +1,33 @@ +#include +#include "../Headers/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.NormalizeCyclesAnCompare(hamiltonianPathActualResult, hamiltonianPathExpectedResult)); + } +} \ No newline at end of file diff --git a/Tests/0003_Graph/CMakeLists.txt b/Tests/0003_Graph/CMakeLists.txt index b43d3d3..e58a3c7 100644 --- a/Tests/0003_Graph/CMakeLists.txt +++ b/Tests/0003_Graph/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable( 0002_DepthFirstSearchTest.cc 0003_TopologicalSortTest.cc 0004_StronglyConnectedComponentsTest.cc + 0005_HamiltonianPathAndCycleTest.cc ) target_link_libraries(