From 0661f09ae85bcdd59d45b7a5ec1010fe39025437 Mon Sep 17 00:00:00 2001 From: Adarsh Kishore <76656932+adarsh-kishore786@users.noreply.github.com> Date: Tue, 14 Sep 2021 19:15:07 +0530 Subject: [PATCH] chore(CPlusPlus): add linked list implementation (#463) --- algorithms/CPlusPlus/Linked-Lists/singly.cpp | 158 ++++++++++++++++--- 1 file changed, 134 insertions(+), 24 deletions(-) diff --git a/algorithms/CPlusPlus/Linked-Lists/singly.cpp b/algorithms/CPlusPlus/Linked-Lists/singly.cpp index 178cc7e7..34bd698e 100644 --- a/algorithms/CPlusPlus/Linked-Lists/singly.cpp +++ b/algorithms/CPlusPlus/Linked-Lists/singly.cpp @@ -1,19 +1,23 @@ #include +#include -template -class Node { - public: - T data; - Node *next; +using dType = int; - Node(T data) - : data(data) , next(nullptr) {}; - Node(){} -}; template class SinglyLinkedList { private: + template + class Node { + public: + T data; + Node *next; + + Node(T data) + : data(data) , next(nullptr) {}; + Node(){} + }; + Node* head; Node* tail; @@ -21,6 +25,19 @@ class SinglyLinkedList { SinglyLinkedList() : head(nullptr),tail(nullptr){} + ~SinglyLinkedList(){ + Node *itr = this->head; + // iterate through list until itr reach to nullptr and print data + while(itr != nullptr) { + // creating temporary pointer to delete memory + Node *temp_ptr = itr; + itr = itr->next; + delete temp_ptr; + } + + // std::cout << "Destructor called\n"; + } + void insertAtHead(T data) { Node *temp = new Node(data); @@ -36,7 +53,7 @@ class SinglyLinkedList { // change head point to new node this->head = temp; } - + void insertAtEnd(T data){ Node *newNode = new Node(data); @@ -57,10 +74,8 @@ class SinglyLinkedList { T removeAtHead() { // if list is empty we can't remove node - if(this->head == nullptr) { - std::cout<<"List is Empty"<head == nullptr) + throw std::runtime_error("List is Empty."); // save data of node where head is pointed T data = this->head->data; @@ -73,9 +88,59 @@ class SinglyLinkedList { return data; } + T removeAtEnd() { + // if list is empty we can't remove node + if (this->head == nullptr) + throw std::runtime_error("List is Empty."); + // if list is singleton it just becomes nullptr + if(this->head->next == nullptr) { + T data = this->tail->data; + + Node* temp_ptr = this->tail; + this->head = nullptr; + this->tail = nullptr; + + delete temp_ptr; + return data; + } + + // save data of node where tail is pointed + T data = this->tail->data; + + // now iterate to one before last pointer + Node* currNode = this->head; + Node* nextNode = currNode->next; + + while (nextNode && nextNode->next) + { + currNode = nextNode; + nextNode = nextNode->next; + } + + // save temp pointer to free the memory + Node* temp_ptr = this->tail; + currNode->next = nullptr; + this->tail = currNode; + + delete temp_ptr; + return data; + } + + T front() { + if(this->head == nullptr) + throw std::runtime_error("Empty List."); + return this->head->data; + } + + T back() { + if(this->head == nullptr) + throw std::runtime_error("Empty List."); + return this->tail->data; + } + void printList() const { if(this->head == nullptr) { - std::cout<<"List is Empty"< *itr = this->head; // iterate through list until itr reach to nullptr and print data @@ -88,13 +153,58 @@ class SinglyLinkedList { } }; -int main() { - SinglyLinkedList l; - l.insertAtHead(1); - l.insertAtHead(2); - l.insertAtHead(3); - l.insertAtEnd(5); - l.removeAtHead(); - l.printList(); - return 0; +template +void insert_element(SinglyLinkedList& list, bool front) { + T val {}; + std::cout << "Enter value to be inserted: "; + std::cin >> val; + + if (front) list.insertAtHead(val); + else list.insertAtEnd(val); +} + +void menu() { + SinglyLinkedList list {}; + while (true) { + std::cout << "\nWhat would you like to do?\n"; + std::cout << "1. Push back an element\n"; + std::cout << "2. Push front an element\n"; + std::cout << "3. Display the linked list\n"; + std::cout << "4. Get front\n"; + std::cout << "5. Get back\n"; + std::cout << "6. Pop front\n"; + std::cout << "7. Pop back\n"; + std::cout << "8. Quit\n"; + std::cout << "Enter corresponding number to your choice: "; + int ch {}; + std::cin >> ch; + + try { + switch (ch) { + case 1: insert_element(list, false); + break; + case 2: insert_element(list, true); + break; + case 3: list.printList(); + break; + case 4: std::cout << list.front() << "\n"; + break; + case 5: std::cout << list.back() << "\n"; + break; + case 6: list.removeAtHead(); + break; + case 7: list.removeAtEnd(); + break; + case 8: return; + default: std::cout << "That's an invalid option. Please try again.\n"; + } + } + catch (const std::runtime_error& re) { + std::cerr << re.what() << "\n"; + } + } +} + +int main() { + menu(); }