From 224913e49465324f5fdbbce253970303fc581eb1 Mon Sep 17 00:00:00 2001 From: balanarayank <28087097+balanarayank@users.noreply.github.com> Date: Tue, 17 May 2022 20:58:15 +0530 Subject: [PATCH 1/4] Cleaning up for re-writing more simple code --- CMakeLists.txt | 6 - src/CMakeLists.txt | 7 - src/DoublyLinkedList/DoublyLinkedList.h | 175 ------------- src/SinglyLinkedList/SinglyLinkedList.h | 131 ---------- src/main.cpp | 39 --- tests/CMakeLists.txt | 19 -- tests/DoublyLinkedList/DoublyLinkedList_ut.h | 244 ------------------- tests/SinglyLinkedList/SinglyLinkedList_ut.h | 220 ----------------- tests/main_ut.cc | 7 - 9 files changed, 848 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 src/CMakeLists.txt delete mode 100644 src/DoublyLinkedList/DoublyLinkedList.h delete mode 100644 src/SinglyLinkedList/SinglyLinkedList.h delete mode 100644 src/main.cpp delete mode 100644 tests/CMakeLists.txt delete mode 100644 tests/DoublyLinkedList/DoublyLinkedList_ut.h delete mode 100644 tests/SinglyLinkedList/SinglyLinkedList_ut.h delete mode 100644 tests/main_ut.cc diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 9dc3979..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -project(simple-datastructures-cpp) -cmake_minimum_required(VERSION 3.0) -add_subdirectory(src) -add_subdirectory(tests) -enable_testing() -add_test(NAME datastructures-cpp-ut COMMAND tests/datastructures-cpp-ut) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index a3f7995..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -project(datastructures-cpp-example) -cmake_minimum_required(VERSION 3.5) - -set(DATASTRUCTURES_INC_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE) -set(DATASTRUCTURES_CPP_SOURCES main.cpp) - -add_executable(${PROJECT_NAME} ${DATASTRUCTURES_CPP_SOURCES}) \ No newline at end of file diff --git a/src/DoublyLinkedList/DoublyLinkedList.h b/src/DoublyLinkedList/DoublyLinkedList.h deleted file mode 100644 index e796bb5..0000000 --- a/src/DoublyLinkedList/DoublyLinkedList.h +++ /dev/null @@ -1,175 +0,0 @@ -#ifndef __DOUBLY__LINKED__LIST__H__ -#define __DOUBLY__LINKED__LIST__H__ - -#include - -//Node for Doubly Linked List -template -class DLLNode { - public: - T data; //data - DLLNode *prev; //address of previous node - DLLNode *next; //address of next node -}; - -template -class DoublyLinkedList { - private: - DLLNode *head; //start of the doubly linked list - DLLNode *tail; //end of the doubly linked list - //Create new node - DLLNode *GetNewNode(T new_data) { - DLLNode *newNode = new DLLNode (); - newNode->data = new_data; - newNode->prev = nullptr; - newNode->next = nullptr; - return newNode; - } - DLLNode *GetLastNode() { - DLLNode *currNode = head; - while(currNode->next != nullptr) { - currNode = currNode->next; - } - return currNode; - } - public: - //New Doubly Linked List should have no data (head = NULL) - DoublyLinkedList() : head(nullptr), tail(nullptr) {} - //Delete each node to avoid memory leak - ~DoublyLinkedList() { - DLLNode *nodeToDelete = head; - while(nodeToDelete != nullptr) { - DLLNode *nextNode = nodeToDelete->next; //store next node - delete nodeToDelete; //delete current node - nodeToDelete = nextNode; //proceed to delete next node - } - } - //Insert new data at front - bool InsertAtHead(T new_data) { - bool returnStatus = false; - try{ - DLLNode *newNode = GetNewNode(new_data); - if(head == nullptr) { - head = newNode; //if node is empty, head will be newNode - tail = newNode; //if node is empty, tail will also be newNode - returnStatus = true; - } - else { - newNode->next = head; - head->prev = newNode; - head = newNode; - tail = GetLastNode(); //update tail node - returnStatus = true; - } - } - catch(const std::exception &e) { - std::cout << __FUNCTION__ << ": (" << __LINE__ << ") Caught Exception: " << e.what() << '\n'; - } - return returnStatus; - } - //Insert new data at tail - bool InsertAtTail(T new_data) { - bool returnStatus = false; - try { - if(head == nullptr) { - returnStatus = InsertAtHead(new_data); - } - else { - DLLNode *newNode = GetNewNode(new_data); - tail->next = newNode; - newNode->prev = tail; - returnStatus = true; - } - if(returnStatus == true) { - tail = GetLastNode(); //update tail node - } - } - catch(const std::exception &e) { - std::cout << __FUNCTION__ << ": (" << __LINE__ << ") Caught Exception: " << e.what() << '\n'; - } - return returnStatus; - } - //Delete node containing data - bool Delete(T dataToDelete, bool returnStatus = false) { - //if linked list is empty, do nothing - if(head != nullptr) { - //if head contains data to be deleted - if(head->data == dataToDelete) { - if(head->next != nullptr) { - DLLNode *nodeToDelete = head->next; - head->data = head->next->data; //next node will be new head - head->next = head->next->next; - head->next->prev = head; //change previous node of next node to point to head - delete nodeToDelete; //delete next node info at old head - returnStatus = true; - tail = GetLastNode(); - Delete(dataToDelete, returnStatus); //Recursive call to delete other nodes - } - else { - delete head; - head = nullptr; - tail = nullptr; - returnStatus = true; - } - } - else { - //head doesn't contain data to be deleted - DLLNode *currNode = head; - while(currNode->next != nullptr) { - if(currNode->next->data == dataToDelete) { - //if next node contains data to be deleted - DLLNode *nodeToDelete = currNode->next; - currNode->next = currNode->next->next; //move the next node - if(currNode->next != nullptr) { - currNode->next->prev = currNode; - } - else { - tail->prev = currNode; //if its last node, change previous node of tail - } - delete nodeToDelete; //delete the node containing data - returnStatus = true; - } - else { - currNode = currNode->next; - } - } - if(returnStatus == true) { - tail = GetLastNode(); - } - } - } - return returnStatus; - } - //Display contents of linked list - std::string Display() { - std::stringstream ss(""); - if(head != nullptr) { - DLLNode *currNode = head; - while(currNode != nullptr) { - ss << currNode->data; - currNode = currNode->next; - if(currNode != nullptr) { - ss << " -> "; - } - } - } - return ss.str(); - } - //Display contents of linked list - std::string DisplayReverse() { - std::stringstream ss(""); - if(tail != nullptr) { - DLLNode *lastNode = tail; - while(lastNode != nullptr) { - ss << lastNode->data; - lastNode = lastNode->prev; - if(lastNode != nullptr) { - ss << " <- "; - } - } - } - return ss.str(); - } -}; - -#endif \ No newline at end of file diff --git a/src/SinglyLinkedList/SinglyLinkedList.h b/src/SinglyLinkedList/SinglyLinkedList.h deleted file mode 100644 index 670c1b3..0000000 --- a/src/SinglyLinkedList/SinglyLinkedList.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef __SINGLY__LINKED__LIST__H__ -#define __SINGLY__LINKED__LIST__H__ - -#include - -//Node for Singly Linked List -template -class SLLNode { - public: - T data; //data - SLLNode *next; //address of next node -}; - -template -class SinglyLinkedList { - private: - SLLNode *head; //start of the Singly Linked List - //Create new node - SLLNode *GetNewNode(T new_data) { - SLLNode *newNode = new SLLNode (); - newNode->data = new_data; - newNode->next = nullptr; - return newNode; - } - public: - //New Singly Linked List should have no data (head = NULL) - SinglyLinkedList() : head(nullptr) {} - //Delete each node to avoid memory leaks - ~SinglyLinkedList() { - SLLNode *nodeToDelete = head; - while(nodeToDelete != nullptr) { - SLLNode *nextNode = nodeToDelete->next; //store next node - delete nodeToDelete; //delete current node - nodeToDelete = nextNode; //proceed to delete next node - } - } - //Insert new data at front - bool InsertAtHead(T new_data) { - bool returnStatus = false; - try { - SLLNode *newNode = GetNewNode(new_data); //get new node - newNode->next = head; //new node should point to existing head - head = newNode; //modify head - returnStatus = true; - } - catch(const std::exception &e) { - std::cout << __FUNCTION__ << ": (" << __LINE__ << ") Caught Exception: " << e.what() << '\n'; - } - return returnStatus; - } - //Insert new data at end - bool InsertAtTail(T new_data) { - bool returnStatus = false; - try { - //if linked list is empty, insert data at head - if(head == nullptr) { - returnStatus = InsertAtHead(new_data); - } - else { - SLLNode *newNode = GetNewNode(new_data); //get new node - SLLNode *currNode = head; - while(currNode->next != nullptr) { //iterate towards the last node - currNode = currNode->next; - } - currNode->next = newNode; //new node will now be the last node - returnStatus = true; - } - } - catch(const std::exception &e) { - std::cout << __FUNCTION__ << ": (" << __LINE__ << ") Caught Exception: " << e.what() << '\n'; - } - return returnStatus; - } - //Delete node containing data - bool Delete(T dataToDelete, bool returnStatus = false) { - //if linked list is empty, do nothing - if(head != nullptr) { - //if head contains data to be deleted - if(head->data == dataToDelete) { - if(head->next != nullptr) { - SLLNode *nodeToDelete = head->next; - head->data = head->next->data; //next node will be new head - head->next = head->next->next; - delete nodeToDelete; //delete next node info at old head - returnStatus = true; - Delete(dataToDelete, returnStatus); //Recursive call to delete other nodes - } - else { - //if head is the only node, simply delete it - delete head; - head = nullptr; - returnStatus = true; - } - } - else { - //head doesn't contain data to be deleted - SLLNode *currNode = head; - while(currNode->next != nullptr) { - if(currNode->next->data == dataToDelete) { - //if next node contains data to be deleted - SLLNode *nodeToDelete = currNode->next; - currNode->next = currNode->next->next; //move the next node - delete nodeToDelete; //delete the node containing data - returnStatus = true; - } - else { - currNode = currNode->next; - } - } - } - } - return returnStatus; - } - //Display contents of linked list - std::string Display() { - std::stringstream ss(""); - if(head != nullptr) { - SLLNode *currNode = head; - while(currNode != nullptr) { - ss << currNode->data; - currNode = currNode->next; - if(currNode != nullptr) { - ss << " -> "; - } - } - } - return ss.str(); - } -}; - -#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 0bb7e36..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include "SinglyLinkedList/SinglyLinkedList.h" -#include "DoublyLinkedList/DoublyLinkedList.h" - -int main(int argc, char* argv[]) { - SinglyLinkedList sIntObj; - sIntObj.InsertAtHead(10); - sIntObj.InsertAtHead(20); - sIntObj.InsertAtHead(30); - sIntObj.InsertAtTail(30); - std::cout << sIntObj.Display() << '\n'; - sIntObj.Delete(20); - sIntObj.Delete(30); - std::cout << sIntObj.Display() << '\n'; - - SinglyLinkedList sStrObj; - sStrObj.InsertAtHead("Hi"); - sStrObj.InsertAtTail("This"); - sStrObj.InsertAtTail("Works!"); - std::cout << sStrObj.Display() << '\n'; - sStrObj.Delete("Hi"); - std::cout << sStrObj.Display() << '\n'; - - DoublyLinkedList dIntObj; - dIntObj.InsertAtHead(40); - dIntObj.InsertAtHead(30); - dIntObj.InsertAtHead(20); - dIntObj.InsertAtTail(10); - dIntObj.InsertAtTail(5); - std::cout << dIntObj.Display() << '\n'; - std::cout << dIntObj.DisplayReverse() << '\n'; - dIntObj.Delete(20); - std::cout << dIntObj.Display() << '\n'; - std::cout << dIntObj.DisplayReverse() << '\n'; - dIntObj.Delete(5); - std::cout << dIntObj.Display() << '\n'; - std::cout << dIntObj.DisplayReverse() << '\n'; - return EXIT_SUCCESS; -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt deleted file mode 100644 index 489dd36..0000000 --- a/tests/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -project(datastructures-cpp-ut) -cmake_minimum_required(VERSION 3.5) -set(CMAKE_CXX_STANDARD 11) -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads) - -#googletest -include(FetchContent) -FetchContent_Declare(googletest -GIT_REPOSITORY "https://github.com/google/googletest.git" -GIT_TAG "release-1.11.0" -) -FetchContent_MakeAvailable(googletest) - -set(UT_CPP_SOURCES main_ut.cc) - -add_executable(${PROJECT_NAME} ${UT_CPP_SOURCES}) -target_include_directories(${PROJECT_NAME} PRIVATE ${DATASTRUCTURES_INC_DIR}) -target_link_libraries(${PROJECT_NAME} gtest gtest_main gmock gmock_main Threads::Threads) diff --git a/tests/DoublyLinkedList/DoublyLinkedList_ut.h b/tests/DoublyLinkedList/DoublyLinkedList_ut.h deleted file mode 100644 index 3d7830d..0000000 --- a/tests/DoublyLinkedList/DoublyLinkedList_ut.h +++ /dev/null @@ -1,244 +0,0 @@ -#ifndef __DOUBLY__LINKED__LIST__UT__H__ -#define __DOUBLY__LINKED__LIST__UT__H__ - -#include "gtest/gtest.h" -#include "DoublyLinkedList/DoublyLinkedList.h" -#include - -/* - * Singly Linked List Test Cases - * 1) Print Empty Linked List - * 2) Delete Empty Linked List - * 3) Insert At Head, Delete and print empty linked list - * 4) Insert At Tail, Delete and print empty linked list - * 5) Insert 3 at head, 4 at tail, delete 3 and print 4 linked list - */ - -//Print empty linked list -TEST(DoublyLinkedListIntTest, PrintEmpty) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.Display(), ""); - EXPECT_EQ(dObj.DisplayReverse(), ""); -} - -//Delete element from empty linked list -TEST(DoublyLinkedListIntTest, DeleteEmpty) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.Delete(2), false); - EXPECT_EQ(dObj.Display(), ""); - EXPECT_EQ(dObj.DisplayReverse(), ""); -} - -//Insert data at head and delete -TEST(DoublyLinkedListIntTest, InsertAtHeadDelete) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead(5), true); - EXPECT_EQ(dObj.Display(), "5"); - EXPECT_EQ(dObj.Delete(5), true); - EXPECT_EQ(dObj.Display(), ""); -} - -//Insert data at tail and delete -TEST(DoublyLinkedListIntTest, InsertAtTailDelete) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtTail(6), true); - EXPECT_EQ(dObj.Display(), "6"); - EXPECT_EQ(dObj.Delete(6), true); - EXPECT_EQ(dObj.Display(), ""); -} - -//Delete data from head -TEST(DoublyLinkedListIntTest, DeleteDataFromHead) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead(6), true); - EXPECT_EQ(dObj.InsertAtTail(5), true); - EXPECT_EQ(dObj.InsertAtTail(4), true); - EXPECT_EQ(dObj.Delete(6), true); - EXPECT_EQ(dObj.Display(), "5 -> 4"); - EXPECT_EQ(dObj.DisplayReverse(), "4 <- 5"); -} - -//Delete data from tail -TEST(DoublyLinkedListIntTest, DeleteDataFromTail) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead(6), true); - EXPECT_EQ(dObj.InsertAtTail(5), true); - EXPECT_EQ(dObj.InsertAtTail(4), true); - EXPECT_EQ(dObj.Delete(4), true); - EXPECT_EQ(dObj.Display(), "6 -> 5"); - EXPECT_EQ(dObj.DisplayReverse(), "5 <- 6"); -} - -//Insert data at head and tail and delete -TEST(DoublyLinkedListIntTest, InsertAtHeadTailDelete) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead(1), true); - EXPECT_EQ(dObj.InsertAtTail(2), true); - EXPECT_EQ(dObj.InsertAtHead(3), true); - EXPECT_EQ(dObj.InsertAtTail(4), true); - EXPECT_EQ(dObj.InsertAtHead(5), true); - EXPECT_EQ(dObj.InsertAtTail(6), true); - EXPECT_EQ(dObj.Delete(3), true); - EXPECT_EQ(dObj.Delete(6), true); - EXPECT_EQ(dObj.Delete(3), false); - EXPECT_EQ(dObj.Display(),"5 -> 1 -> 2 -> 4"); - EXPECT_EQ(dObj.DisplayReverse(),"4 <- 2 <- 1 <- 5"); -} - -//Delete data occuring at multiple nodes -TEST(DoublyLinkedListIntTest, DeleteRecurringData) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead(1), true); - EXPECT_EQ(dObj.InsertAtTail(2), true); - EXPECT_EQ(dObj.InsertAtHead(3), true); - EXPECT_EQ(dObj.InsertAtTail(4), true); - EXPECT_EQ(dObj.InsertAtHead(5), true); - EXPECT_EQ(dObj.InsertAtTail(6), true); - EXPECT_EQ(dObj.InsertAtHead(1), true); - EXPECT_EQ(dObj.InsertAtTail(2), true); - EXPECT_EQ(dObj.InsertAtHead(3), true); - EXPECT_EQ(dObj.InsertAtTail(4), true); - EXPECT_EQ(dObj.InsertAtHead(5), true); - EXPECT_EQ(dObj.InsertAtTail(6), true); - EXPECT_EQ(dObj.Display(),"5 -> 3 -> 1 -> 5 -> 3 -> 1 -> 2 -> 4 -> 6 -> 2 -> 4 -> 6"); - EXPECT_EQ(dObj.DisplayReverse(),"6 <- 4 <- 2 <- 6 <- 4 <- 2 <- 1 <- 3 <- 5 <- 1 <- 3 <- 5"); - EXPECT_EQ(dObj.Delete(5), true); - EXPECT_EQ(dObj.Delete(1), true); - EXPECT_EQ(dObj.Delete(5), false); - EXPECT_EQ(dObj.Display(), "3 -> 3 -> 2 -> 4 -> 6 -> 2 -> 4 -> 6"); - EXPECT_EQ(dObj.DisplayReverse(), "6 <- 4 <- 2 <- 6 <- 4 <- 2 <- 3 <- 3"); -} - -//Delete consecutive data occuring at multiple nodes -TEST(DoublyLinkedListIntTest, DeleteConsecutiveData) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead(1), true); - EXPECT_EQ(dObj.InsertAtHead(2), true); - EXPECT_EQ(dObj.InsertAtHead(3), true); - EXPECT_EQ(dObj.InsertAtHead(3), true); - EXPECT_EQ(dObj.InsertAtHead(4), true); - EXPECT_EQ(dObj.Display(), "4 -> 3 -> 3 -> 2 -> 1"); - EXPECT_EQ(dObj.DisplayReverse(), "1 <- 2 <- 3 <- 3 <- 4"); - EXPECT_EQ(dObj.Delete(3), true); - EXPECT_EQ(dObj.Display(), "4 -> 2 -> 1"); - EXPECT_EQ(dObj.DisplayReverse(), "1 <- 2 <- 4"); -} - -//Print empty linked list -TEST(DoublyLinkedListStringTest, PrintEmpty) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.Display(), ""); - EXPECT_EQ(dObj.DisplayReverse(), ""); -} - -//Delete element from empty linked list -TEST(DoublyLinkedListStringTest, DeleteEmpty) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.Delete("Hello"), false); - EXPECT_EQ(dObj.Display(), ""); - EXPECT_EQ(dObj.DisplayReverse(), ""); -} - -//Insert data at head and delete -TEST(DoublyLinkedListStringTest, InsertAtHeadDelete) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead("Hello"), true); - EXPECT_EQ(dObj.Display(), "Hello"); - EXPECT_EQ(dObj.Delete("Hello"), true); - EXPECT_EQ(dObj.Display(), ""); - EXPECT_EQ(dObj.DisplayReverse(), ""); -} - -//Insert data at tail and delete -TEST(DoublyLinkedListStringTest, InsertAtTailDelete) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtTail("Hello"), true); - EXPECT_EQ(dObj.Display(), "Hello"); - EXPECT_EQ(dObj.Delete("Hello"), true); - EXPECT_EQ(dObj.Display(), ""); - EXPECT_EQ(dObj.DisplayReverse(), ""); -} - -//Delete data from head -TEST(DoublyLinkedListStringTest, DeleteDataFromHead) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead("Hello"), true); - EXPECT_EQ(dObj.InsertAtTail("World"), true); - EXPECT_EQ(dObj.InsertAtTail("Cool"), true); - EXPECT_EQ(dObj.Display(), "Hello -> World -> Cool"); - EXPECT_EQ(dObj.DisplayReverse(), "Cool <- World <- Hello"); - EXPECT_EQ(dObj.Delete("Hello"), true); - EXPECT_EQ(dObj.Display(), "World -> Cool"); - EXPECT_EQ(dObj.DisplayReverse(), "Cool <- World"); -} - -//Delete data from tail -TEST(DoublyLinkedListStringTest, DeleteDataFromTail) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead("Hello"), true); - EXPECT_EQ(dObj.InsertAtTail("World"), true); - EXPECT_EQ(dObj.InsertAtTail("Cool"), true); - EXPECT_EQ(dObj.Display(), "Hello -> World -> Cool"); - EXPECT_EQ(dObj.DisplayReverse(), "Cool <- World <- Hello"); - EXPECT_EQ(dObj.Delete("Cool"), true); - EXPECT_EQ(dObj.Display(), "Hello -> World"); - EXPECT_EQ(dObj.DisplayReverse(), "World <- Hello"); -} - -//Insert data at head and tail and delete -TEST(DoublyLinkedListStringTest, InsertAtHeadTailDelete) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead("Hello"), true); - EXPECT_EQ(dObj.InsertAtTail("World"), true); - EXPECT_EQ(dObj.InsertAtHead("Good"), true); - EXPECT_EQ(dObj.InsertAtTail("Morning"), true); - EXPECT_EQ(dObj.InsertAtHead("Hello"), true); - EXPECT_EQ(dObj.InsertAtTail("World"), true); - EXPECT_EQ(dObj.Display(), "Hello -> Good -> Hello -> World -> Morning -> World"); - EXPECT_EQ(dObj.DisplayReverse(), "World <- Morning <- World <- Hello <- Good <- Hello"); - EXPECT_EQ(dObj.Delete("World"), true); - EXPECT_EQ(dObj.Delete("Morning"), true); - EXPECT_EQ(dObj.Delete("World"), false); - EXPECT_EQ(dObj.Display(),"Hello -> Good -> Hello"); - EXPECT_EQ(dObj.DisplayReverse(), "Hello <- Good <- Hello"); -} - -//Delete data occuring at multiple nodes -TEST(DoublyLinkedListStringTest, DeleteRecurringData) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead("Hello"), true); - EXPECT_EQ(dObj.InsertAtTail("World"), true); - EXPECT_EQ(dObj.InsertAtHead("Good"), true); - EXPECT_EQ(dObj.InsertAtTail("Morning"), true); - EXPECT_EQ(dObj.InsertAtHead("Rise"), true); - EXPECT_EQ(dObj.InsertAtTail("Shine"), true); - EXPECT_EQ(dObj.InsertAtHead("Hello"), true); - EXPECT_EQ(dObj.InsertAtTail("World"), true); - EXPECT_EQ(dObj.InsertAtHead("Good"), true); - EXPECT_EQ(dObj.InsertAtTail("Morning"), true); - EXPECT_EQ(dObj.InsertAtHead("Rise"), true); - EXPECT_EQ(dObj.InsertAtTail("Shine"), true); - EXPECT_EQ(dObj.Display(),"Rise -> Good -> Hello -> Rise -> Good -> Hello -> World -> Morning -> Shine -> World -> Morning -> Shine"); - EXPECT_EQ(dObj.DisplayReverse(),"Shine <- Morning <- World <- Shine <- Morning <- World <- Hello <- Good <- Rise <- Hello <- Good <- Rise"); - EXPECT_EQ(dObj.Delete("Rise"), true); - EXPECT_EQ(dObj.Delete("Good"), true); - EXPECT_EQ(dObj.Delete("Good"), false); - EXPECT_EQ(dObj.Display(),"Hello -> Hello -> World -> Morning -> Shine -> World -> Morning -> Shine"); - EXPECT_EQ(dObj.DisplayReverse(),"Shine <- Morning <- World <- Shine <- Morning <- World <- Hello <- Hello"); -} - -//Delete consecutive data occuring at multiple nodes -TEST(DoublyLinkedListStringTest, DeleteConsecutiveData) { - DoublyLinkedList dObj; - EXPECT_EQ(dObj.InsertAtHead("Hello"), true); - EXPECT_EQ(dObj.InsertAtTail("Good"), true); - EXPECT_EQ(dObj.InsertAtTail("Morning"), true); - EXPECT_EQ(dObj.InsertAtTail("Morning"), true); - EXPECT_EQ(dObj.InsertAtTail("World"), true); - EXPECT_EQ(dObj.Display(), "Hello -> Good -> Morning -> Morning -> World"); - EXPECT_EQ(dObj.DisplayReverse(), "World <- Morning <- Morning <- Good <- Hello"); - EXPECT_EQ(dObj.Delete("Morning"), true); - EXPECT_EQ(dObj.Display(), "Hello -> Good -> World"); - EXPECT_EQ(dObj.DisplayReverse(), "World <- Good <- Hello"); -} -#endif \ No newline at end of file diff --git a/tests/SinglyLinkedList/SinglyLinkedList_ut.h b/tests/SinglyLinkedList/SinglyLinkedList_ut.h deleted file mode 100644 index c4dd14d..0000000 --- a/tests/SinglyLinkedList/SinglyLinkedList_ut.h +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef __SINGLY__LINKED__LIST__UT__H__ -#define __SINGLY__LINKED__LIST__UT__H__ - -#include "gtest/gtest.h" -#include "SinglyLinkedList/SinglyLinkedList.h" -#include - -/* - * Singly Linked List Test Cases - * 1) Print Empty Linked List - * 2) Delete Empty Linked List - * 3) Insert At Head, Delete and print empty linked list - * 4) Insert At Tail, Delete and print empty linked list - * 5) Insert 3 at head, 4 at tail, delete 3 and print 4 linked list - */ - -//Print empty linked list -TEST(SinglyLinkedListIntTest, PrintEmpty) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.Display(), ""); -} - -//Delete element from empty linked list -TEST(SinglyLinkedListIntTest, DeleteEmpty) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.Delete(2), false); - EXPECT_EQ(sObj.Display(), ""); -} - -//Insert data at head and delete -TEST(SinglyLinkedListIntTest, InsertAtHeadDelete) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead(5), true); - EXPECT_EQ(sObj.Delete(5), true); - EXPECT_EQ(sObj.Display(), ""); -} - -//Insert data at tail and delete -TEST(SinglyLinkedListIntTest, InsertAtTailDelete) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtTail(6), true); - EXPECT_EQ(sObj.Delete(6), true); - EXPECT_EQ(sObj.Display(), ""); -} - -//Delete data from head -TEST(SinglyLinkedListIntTest, DeleteDataFromHead) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead(6), true); - EXPECT_EQ(sObj.InsertAtTail(5), true); - EXPECT_EQ(sObj.InsertAtTail(4), true); - EXPECT_EQ(sObj.Delete(6), true); - EXPECT_EQ(sObj.Display(), "5 -> 4"); -} - -//Delete data from tail -TEST(SinglyLinkedListIntTest, DeleteDataFromTail) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead(6), true); - EXPECT_EQ(sObj.InsertAtTail(5), true); - EXPECT_EQ(sObj.InsertAtTail(4), true); - EXPECT_EQ(sObj.Delete(4), true); - EXPECT_EQ(sObj.Display(), "6 -> 5"); -} - -//Insert data at head and tail and delete -TEST(SinglyLinkedListIntTest, InsertAtHeadTailDelete) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead(1), true); - EXPECT_EQ(sObj.InsertAtTail(2), true); - EXPECT_EQ(sObj.InsertAtHead(3), true); - EXPECT_EQ(sObj.InsertAtTail(4), true); - EXPECT_EQ(sObj.InsertAtHead(5), true); - EXPECT_EQ(sObj.InsertAtTail(6), true); - EXPECT_EQ(sObj.Delete(3), true); - EXPECT_EQ(sObj.Delete(6), true); - EXPECT_EQ(sObj.Delete(3), false); - EXPECT_EQ(sObj.Display(),"5 -> 1 -> 2 -> 4"); -} - -//Delete data occuring at multiple nodes -TEST(SinglyLinkedListIntTest, DeleteRecurringData) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead(1), true); - EXPECT_EQ(sObj.InsertAtTail(2), true); - EXPECT_EQ(sObj.InsertAtHead(3), true); - EXPECT_EQ(sObj.InsertAtTail(4), true); - EXPECT_EQ(sObj.InsertAtHead(5), true); - EXPECT_EQ(sObj.InsertAtTail(6), true); - EXPECT_EQ(sObj.InsertAtHead(1), true); - EXPECT_EQ(sObj.InsertAtTail(2), true); - EXPECT_EQ(sObj.InsertAtHead(3), true); - EXPECT_EQ(sObj.InsertAtTail(4), true); - EXPECT_EQ(sObj.InsertAtHead(5), true); - EXPECT_EQ(sObj.InsertAtTail(6), true); - EXPECT_EQ(sObj.Display(),"5 -> 3 -> 1 -> 5 -> 3 -> 1 -> 2 -> 4 -> 6 -> 2 -> 4 -> 6"); - EXPECT_EQ(sObj.Delete(5), true); - EXPECT_EQ(sObj.Delete(1), true); - EXPECT_EQ(sObj.Delete(5), false); - EXPECT_EQ(sObj.Display(),"3 -> 3 -> 2 -> 4 -> 6 -> 2 -> 4 -> 6"); -} - -//Delete consecutive data occuring at multiple nodes -TEST(SinglyLinkedListIntTest, DeleteConsecutiveData) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead(1), true); - EXPECT_EQ(sObj.InsertAtHead(2), true); - EXPECT_EQ(sObj.InsertAtHead(3), true); - EXPECT_EQ(sObj.InsertAtHead(3), true); - EXPECT_EQ(sObj.InsertAtHead(4), true); - EXPECT_EQ(sObj.Display(), "4 -> 3 -> 3 -> 2 -> 1"); - EXPECT_EQ(sObj.Delete(3), true); - EXPECT_EQ(sObj.Display(), "4 -> 2 -> 1"); -} - -//Print empty linked list -TEST(SinglyLinkedListStringTest, PrintEmpty) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.Display(), ""); -} - -//Delete element from empty linked list -TEST(SinglyLinkedListStringTest, DeleteEmpty) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.Delete("Hello"), false); - EXPECT_EQ(sObj.Display(), ""); -} - -//Insert data at head and delete -TEST(SinglyLinkedListStringTest, InsertAtHeadDelete) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead("Hello"), true); - EXPECT_EQ(sObj.Display(), "Hello"); - EXPECT_EQ(sObj.Delete("Hello"), true); - EXPECT_EQ(sObj.Display(), ""); -} - -//Insert data at tail and delete -TEST(SinglyLinkedListStringTest, InsertAtTailDelete) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtTail("Hello"), true); - EXPECT_EQ(sObj.Display(), "Hello"); - EXPECT_EQ(sObj.Delete("Hello"), true); - EXPECT_EQ(sObj.Display(), ""); -} - -//Delete data from head -TEST(SinglyLinkedListStringTest, DeleteDataFromHead) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead("Hello"), true); - EXPECT_EQ(sObj.InsertAtTail("World"), true); - EXPECT_EQ(sObj.InsertAtTail("Cool"), true); - EXPECT_EQ(sObj.Display(), "Hello -> World -> Cool"); - EXPECT_EQ(sObj.Delete("Hello"), true); - EXPECT_EQ(sObj.Display(), "World -> Cool"); -} - -//Delete data from tail -TEST(SinglyLinkedListStringTest, DeleteDataFromTail) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead("Hello"), true); - EXPECT_EQ(sObj.InsertAtTail("World"), true); - EXPECT_EQ(sObj.InsertAtTail("Cool"), true); - EXPECT_EQ(sObj.Display(), "Hello -> World -> Cool"); - EXPECT_EQ(sObj.Delete("Cool"), true); - EXPECT_EQ(sObj.Display(), "Hello -> World"); -} - -//Insert data at head and tail and delete -TEST(SinglyLinkedListStringTest, InsertAtHeadTailDelete) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead("Hello"), true); - EXPECT_EQ(sObj.InsertAtTail("World"), true); - EXPECT_EQ(sObj.InsertAtHead("Good"), true); - EXPECT_EQ(sObj.InsertAtTail("Morning"), true); - EXPECT_EQ(sObj.InsertAtHead("Hello"), true); - EXPECT_EQ(sObj.InsertAtTail("World"), true); - EXPECT_EQ(sObj.Display(), "Hello -> Good -> Hello -> World -> Morning -> World"); - EXPECT_EQ(sObj.Delete("World"), true); - EXPECT_EQ(sObj.Delete("Morning"), true); - EXPECT_EQ(sObj.Delete("World"), false); - EXPECT_EQ(sObj.Display(),"Hello -> Good -> Hello"); -} - -//Delete data occuring at multiple nodes -TEST(SinglyLinkedListStringTest, DeleteRecurringData) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead("Hello"), true); - EXPECT_EQ(sObj.InsertAtTail("World"), true); - EXPECT_EQ(sObj.InsertAtHead("Good"), true); - EXPECT_EQ(sObj.InsertAtTail("Morning"), true); - EXPECT_EQ(sObj.InsertAtHead("Rise"), true); - EXPECT_EQ(sObj.InsertAtTail("Shine"), true); - EXPECT_EQ(sObj.InsertAtHead("Hello"), true); - EXPECT_EQ(sObj.InsertAtTail("World"), true); - EXPECT_EQ(sObj.InsertAtHead("Good"), true); - EXPECT_EQ(sObj.InsertAtTail("Morning"), true); - EXPECT_EQ(sObj.InsertAtHead("Rise"), true); - EXPECT_EQ(sObj.InsertAtTail("Shine"), true); - EXPECT_EQ(sObj.Display(),"Rise -> Good -> Hello -> Rise -> Good -> Hello -> World -> Morning -> Shine -> World -> Morning -> Shine"); - EXPECT_EQ(sObj.Delete("Rise"), true); - EXPECT_EQ(sObj.Delete("Good"), true); - EXPECT_EQ(sObj.Delete("Good"), false); - EXPECT_EQ(sObj.Display(),"Hello -> Hello -> World -> Morning -> Shine -> World -> Morning -> Shine"); -} - -//Delete consecutive data occuring at multiple nodes -TEST(SinglyLinkedListStringTest, DeleteConsecutiveData) { - SinglyLinkedList sObj; - EXPECT_EQ(sObj.InsertAtHead("Hello"), true); - EXPECT_EQ(sObj.InsertAtTail("Good"), true); - EXPECT_EQ(sObj.InsertAtTail("Morning"), true); - EXPECT_EQ(sObj.InsertAtTail("Morning"), true); - EXPECT_EQ(sObj.InsertAtTail("World"), true); - EXPECT_EQ(sObj.Display(), "Hello -> Good -> Morning -> Morning -> World"); - EXPECT_EQ(sObj.Delete("Morning"), true); - EXPECT_EQ(sObj.Display(), "Hello -> Good -> World"); -} - -#endif diff --git a/tests/main_ut.cc b/tests/main_ut.cc deleted file mode 100644 index 9dec0bb..0000000 --- a/tests/main_ut.cc +++ /dev/null @@ -1,7 +0,0 @@ -#include "SinglyLinkedList/SinglyLinkedList_ut.h" -#include "DoublyLinkedList/DoublyLinkedList_ut.h" - -int main(int argc, char* argv[]) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file From 1bfe558bbfae3971d07bee29c7d77b56d88be18c Mon Sep 17 00:00:00 2001 From: balanarayank <28087097+balanarayank@users.noreply.github.com> Date: Tue, 17 May 2022 23:03:24 +0530 Subject: [PATCH 2/4] Added Singly Linked List --- CMakeLists.txt | 10 ++ README.md | 4 +- examples/SinglyLinkedList.cpp | 68 +++++++++++ inc/LinkedList.h | 33 +++++ inc/SinglyLinkedList.h | 144 ++++++++++++++++++++++ tests/CMakeLists.txt | 15 +++ tests/SinglyLinkedList_ut.h | 220 ++++++++++++++++++++++++++++++++++ tests/main_test.cc | 6 + 8 files changed, 498 insertions(+), 2 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 examples/SinglyLinkedList.cpp create mode 100644 inc/LinkedList.h create mode 100644 inc/SinglyLinkedList.h create mode 100644 tests/CMakeLists.txt create mode 100644 tests/SinglyLinkedList_ut.h create mode 100644 tests/main_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..43179da --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +project(simple-cpp-datastructures) +cmake_minimum_required(VERSION 3.14) + +set(LINKEDLIST_INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc CACHE INTERNAL "") + +set(EXAMPLES_CPP_SOURCES examples/SinglyLinkedList.cpp) +add_executable(${PROJECT_NAME} ${EXAMPLES_CPP_SOURCES}) +target_include_directories(${PROJECT_NAME} PRIVATE ${LINKEDLIST_INC_DIR}) + +add_subdirectory(tests) \ No newline at end of file diff --git a/README.md b/README.md index e81bf11..651be57 100644 --- a/README.md +++ b/README.md @@ -167,9 +167,9 @@ For more details regarding usage, refer googletest [documentation](https://googl ## TODO - [ ] ChangeLog -- [x] Doubly Linked List +- [ ] Doubly Linked List - [ ] Binary Search Tree -- [x] Improve source code comments +- [ ] Improve source code comments ## Contributing diff --git a/examples/SinglyLinkedList.cpp b/examples/SinglyLinkedList.cpp new file mode 100644 index 0000000..8e64498 --- /dev/null +++ b/examples/SinglyLinkedList.cpp @@ -0,0 +1,68 @@ +#include "SinglyLinkedList.h" +#include + +int main(int argc, char* argv[]) { + SinglyLinkedList sllIntObj; + sllIntObj.InsertAtHead(1); + sllIntObj.InsertAtHead(3); + sllIntObj.InsertAtTail(2); + sllIntObj.InsertAtTail(4); + sllIntObj.InsertAtHead(5); + std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj.Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + + if(sllIntObj.DeleteData(5)) { + std::cout << "Deleted 5\n"; + } + std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj.Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + + if(sllIntObj.DeleteData(1)) { + std::cout << "Deleted 1\n"; + } + if(sllIntObj.DeleteData(100)) { + std::cout << "Deleted 100\n"; + } + std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj.Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + + sllIntObj.InsertAtTail(6); + sllIntObj.InsertAtHead(7); + std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj.Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + + if(sllIntObj.DeleteData(6)) { + std::cout << "Deleted 6\n"; + } + std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj.Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + + if(sllIntObj.DeleteNode(sllIntObj.GetFirstNode()->next->next)) { + std::cout << "Deleted node\n"; + } + std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj.Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + std::cout << "Linked List in reverse: " << sllIntObj.DisplayReverse() << std::endl; + + SinglyLinkedList sllStrObj; + sllStrObj.InsertAtHead("Hello"); + std::cout << "Linked List: " << sllStrObj.Display() << std::endl; + std::cout << "Linked List Size: " << sllStrObj.GetSize() << std::endl; + sllStrObj.DeleteData("Hello"); + std::cout << "Linked List: " << sllStrObj.Display() << std::endl; + std::cout << "Linked List Size: " << sllStrObj.GetSize() << std::endl; + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/inc/LinkedList.h b/inc/LinkedList.h new file mode 100644 index 0000000..e7e1ede --- /dev/null +++ b/inc/LinkedList.h @@ -0,0 +1,33 @@ +#ifndef __LINKED_LIST_H__ +#define __LINKED_LIST_H__ + +#include + +//Node for Linked List +template +class Node { + public: + T data; + Node *next; + Node *prev; +}; + +//Linked List abstract +template +class LinkedList { + private: + virtual Node *GetNewNode(T data) = 0; + public: + virtual ~LinkedList() {} + virtual Node *GetFirstNode() = 0; //Get first node + virtual Node *GetLastNode() = 0; //Get last node + virtual void InsertAtHead(T new_data) = 0; //Insert new data at head + virtual void InsertAtTail(T new_data) = 0; //Insert new data at tail + virtual bool DeleteData(T dataToDelete) = 0; //Delete the first node from head that contains data + virtual bool DeleteNode(Node* nodeToDelete) = 0; //Delete a particular node + virtual std::string Display() = 0; //Display Linked List + virtual std::string DisplayReverse() = 0; //Display Linked List in Reverse + virtual size_t GetSize() = 0; //Get the size +}; + +#endif \ No newline at end of file diff --git a/inc/SinglyLinkedList.h b/inc/SinglyLinkedList.h new file mode 100644 index 0000000..f09df3b --- /dev/null +++ b/inc/SinglyLinkedList.h @@ -0,0 +1,144 @@ +#ifndef __SINGLY_LINKED_LIST_H__ +#define __SINGLY_LINKED_LIST_H__ + +#include "LinkedList.h" +#include + +template +class SinglyLinkedList : public LinkedList { + private: + Node *head; //head of linked list + Node *tail; //tail of linked list + size_t sllSize; //size of linked list + //Get new node with data + Node *GetNewNode(T data) override { + Node *newNode = new Node; + newNode->data = data; + newNode->next = nullptr; + return newNode; + } + public: + //Initialize head, tail and size as null + SinglyLinkedList() : head(nullptr), tail(nullptr), sllSize(0) {} + //Delete each node to prevent memory leak + ~SinglyLinkedList() { + Node *nodeToDelete = head; + while(nodeToDelete != nullptr) { + Node *nextNode = nodeToDelete->next; + delete nodeToDelete; + nodeToDelete = nextNode; + } + } + //Get First Node + Node *GetFirstNode() override { + return head; + } + //Get Last Node + Node *GetLastNode() override { + return tail; + } + //Insert new data at head + void InsertAtHead(T new_data) override { + Node *newNode = GetNewNode(new_data); + if(head == nullptr) { //if head is null, new node will be head and tail + head = newNode; + tail = newNode; + sllSize++; + return; + } + newNode->next = head; //new node should point to head + head = newNode; //update new head as new node + sllSize++; + return; + } + //Insert new data at tail + void InsertAtTail(T new_data) override { + Node *newNode = GetNewNode(new_data); + if(tail == nullptr) { //if head is null, new node will be head + head = newNode; + tail = newNode; + sllSize++; + return; + } + tail->next = newNode; //insert new node at the last + tail = newNode; + sllSize++; + } + //Deletes the first node from head that contains data + bool DeleteData(T dataToDelete) override { + if(head == nullptr) { + return false; + } + if(head->data == dataToDelete) { + Node *nodeToDelete = head; + head = head->next; + if(head == nullptr) { + tail = nullptr; + } + delete nodeToDelete; + sllSize--; + return true; + } + Node *currNode = head; + bool isDelete = false; + while(currNode->next != nullptr) { + if(currNode->next->data == dataToDelete) { + isDelete = true; + break; + } + currNode = currNode->next; + } + if(isDelete) { + Node *nodeToDelete = currNode->next; + currNode->next = currNode->next->next; + if(currNode->next == nullptr) { + tail = currNode; + } + delete nodeToDelete; + sllSize--; + return true; + } + return false; + } + //Delete a particular node + bool DeleteNode(Node *nodeToDelete) { + if(head == nodeToDelete) { + head = head->next; + delete nodeToDelete; + sllSize--; + return true; + } + Node *currNode = head; + bool isDelete = false; + while(currNode->next != nodeToDelete) { + currNode = currNode->next; + } + currNode->next = currNode->next->next; + if(currNode->next == nullptr) { + tail = currNode; + } + delete nodeToDelete; + sllSize--; + return true; + } + std::string Display() override { + if(head == nullptr) { + return "SinglyLinkedList is empty"; + } + std::ostringstream oss; + Node *currNode = head; + while(currNode != nullptr) { + oss << currNode->data << " -> "; + currNode = currNode->next; + } + return oss.str(); + } + std::string DisplayReverse() override { + return "Not supported for SinglyLinkedList"; + } + size_t GetSize() override { + return sllSize; + } +}; + +#endif \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..5d4dd77 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,15 @@ +project(simple-cpp-datastructures-ut) +cmake_minimum_required(VERSION 3.14) + +#GoogleTest version 1.11.0 +include(FetchContent) +FetchContent_Declare( googletest + GIT_REPOSITORY "https://github.com/google/googletest" + GIT_TAG "release-1.11.0" +) +FetchContent_MakeAvailable(googletest) + +set(UT_CPP_SOURCES main_test.cc) +add_executable(${PROJECT_NAME} ${UT_CPP_SOURCES}) +target_include_directories(${PROJECT_NAME} PRIVATE ${LINKEDLIST_INC_DIR}) +target_link_libraries(${PROJECT_NAME} PRIVATE gtest gtest_main gmock gmock_main) \ No newline at end of file diff --git a/tests/SinglyLinkedList_ut.h b/tests/SinglyLinkedList_ut.h new file mode 100644 index 0000000..2c4b032 --- /dev/null +++ b/tests/SinglyLinkedList_ut.h @@ -0,0 +1,220 @@ +#ifndef __SINGLY_LINKED_LIST_UT_H__ +#define __SINGLY_LINKED_LIST_UT_H__ + +#include "gtest/gtest.h" +#include "SinglyLinkedList.h" + +TEST(SinglyLinkedListIntTest, EmptyLinkedList) { + SinglyLinkedList sllIntObj; + ASSERT_EQ(sllIntObj.GetFirstNode(), nullptr); + ASSERT_EQ(sllIntObj.GetLastNode(), nullptr); + ASSERT_EQ(sllIntObj.GetSize(), 0); + ASSERT_EQ(sllIntObj.DeleteData(2), false); + ASSERT_EQ(sllIntObj.Display(), "SinglyLinkedList is empty"); + ASSERT_EQ(sllIntObj.DisplayReverse(), "Not supported for SinglyLinkedList"); +} + +TEST(SinglyLinkedListIntTest, InsertAtHeadAndDeleteData) { + SinglyLinkedList sllIntObj; + sllIntObj.InsertAtHead(1); + ASSERT_EQ(sllIntObj.GetFirstNode()->data, 1); + ASSERT_EQ(sllIntObj.GetLastNode()->data, 1); + ASSERT_EQ(sllIntObj.GetSize(), 1); + ASSERT_EQ(sllIntObj.Display(), "1 -> "); + + ASSERT_EQ(sllIntObj.DeleteData(2), false); + ASSERT_EQ(sllIntObj.DeleteData(1), true); + ASSERT_EQ(sllIntObj.GetFirstNode(), nullptr); + ASSERT_EQ(sllIntObj.GetLastNode(), nullptr); + ASSERT_EQ(sllIntObj.GetSize(), 0); + ASSERT_EQ(sllIntObj.Display(), "SinglyLinkedList is empty"); +} + +TEST(SinglyLinkedListIntTest, InsertAtTailAndDeleteData) { + SinglyLinkedList sllIntObj; + sllIntObj.InsertAtTail(10); + ASSERT_EQ(sllIntObj.GetFirstNode()->data, 10); + ASSERT_EQ(sllIntObj.GetLastNode()->data, 10); + ASSERT_EQ(sllIntObj.GetSize(), 1); + ASSERT_EQ(sllIntObj.Display(), "10 -> "); + + ASSERT_EQ(sllIntObj.DeleteData(20), false); + ASSERT_EQ(sllIntObj.DeleteData(10), true); + ASSERT_EQ(sllIntObj.GetFirstNode(), nullptr); + ASSERT_EQ(sllIntObj.GetLastNode(), nullptr); + ASSERT_EQ(sllIntObj.GetSize(), 0); + ASSERT_EQ(sllIntObj.Display(), "SinglyLinkedList is empty"); +} + +class SinglyLinkedListIntTestF : public ::testing::Test +{ + protected: + SinglyLinkedList sllIntObj; + + virtual void SetUp() { + sllIntObj.InsertAtHead(1); + sllIntObj.InsertAtHead(2); + sllIntObj.InsertAtHead(3); + sllIntObj.InsertAtTail(4); + sllIntObj.InsertAtTail(5); + sllIntObj.InsertAtHead(6); + sllIntObj.InsertAtTail(7); + sllIntObj.InsertAtHead(8); + } + + virtual void TearDown() { + + } +}; + +TEST_F(SinglyLinkedListIntTestF, InsertDataAndPrint) { + ASSERT_EQ(sllIntObj.GetFirstNode()->data, 8); + ASSERT_EQ(sllIntObj.GetLastNode()->data, 7); + ASSERT_EQ(sllIntObj.GetSize(), 8); + ASSERT_EQ(sllIntObj.Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 4 -> 5 -> 7 -> "); +} + +TEST_F(SinglyLinkedListIntTestF, DeleteDataAtHead) { + ASSERT_EQ(sllIntObj.DeleteData(8), true); + ASSERT_EQ(sllIntObj.GetFirstNode()->data, 6); + ASSERT_EQ(sllIntObj.GetLastNode()->data, 7); + ASSERT_EQ(sllIntObj.GetSize(), 7); + ASSERT_EQ(sllIntObj.Display(), "6 -> 3 -> 2 -> 1 -> 4 -> 5 -> 7 -> "); +} + +TEST_F(SinglyLinkedListIntTestF, DeleteDataAtTail) { + ASSERT_EQ(sllIntObj.DeleteData(7), true); + ASSERT_EQ(sllIntObj.GetFirstNode()->data, 8); + ASSERT_EQ(sllIntObj.GetLastNode()->data, 5); + ASSERT_EQ(sllIntObj.GetSize(), 7); + ASSERT_EQ(sllIntObj.Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 4 -> 5 -> "); +} + +TEST_F(SinglyLinkedListIntTestF, DeleteDataInside) { + ASSERT_EQ(sllIntObj.DeleteData(4), true); + ASSERT_EQ(sllIntObj.GetFirstNode()->data, 8); + ASSERT_EQ(sllIntObj.GetLastNode()->data, 7); + ASSERT_EQ(sllIntObj.GetSize(), 7); + ASSERT_EQ(sllIntObj.Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 5 -> 7 -> "); +} + +TEST_F(SinglyLinkedListIntTestF, DeleteMultipleData) { + ASSERT_EQ(sllIntObj.DeleteData(4), true); + ASSERT_EQ(sllIntObj.DeleteData(8), true); + ASSERT_EQ(sllIntObj.DeleteData(6), true); + ASSERT_EQ(sllIntObj.DeleteData(7), true); + ASSERT_EQ(sllIntObj.GetFirstNode()->data, 3); + ASSERT_EQ(sllIntObj.GetLastNode()->data, 5); + ASSERT_EQ(sllIntObj.GetSize(), 4); + ASSERT_EQ(sllIntObj.Display(), "3 -> 2 -> 1 -> 5 -> "); +} + +//========================================== + +TEST(SinglyLinkedListStringTest, EmptyLinkedList) { + SinglyLinkedList sllStrObj; + ASSERT_EQ(sllStrObj.GetFirstNode(), nullptr); + ASSERT_EQ(sllStrObj.GetLastNode(), nullptr); + ASSERT_EQ(sllStrObj.GetSize(), 0); + ASSERT_EQ(sllStrObj.DeleteData("Hello"), false); + ASSERT_EQ(sllStrObj.Display(), "SinglyLinkedList is empty"); + ASSERT_EQ(sllStrObj.DisplayReverse(), "Not supported for SinglyLinkedList"); +} + +TEST(SinglyLinkedListStringTest, InsertAtHeadAndDeleteData) { + SinglyLinkedList sllStrObj; + sllStrObj.InsertAtHead("Hello"); + ASSERT_EQ(sllStrObj.GetFirstNode()->data, "Hello"); + ASSERT_EQ(sllStrObj.GetLastNode()->data, "Hello"); + ASSERT_EQ(sllStrObj.GetSize(), 1); + ASSERT_EQ(sllStrObj.Display(), "Hello -> "); + + ASSERT_EQ(sllStrObj.DeleteData("World"), false); + ASSERT_EQ(sllStrObj.DeleteData("Hello"), true); + ASSERT_EQ(sllStrObj.GetFirstNode(), nullptr); + ASSERT_EQ(sllStrObj.GetLastNode(), nullptr); + ASSERT_EQ(sllStrObj.GetSize(), 0); + ASSERT_EQ(sllStrObj.Display(), "SinglyLinkedList is empty"); +} + +TEST(SinglyLinkedListStringTest, InsertAtTailAndDeleteData) { + SinglyLinkedList sllStrObj; + sllStrObj.InsertAtTail("World"); + ASSERT_EQ(sllStrObj.GetFirstNode()->data, "World"); + ASSERT_EQ(sllStrObj.GetLastNode()->data, "World"); + ASSERT_EQ(sllStrObj.GetSize(), 1); + ASSERT_EQ(sllStrObj.Display(), "World -> "); + + ASSERT_EQ(sllStrObj.DeleteData("Hello"), false); + ASSERT_EQ(sllStrObj.DeleteData("World"), true); + ASSERT_EQ(sllStrObj.GetFirstNode(), nullptr); + ASSERT_EQ(sllStrObj.GetLastNode(), nullptr); + ASSERT_EQ(sllStrObj.GetSize(), 0); + ASSERT_EQ(sllStrObj.Display(), "SinglyLinkedList is empty"); +} + +class SinglyLinkedListStringTestF : public ::testing::Test +{ + protected: + SinglyLinkedList sllStrObj; + + virtual void SetUp() { + sllStrObj.InsertAtHead("Hello"); + sllStrObj.InsertAtHead("World"); + sllStrObj.InsertAtHead("Good"); + sllStrObj.InsertAtTail("Morning"); + sllStrObj.InsertAtTail("Test"); + sllStrObj.InsertAtHead("This"); + sllStrObj.InsertAtTail("Great"); + sllStrObj.InsertAtHead("Day"); + } + + virtual void TearDown() { + + } +}; + +TEST_F(SinglyLinkedListStringTestF, InsertDataAndPrint) { + ASSERT_EQ(sllStrObj.GetFirstNode()->data, "Day"); + ASSERT_EQ(sllStrObj.GetLastNode()->data, "Great"); + ASSERT_EQ(sllStrObj.GetSize(), 8); + ASSERT_EQ(sllStrObj.Display(), "Day -> This -> Good -> World -> Hello -> Morning -> Test -> Great -> "); +} + +TEST_F(SinglyLinkedListStringTestF, DeleteDataAtHead) { + ASSERT_EQ(sllStrObj.DeleteData("Day"), true); + ASSERT_EQ(sllStrObj.GetFirstNode()->data, "This"); + ASSERT_EQ(sllStrObj.GetLastNode()->data, "Great"); + ASSERT_EQ(sllStrObj.GetSize(), 7); + ASSERT_EQ(sllStrObj.Display(), "This -> Good -> World -> Hello -> Morning -> Test -> Great -> "); +} + +TEST_F(SinglyLinkedListStringTestF, DeleteDataAtTail) { + ASSERT_EQ(sllStrObj.DeleteData("Great"), true); + ASSERT_EQ(sllStrObj.GetFirstNode()->data, "Day"); + ASSERT_EQ(sllStrObj.GetLastNode()->data, "Test"); + ASSERT_EQ(sllStrObj.GetSize(), 7); + ASSERT_EQ(sllStrObj.Display(), "Day -> This -> Good -> World -> Hello -> Morning -> Test -> "); +} + +TEST_F(SinglyLinkedListStringTestF, DeleteDataInside) { + ASSERT_EQ(sllStrObj.DeleteData("Morning"), true); + ASSERT_EQ(sllStrObj.GetFirstNode()->data, "Day"); + ASSERT_EQ(sllStrObj.GetLastNode()->data, "Great"); + ASSERT_EQ(sllStrObj.GetSize(), 7); + ASSERT_EQ(sllStrObj.Display(), "Day -> This -> Good -> World -> Hello -> Test -> Great -> "); +} + +TEST_F(SinglyLinkedListStringTestF, DeleteMultipleData) { + ASSERT_EQ(sllStrObj.DeleteData("Good"), true); + ASSERT_EQ(sllStrObj.DeleteData("Hello"), true); + ASSERT_EQ(sllStrObj.DeleteData("Day"), true); + ASSERT_EQ(sllStrObj.DeleteData("This"), true); + ASSERT_EQ(sllStrObj.DeleteData("Great"), true); + ASSERT_EQ(sllStrObj.GetFirstNode()->data, "World"); + ASSERT_EQ(sllStrObj.GetLastNode()->data, "Test"); + ASSERT_EQ(sllStrObj.GetSize(), 3); + ASSERT_EQ(sllStrObj.Display(), "World -> Morning -> Test -> "); +} + +#endif \ No newline at end of file diff --git a/tests/main_test.cc b/tests/main_test.cc new file mode 100644 index 0000000..32bd6fc --- /dev/null +++ b/tests/main_test.cc @@ -0,0 +1,6 @@ +#include "SinglyLinkedList_ut.h" + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file From 3a73b210848ca6874c2499e17fd7a8c2101735e4 Mon Sep 17 00:00:00 2001 From: balanarayank <28087097+balanarayank@users.noreply.github.com> Date: Sat, 21 May 2022 12:47:34 +0530 Subject: [PATCH 3/4] 1. Added more test cases 2. Improved implementation --- examples/SinglyLinkedList.cpp | 94 +++++----- tests/SinglyLinkedList_ut.h | 321 +++++++++++++++++++--------------- 2 files changed, 232 insertions(+), 183 deletions(-) diff --git a/examples/SinglyLinkedList.cpp b/examples/SinglyLinkedList.cpp index 8e64498..c196283 100644 --- a/examples/SinglyLinkedList.cpp +++ b/examples/SinglyLinkedList.cpp @@ -2,67 +2,71 @@ #include int main(int argc, char* argv[]) { - SinglyLinkedList sllIntObj; - sllIntObj.InsertAtHead(1); - sllIntObj.InsertAtHead(3); - sllIntObj.InsertAtTail(2); - sllIntObj.InsertAtTail(4); - sllIntObj.InsertAtHead(5); - std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; - std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; - std::cout << "Linked List: " << sllIntObj.Display() << std::endl; - std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + LinkedList *sllIntObj = new SinglyLinkedList; + sllIntObj->InsertAtHead(1); + sllIntObj->InsertAtHead(3); + sllIntObj->InsertAtTail(2); + sllIntObj->InsertAtTail(4); + sllIntObj->InsertAtHead(5); + std::cout << "First Node Data: " << sllIntObj->GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj->GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj->Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj->GetSize() << std::endl; - if(sllIntObj.DeleteData(5)) { + if(sllIntObj->DeleteData(5)) { std::cout << "Deleted 5\n"; } - std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; - std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; - std::cout << "Linked List: " << sllIntObj.Display() << std::endl; - std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + std::cout << "First Node Data: " << sllIntObj->GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj->GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj->Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj->GetSize() << std::endl; - if(sllIntObj.DeleteData(1)) { + if(sllIntObj->DeleteData(1)) { std::cout << "Deleted 1\n"; } - if(sllIntObj.DeleteData(100)) { + if(sllIntObj->DeleteData(100)) { std::cout << "Deleted 100\n"; } - std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; - std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; - std::cout << "Linked List: " << sllIntObj.Display() << std::endl; - std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + std::cout << "First Node Data: " << sllIntObj->GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj->GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj->Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj->GetSize() << std::endl; - sllIntObj.InsertAtTail(6); - sllIntObj.InsertAtHead(7); - std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; - std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; - std::cout << "Linked List: " << sllIntObj.Display() << std::endl; - std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + sllIntObj->InsertAtTail(6); + sllIntObj->InsertAtHead(7); + std::cout << "First Node Data: " << sllIntObj->GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj->GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj->Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj->GetSize() << std::endl; - if(sllIntObj.DeleteData(6)) { + if(sllIntObj->DeleteData(6)) { std::cout << "Deleted 6\n"; } - std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; - std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; - std::cout << "Linked List: " << sllIntObj.Display() << std::endl; - std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; + std::cout << "First Node Data: " << sllIntObj->GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj->GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj->Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj->GetSize() << std::endl; - if(sllIntObj.DeleteNode(sllIntObj.GetFirstNode()->next->next)) { + if(sllIntObj->DeleteNode(sllIntObj->GetFirstNode()->next->next)) { std::cout << "Deleted node\n"; } - std::cout << "First Node Data: " << sllIntObj.GetFirstNode()->data << std::endl; - std::cout << "Last Node Data: " << sllIntObj.GetLastNode()->data << std::endl; - std::cout << "Linked List: " << sllIntObj.Display() << std::endl; - std::cout << "Linked List Size: " << sllIntObj.GetSize() << std::endl; - std::cout << "Linked List in reverse: " << sllIntObj.DisplayReverse() << std::endl; + std::cout << "First Node Data: " << sllIntObj->GetFirstNode()->data << std::endl; + std::cout << "Last Node Data: " << sllIntObj->GetLastNode()->data << std::endl; + std::cout << "Linked List: " << sllIntObj->Display() << std::endl; + std::cout << "Linked List Size: " << sllIntObj->GetSize() << std::endl; + std::cout << "Linked List in reverse: " << sllIntObj->DisplayReverse() << std::endl; - SinglyLinkedList sllStrObj; - sllStrObj.InsertAtHead("Hello"); - std::cout << "Linked List: " << sllStrObj.Display() << std::endl; - std::cout << "Linked List Size: " << sllStrObj.GetSize() << std::endl; - sllStrObj.DeleteData("Hello"); - std::cout << "Linked List: " << sllStrObj.Display() << std::endl; - std::cout << "Linked List Size: " << sllStrObj.GetSize() << std::endl; + delete sllIntObj; + + LinkedList *sllStrObj = new SinglyLinkedList; + sllStrObj->InsertAtHead("Hello"); + std::cout << "Linked List: " << sllStrObj->Display() << std::endl; + std::cout << "Linked List Size: " << sllStrObj->GetSize() << std::endl; + sllStrObj->DeleteData("Hello"); + std::cout << "Linked List: " << sllStrObj->Display() << std::endl; + std::cout << "Linked List Size: " << sllStrObj->GetSize() << std::endl; + + delete sllStrObj; return EXIT_SUCCESS; } \ No newline at end of file diff --git a/tests/SinglyLinkedList_ut.h b/tests/SinglyLinkedList_ut.h index 2c4b032..2c0d180 100644 --- a/tests/SinglyLinkedList_ut.h +++ b/tests/SinglyLinkedList_ut.h @@ -5,216 +5,261 @@ #include "SinglyLinkedList.h" TEST(SinglyLinkedListIntTest, EmptyLinkedList) { - SinglyLinkedList sllIntObj; - ASSERT_EQ(sllIntObj.GetFirstNode(), nullptr); - ASSERT_EQ(sllIntObj.GetLastNode(), nullptr); - ASSERT_EQ(sllIntObj.GetSize(), 0); - ASSERT_EQ(sllIntObj.DeleteData(2), false); - ASSERT_EQ(sllIntObj.Display(), "SinglyLinkedList is empty"); - ASSERT_EQ(sllIntObj.DisplayReverse(), "Not supported for SinglyLinkedList"); + LinkedList *sllIntObj = new SinglyLinkedList; + ASSERT_EQ(sllIntObj->GetFirstNode(), nullptr); + ASSERT_EQ(sllIntObj->GetLastNode(), nullptr); + ASSERT_EQ(sllIntObj->GetSize(), 0); + ASSERT_EQ(sllIntObj->DeleteData(2), false); + ASSERT_EQ(sllIntObj->Display(), "SinglyLinkedList is empty"); + ASSERT_EQ(sllIntObj->DisplayReverse(), "Not supported for SinglyLinkedList"); + delete sllIntObj; } TEST(SinglyLinkedListIntTest, InsertAtHeadAndDeleteData) { - SinglyLinkedList sllIntObj; - sllIntObj.InsertAtHead(1); - ASSERT_EQ(sllIntObj.GetFirstNode()->data, 1); - ASSERT_EQ(sllIntObj.GetLastNode()->data, 1); - ASSERT_EQ(sllIntObj.GetSize(), 1); - ASSERT_EQ(sllIntObj.Display(), "1 -> "); + LinkedList *sllIntObj = new SinglyLinkedList; + sllIntObj->InsertAtHead(1); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 1); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 1); + ASSERT_EQ(sllIntObj->GetSize(), 1); + ASSERT_EQ(sllIntObj->Display(), "1 -> "); - ASSERT_EQ(sllIntObj.DeleteData(2), false); - ASSERT_EQ(sllIntObj.DeleteData(1), true); - ASSERT_EQ(sllIntObj.GetFirstNode(), nullptr); - ASSERT_EQ(sllIntObj.GetLastNode(), nullptr); - ASSERT_EQ(sllIntObj.GetSize(), 0); - ASSERT_EQ(sllIntObj.Display(), "SinglyLinkedList is empty"); + ASSERT_EQ(sllIntObj->DeleteData(2), false); + ASSERT_EQ(sllIntObj->DeleteData(1), true); + ASSERT_EQ(sllIntObj->GetFirstNode(), nullptr); + ASSERT_EQ(sllIntObj->GetLastNode(), nullptr); + ASSERT_EQ(sllIntObj->GetSize(), 0); + ASSERT_EQ(sllIntObj->Display(), "SinglyLinkedList is empty"); + delete sllIntObj; } TEST(SinglyLinkedListIntTest, InsertAtTailAndDeleteData) { - SinglyLinkedList sllIntObj; - sllIntObj.InsertAtTail(10); - ASSERT_EQ(sllIntObj.GetFirstNode()->data, 10); - ASSERT_EQ(sllIntObj.GetLastNode()->data, 10); - ASSERT_EQ(sllIntObj.GetSize(), 1); - ASSERT_EQ(sllIntObj.Display(), "10 -> "); + LinkedList *sllIntObj = new SinglyLinkedList; + sllIntObj->InsertAtTail(10); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 10); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 10); + ASSERT_EQ(sllIntObj->GetSize(), 1); + ASSERT_EQ(sllIntObj->Display(), "10 -> "); - ASSERT_EQ(sllIntObj.DeleteData(20), false); - ASSERT_EQ(sllIntObj.DeleteData(10), true); - ASSERT_EQ(sllIntObj.GetFirstNode(), nullptr); - ASSERT_EQ(sllIntObj.GetLastNode(), nullptr); - ASSERT_EQ(sllIntObj.GetSize(), 0); - ASSERT_EQ(sllIntObj.Display(), "SinglyLinkedList is empty"); + ASSERT_EQ(sllIntObj->DeleteData(20), false); + ASSERT_EQ(sllIntObj->DeleteData(10), true); + ASSERT_EQ(sllIntObj->GetFirstNode(), nullptr); + ASSERT_EQ(sllIntObj->GetLastNode(), nullptr); + ASSERT_EQ(sllIntObj->GetSize(), 0); + ASSERT_EQ(sllIntObj->Display(), "SinglyLinkedList is empty"); + delete sllIntObj; } class SinglyLinkedListIntTestF : public ::testing::Test { protected: - SinglyLinkedList sllIntObj; + LinkedList *sllIntObj; virtual void SetUp() { - sllIntObj.InsertAtHead(1); - sllIntObj.InsertAtHead(2); - sllIntObj.InsertAtHead(3); - sllIntObj.InsertAtTail(4); - sllIntObj.InsertAtTail(5); - sllIntObj.InsertAtHead(6); - sllIntObj.InsertAtTail(7); - sllIntObj.InsertAtHead(8); + sllIntObj = new SinglyLinkedList; + sllIntObj->InsertAtHead(1); + sllIntObj->InsertAtHead(2); + sllIntObj->InsertAtHead(3); + sllIntObj->InsertAtTail(4); + sllIntObj->InsertAtTail(5); + sllIntObj->InsertAtHead(6); + sllIntObj->InsertAtTail(7); + sllIntObj->InsertAtHead(8); } virtual void TearDown() { - + delete sllIntObj; } }; TEST_F(SinglyLinkedListIntTestF, InsertDataAndPrint) { - ASSERT_EQ(sllIntObj.GetFirstNode()->data, 8); - ASSERT_EQ(sllIntObj.GetLastNode()->data, 7); - ASSERT_EQ(sllIntObj.GetSize(), 8); - ASSERT_EQ(sllIntObj.Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 4 -> 5 -> 7 -> "); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 8); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 7); + ASSERT_EQ(sllIntObj->GetSize(), 8); + ASSERT_EQ(sllIntObj->Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 4 -> 5 -> 7 -> "); } TEST_F(SinglyLinkedListIntTestF, DeleteDataAtHead) { - ASSERT_EQ(sllIntObj.DeleteData(8), true); - ASSERT_EQ(sllIntObj.GetFirstNode()->data, 6); - ASSERT_EQ(sllIntObj.GetLastNode()->data, 7); - ASSERT_EQ(sllIntObj.GetSize(), 7); - ASSERT_EQ(sllIntObj.Display(), "6 -> 3 -> 2 -> 1 -> 4 -> 5 -> 7 -> "); + ASSERT_EQ(sllIntObj->DeleteData(8), true); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 6); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 7); + ASSERT_EQ(sllIntObj->GetSize(), 7); + ASSERT_EQ(sllIntObj->Display(), "6 -> 3 -> 2 -> 1 -> 4 -> 5 -> 7 -> "); +} + +TEST_F(SinglyLinkedListIntTestF, DeleteNodeAtHead) { + ASSERT_EQ(sllIntObj->DeleteNode(sllIntObj->GetFirstNode()), true); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 6); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 7); + ASSERT_EQ(sllIntObj->GetSize(), 7); + ASSERT_EQ(sllIntObj->Display(), "6 -> 3 -> 2 -> 1 -> 4 -> 5 -> 7 -> "); } TEST_F(SinglyLinkedListIntTestF, DeleteDataAtTail) { - ASSERT_EQ(sllIntObj.DeleteData(7), true); - ASSERT_EQ(sllIntObj.GetFirstNode()->data, 8); - ASSERT_EQ(sllIntObj.GetLastNode()->data, 5); - ASSERT_EQ(sllIntObj.GetSize(), 7); - ASSERT_EQ(sllIntObj.Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 4 -> 5 -> "); + ASSERT_EQ(sllIntObj->DeleteData(7), true); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 8); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 5); + ASSERT_EQ(sllIntObj->GetSize(), 7); + ASSERT_EQ(sllIntObj->Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 4 -> 5 -> "); +} + +TEST_F(SinglyLinkedListIntTestF, DeleteNodeAtTail) { + ASSERT_EQ(sllIntObj->DeleteNode(sllIntObj->GetLastNode()), true); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 8); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 5); + ASSERT_EQ(sllIntObj->GetSize(), 7); + ASSERT_EQ(sllIntObj->Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 4 -> 5 -> "); } TEST_F(SinglyLinkedListIntTestF, DeleteDataInside) { - ASSERT_EQ(sllIntObj.DeleteData(4), true); - ASSERT_EQ(sllIntObj.GetFirstNode()->data, 8); - ASSERT_EQ(sllIntObj.GetLastNode()->data, 7); - ASSERT_EQ(sllIntObj.GetSize(), 7); - ASSERT_EQ(sllIntObj.Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 5 -> 7 -> "); + ASSERT_EQ(sllIntObj->DeleteData(4), true); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 8); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 7); + ASSERT_EQ(sllIntObj->GetSize(), 7); + ASSERT_EQ(sllIntObj->Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 5 -> 7 -> "); +} + +TEST_F(SinglyLinkedListIntTestF, DeleteNodeInside) { + Node *llNode = sllIntObj->GetFirstNode(); + ASSERT_EQ(sllIntObj->DeleteNode(llNode->next->next->next->next->next), true); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 8); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 7); + ASSERT_EQ(sllIntObj->GetSize(), 7); + ASSERT_EQ(sllIntObj->Display(), "8 -> 6 -> 3 -> 2 -> 1 -> 5 -> 7 -> "); } TEST_F(SinglyLinkedListIntTestF, DeleteMultipleData) { - ASSERT_EQ(sllIntObj.DeleteData(4), true); - ASSERT_EQ(sllIntObj.DeleteData(8), true); - ASSERT_EQ(sllIntObj.DeleteData(6), true); - ASSERT_EQ(sllIntObj.DeleteData(7), true); - ASSERT_EQ(sllIntObj.GetFirstNode()->data, 3); - ASSERT_EQ(sllIntObj.GetLastNode()->data, 5); - ASSERT_EQ(sllIntObj.GetSize(), 4); - ASSERT_EQ(sllIntObj.Display(), "3 -> 2 -> 1 -> 5 -> "); + ASSERT_EQ(sllIntObj->DeleteData(4), true); + ASSERT_EQ(sllIntObj->DeleteData(8), true); + ASSERT_EQ(sllIntObj->DeleteData(6), true); + ASSERT_EQ(sllIntObj->DeleteData(7), true); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 3); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 5); + ASSERT_EQ(sllIntObj->GetSize(), 4); + ASSERT_EQ(sllIntObj->Display(), "3 -> 2 -> 1 -> 5 -> "); } -//========================================== +TEST_F(SinglyLinkedListIntTestF, DeleteMultipleNodes) { + Node *llNode = sllIntObj->GetFirstNode(); + ASSERT_EQ(sllIntObj->DeleteNode(llNode->next->next->next->next->next), true); + ASSERT_EQ(sllIntObj->DeleteNode(llNode), true); + llNode = sllIntObj->GetFirstNode(); + ASSERT_EQ(sllIntObj->DeleteNode(llNode), true); + llNode = sllIntObj->GetLastNode(); + ASSERT_EQ(sllIntObj->DeleteNode(llNode), true); + ASSERT_EQ(sllIntObj->GetFirstNode()->data, 3); + ASSERT_EQ(sllIntObj->GetLastNode()->data, 5); + ASSERT_EQ(sllIntObj->GetSize(), 4); + ASSERT_EQ(sllIntObj->Display(), "3 -> 2 -> 1 -> 5 -> "); +} TEST(SinglyLinkedListStringTest, EmptyLinkedList) { - SinglyLinkedList sllStrObj; - ASSERT_EQ(sllStrObj.GetFirstNode(), nullptr); - ASSERT_EQ(sllStrObj.GetLastNode(), nullptr); - ASSERT_EQ(sllStrObj.GetSize(), 0); - ASSERT_EQ(sllStrObj.DeleteData("Hello"), false); - ASSERT_EQ(sllStrObj.Display(), "SinglyLinkedList is empty"); - ASSERT_EQ(sllStrObj.DisplayReverse(), "Not supported for SinglyLinkedList"); + LinkedList *sllStrObj = new SinglyLinkedList; + ASSERT_EQ(sllStrObj->GetFirstNode(), nullptr); + ASSERT_EQ(sllStrObj->GetLastNode(), nullptr); + ASSERT_EQ(sllStrObj->GetSize(), 0); + ASSERT_EQ(sllStrObj->DeleteData("Hello"), false); + ASSERT_EQ(sllStrObj->Display(), "SinglyLinkedList is empty"); + ASSERT_EQ(sllStrObj->DisplayReverse(), "Not supported for SinglyLinkedList"); + delete sllStrObj; } TEST(SinglyLinkedListStringTest, InsertAtHeadAndDeleteData) { - SinglyLinkedList sllStrObj; - sllStrObj.InsertAtHead("Hello"); - ASSERT_EQ(sllStrObj.GetFirstNode()->data, "Hello"); - ASSERT_EQ(sllStrObj.GetLastNode()->data, "Hello"); - ASSERT_EQ(sllStrObj.GetSize(), 1); - ASSERT_EQ(sllStrObj.Display(), "Hello -> "); + LinkedList *sllStrObj = new SinglyLinkedList; + sllStrObj->InsertAtHead("Hello"); + ASSERT_EQ(sllStrObj->GetFirstNode()->data, "Hello"); + ASSERT_EQ(sllStrObj->GetLastNode()->data, "Hello"); + ASSERT_EQ(sllStrObj->GetSize(), 1); + ASSERT_EQ(sllStrObj->Display(), "Hello -> "); - ASSERT_EQ(sllStrObj.DeleteData("World"), false); - ASSERT_EQ(sllStrObj.DeleteData("Hello"), true); - ASSERT_EQ(sllStrObj.GetFirstNode(), nullptr); - ASSERT_EQ(sllStrObj.GetLastNode(), nullptr); - ASSERT_EQ(sllStrObj.GetSize(), 0); - ASSERT_EQ(sllStrObj.Display(), "SinglyLinkedList is empty"); + ASSERT_EQ(sllStrObj->DeleteData("World"), false); + ASSERT_EQ(sllStrObj->DeleteData("Hello"), true); + ASSERT_EQ(sllStrObj->GetFirstNode(), nullptr); + ASSERT_EQ(sllStrObj->GetLastNode(), nullptr); + ASSERT_EQ(sllStrObj->GetSize(), 0); + ASSERT_EQ(sllStrObj->Display(), "SinglyLinkedList is empty"); + delete sllStrObj; } TEST(SinglyLinkedListStringTest, InsertAtTailAndDeleteData) { - SinglyLinkedList sllStrObj; - sllStrObj.InsertAtTail("World"); - ASSERT_EQ(sllStrObj.GetFirstNode()->data, "World"); - ASSERT_EQ(sllStrObj.GetLastNode()->data, "World"); - ASSERT_EQ(sllStrObj.GetSize(), 1); - ASSERT_EQ(sllStrObj.Display(), "World -> "); + LinkedList *sllStrObj = new SinglyLinkedList; + sllStrObj->InsertAtTail("World"); + ASSERT_EQ(sllStrObj->GetFirstNode()->data, "World"); + ASSERT_EQ(sllStrObj->GetLastNode()->data, "World"); + ASSERT_EQ(sllStrObj->GetSize(), 1); + ASSERT_EQ(sllStrObj->Display(), "World -> "); - ASSERT_EQ(sllStrObj.DeleteData("Hello"), false); - ASSERT_EQ(sllStrObj.DeleteData("World"), true); - ASSERT_EQ(sllStrObj.GetFirstNode(), nullptr); - ASSERT_EQ(sllStrObj.GetLastNode(), nullptr); - ASSERT_EQ(sllStrObj.GetSize(), 0); - ASSERT_EQ(sllStrObj.Display(), "SinglyLinkedList is empty"); + ASSERT_EQ(sllStrObj->DeleteData("Hello"), false); + ASSERT_EQ(sllStrObj->DeleteData("World"), true); + ASSERT_EQ(sllStrObj->GetFirstNode(), nullptr); + ASSERT_EQ(sllStrObj->GetLastNode(), nullptr); + ASSERT_EQ(sllStrObj->GetSize(), 0); + ASSERT_EQ(sllStrObj->Display(), "SinglyLinkedList is empty"); + delete sllStrObj; } class SinglyLinkedListStringTestF : public ::testing::Test { protected: - SinglyLinkedList sllStrObj; + LinkedList *sllStrObj; virtual void SetUp() { - sllStrObj.InsertAtHead("Hello"); - sllStrObj.InsertAtHead("World"); - sllStrObj.InsertAtHead("Good"); - sllStrObj.InsertAtTail("Morning"); - sllStrObj.InsertAtTail("Test"); - sllStrObj.InsertAtHead("This"); - sllStrObj.InsertAtTail("Great"); - sllStrObj.InsertAtHead("Day"); + sllStrObj = new SinglyLinkedList; + sllStrObj->InsertAtHead("Hello"); + sllStrObj->InsertAtHead("World"); + sllStrObj->InsertAtHead("Good"); + sllStrObj->InsertAtTail("Morning"); + sllStrObj->InsertAtTail("Test"); + sllStrObj->InsertAtHead("This"); + sllStrObj->InsertAtTail("Great"); + sllStrObj->InsertAtHead("Day"); } virtual void TearDown() { - + delete sllStrObj; } }; TEST_F(SinglyLinkedListStringTestF, InsertDataAndPrint) { - ASSERT_EQ(sllStrObj.GetFirstNode()->data, "Day"); - ASSERT_EQ(sllStrObj.GetLastNode()->data, "Great"); - ASSERT_EQ(sllStrObj.GetSize(), 8); - ASSERT_EQ(sllStrObj.Display(), "Day -> This -> Good -> World -> Hello -> Morning -> Test -> Great -> "); + ASSERT_EQ(sllStrObj->GetFirstNode()->data, "Day"); + ASSERT_EQ(sllStrObj->GetLastNode()->data, "Great"); + ASSERT_EQ(sllStrObj->GetSize(), 8); + ASSERT_EQ(sllStrObj->Display(), "Day -> This -> Good -> World -> Hello -> Morning -> Test -> Great -> "); } TEST_F(SinglyLinkedListStringTestF, DeleteDataAtHead) { - ASSERT_EQ(sllStrObj.DeleteData("Day"), true); - ASSERT_EQ(sllStrObj.GetFirstNode()->data, "This"); - ASSERT_EQ(sllStrObj.GetLastNode()->data, "Great"); - ASSERT_EQ(sllStrObj.GetSize(), 7); - ASSERT_EQ(sllStrObj.Display(), "This -> Good -> World -> Hello -> Morning -> Test -> Great -> "); + ASSERT_EQ(sllStrObj->DeleteData("Day"), true); + ASSERT_EQ(sllStrObj->GetFirstNode()->data, "This"); + ASSERT_EQ(sllStrObj->GetLastNode()->data, "Great"); + ASSERT_EQ(sllStrObj->GetSize(), 7); + ASSERT_EQ(sllStrObj->Display(), "This -> Good -> World -> Hello -> Morning -> Test -> Great -> "); } TEST_F(SinglyLinkedListStringTestF, DeleteDataAtTail) { - ASSERT_EQ(sllStrObj.DeleteData("Great"), true); - ASSERT_EQ(sllStrObj.GetFirstNode()->data, "Day"); - ASSERT_EQ(sllStrObj.GetLastNode()->data, "Test"); - ASSERT_EQ(sllStrObj.GetSize(), 7); - ASSERT_EQ(sllStrObj.Display(), "Day -> This -> Good -> World -> Hello -> Morning -> Test -> "); + ASSERT_EQ(sllStrObj->DeleteData("Great"), true); + ASSERT_EQ(sllStrObj->GetFirstNode()->data, "Day"); + ASSERT_EQ(sllStrObj->GetLastNode()->data, "Test"); + ASSERT_EQ(sllStrObj->GetSize(), 7); + ASSERT_EQ(sllStrObj->Display(), "Day -> This -> Good -> World -> Hello -> Morning -> Test -> "); } TEST_F(SinglyLinkedListStringTestF, DeleteDataInside) { - ASSERT_EQ(sllStrObj.DeleteData("Morning"), true); - ASSERT_EQ(sllStrObj.GetFirstNode()->data, "Day"); - ASSERT_EQ(sllStrObj.GetLastNode()->data, "Great"); - ASSERT_EQ(sllStrObj.GetSize(), 7); - ASSERT_EQ(sllStrObj.Display(), "Day -> This -> Good -> World -> Hello -> Test -> Great -> "); + ASSERT_EQ(sllStrObj->DeleteData("Morning"), true); + ASSERT_EQ(sllStrObj->GetFirstNode()->data, "Day"); + ASSERT_EQ(sllStrObj->GetLastNode()->data, "Great"); + ASSERT_EQ(sllStrObj->GetSize(), 7); + ASSERT_EQ(sllStrObj->Display(), "Day -> This -> Good -> World -> Hello -> Test -> Great -> "); } TEST_F(SinglyLinkedListStringTestF, DeleteMultipleData) { - ASSERT_EQ(sllStrObj.DeleteData("Good"), true); - ASSERT_EQ(sllStrObj.DeleteData("Hello"), true); - ASSERT_EQ(sllStrObj.DeleteData("Day"), true); - ASSERT_EQ(sllStrObj.DeleteData("This"), true); - ASSERT_EQ(sllStrObj.DeleteData("Great"), true); - ASSERT_EQ(sllStrObj.GetFirstNode()->data, "World"); - ASSERT_EQ(sllStrObj.GetLastNode()->data, "Test"); - ASSERT_EQ(sllStrObj.GetSize(), 3); - ASSERT_EQ(sllStrObj.Display(), "World -> Morning -> Test -> "); + ASSERT_EQ(sllStrObj->DeleteData("Good"), true); + ASSERT_EQ(sllStrObj->DeleteData("Hello"), true); + ASSERT_EQ(sllStrObj->DeleteData("Day"), true); + ASSERT_EQ(sllStrObj->DeleteData("This"), true); + ASSERT_EQ(sllStrObj->DeleteData("Great"), true); + ASSERT_EQ(sllStrObj->GetFirstNode()->data, "World"); + ASSERT_EQ(sllStrObj->GetLastNode()->data, "Test"); + ASSERT_EQ(sllStrObj->GetSize(), 3); + ASSERT_EQ(sllStrObj->Display(), "World -> Morning -> Test -> "); } #endif \ No newline at end of file From 5ad1864e37f62417f7ad3e7b5d50ad2afc5cad85 Mon Sep 17 00:00:00 2001 From: balanarayank <28087097+balanarayank@users.noreply.github.com> Date: Sat, 21 May 2022 13:32:57 +0530 Subject: [PATCH 4/4] Simplified CMakeLists --- CMakeLists.txt | 4 ++-- tests/CMakeLists.txt | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 43179da..b133e85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,10 @@ project(simple-cpp-datastructures) cmake_minimum_required(VERSION 3.14) -set(LINKEDLIST_INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc CACHE INTERNAL "") +set(LINKEDLIST_INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc) +include_directories(${LINKEDLIST_INC_DIR}) set(EXAMPLES_CPP_SOURCES examples/SinglyLinkedList.cpp) add_executable(${PROJECT_NAME} ${EXAMPLES_CPP_SOURCES}) -target_include_directories(${PROJECT_NAME} PRIVATE ${LINKEDLIST_INC_DIR}) add_subdirectory(tests) \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5d4dd77..046961a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,5 +11,4 @@ FetchContent_MakeAvailable(googletest) set(UT_CPP_SOURCES main_test.cc) add_executable(${PROJECT_NAME} ${UT_CPP_SOURCES}) -target_include_directories(${PROJECT_NAME} PRIVATE ${LINKEDLIST_INC_DIR}) target_link_libraries(${PROJECT_NAME} PRIVATE gtest gtest_main gmock gmock_main) \ No newline at end of file