diff --git a/week-07/CMakeLists.txt b/week-07/CMakeLists.txt new file mode 100644 index 0000000..31ba0cb --- /dev/null +++ b/week-07/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.16) +project(week-07) + +set(CMAKE_CXX_STANDARD 17) + +add_executable(week-07 main.cpp) diff --git a/week-07/main.cpp b/week-07/main.cpp new file mode 100644 index 0000000..791915d --- /dev/null +++ b/week-07/main.cpp @@ -0,0 +1,230 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Champlain College SDEV-345-81 + * + * C++ Week 6: Circular or Doubly Linked Lists (first semester) - Linked Lists program (2020/10/16) + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Write a menu driven program that creates a doubly linked list. + * The program should give the user the following options and should + * run in an infinite loop: + * 1) Insert first node + * 2) Insert last node + * 3) Delete first node + * 4) Delete last node + * 5) Display list forward + * 6) Display list backwards + * + * Do not use the C++ Standard template library. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Written by Llewellyn van der Merwe , October 2020 + * Copyright (C) 2020. All Rights Reserved + * License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Adaptation to the code found at +// Week 7: Lecture 4 - Doubly Linked CPP +// Demonstrates Doubly Linked Lists +#include + +using namespace std; + +//////////////////////////////////////////////////////////////// +class Link +{ +public: + double dData; // data item + Link* pNext; // next link in list + Link* pPrevious; // previous link in list +public: +//------------------------------------------------------------- + Link(double dd) : // constructor + dData(dd), pNext(NULL), pPrevious(NULL) + { } +//------------------------------------------------------------- + void displayLink() // display this link + { cout << dData << " "; } +//------------------------------------------------------------- +}; //end class Link +//////////////////////////////////////////////////////////////// +class DoublyLinkedList +{ +private: + Link* pFirst; // pointer to first item + Link* pLast; // pointer to last item +public: +//------------------------------------------------------------- + DoublyLinkedList() : // constructor + pFirst(NULL), pLast(NULL) + { } +//------------------------------------------------------------- + ~DoublyLinkedList() // destructor (deletes links) + { + Link* pCurrent = pFirst; // start at beginning of list + while(pCurrent != NULL) // until end of list, + { + Link* pOldCur = pCurrent; // save current link + pCurrent = pCurrent->pNext; // move to next link + delete pOldCur; // delete old current + } + } +//------------------------------------------------------------- + bool isEmpty() // true if no links + { return pFirst==NULL; } +//------------------------------------------------------------- + void insertFirst(double dd) // insert at front of list + { + Link* pNewLink = new Link(dd); // make new link + + if( isEmpty() ) // if empty list, + pLast = pNewLink; // newLink <-- last + else + pFirst->pPrevious = pNewLink; // newLink <-- old first + pNewLink->pNext = pFirst; // newLink --> old first + pFirst = pNewLink; // first --> newLink + } +//------------------------------------------------------------- + void insertLast(double dd) // insert at end of list + { + Link* pNewLink = new Link(dd); // make new link + if( isEmpty() ) // if empty list, + pFirst = pNewLink; // first --> newLink + else + { + pLast->pNext = pNewLink; // old last --> newLink + pNewLink->pPrevious = pLast; // old last <-- newLink + } + pLast = pNewLink; // newLink <-- last + } +//------------------------------------------------------------- + void removeFirst() // remove first link + { // (assumes non-empty list) + Link* pTemp = pFirst; + if(pFirst->pNext == NULL) // if only one item + pLast = NULL; // null <-- last + else + pFirst->pNext->pPrevious = NULL; // null <-- old next + pFirst = pFirst->pNext; // first --> old next + delete pTemp; // delete old first + } +//------------------------------------------------------------- + void removeLast() // remove last link + { // (assumes non-empty list) + Link* pTemp = pLast; + if(pFirst->pNext == NULL) // if only one item + pFirst = NULL; // first --> null + else + pLast->pPrevious->pNext = NULL; // old previous --> null + pLast = pLast->pPrevious; // old previous <-- last + delete pTemp; // delete old last + } +//------------------------------------------------------------- + void displayForward() + { + cout << "List (first-->last): "; + Link* pCurrent = pFirst; // start at beginning + while(pCurrent != NULL) // until end of list, + { + pCurrent->displayLink(); // display data + pCurrent = pCurrent->pNext; // move to next link + } + cout << endl; + } +//------------------------------------------------------------- + void displayBackward() + { + cout << "List (last-->first): "; + Link* pCurrent = pLast; // start at end + while(pCurrent != NULL) // until start of list, + { + pCurrent->displayLink(); // display data + pCurrent = pCurrent->pPrevious; // go to previous link + } + cout << endl; + } +//------------------------------------------------------------- +}; //end class DoublyLinkedList +//////////////////////////////////////////////////////////////// +void getUserInput(const string &question, double &value) { + cin.clear(); + while (true) { + cout << question << endl; + cout << "[value]: "; + cin >> value; // get only an double + if (!cin.fail() && value > 0) { + cin.ignore(numeric_limits::max(), '\n'); + break; + } + cin.clear(); + cin.ignore(numeric_limits::max(), '\n'); + cout << "The value must be an double above zero, lets try again." << endl; + } +} +void displayMenu(int &action) { + while (true) { + cin.clear(); + cout << " 1] Insert first node" << endl; + cout << " 2] Insert last node" << endl; + cout << " 3] Delete first node" << endl; + cout << " 4] Delete last node" << endl; + cout << " 5] Display list forward" << endl; + cout << " 6] Display list backwards" << endl; + cout << " [1-6]: "; + cin >> action; + action = (int) action; + if (!cin.fail() && action > 0 && action < 7) { + break; + } + cin.clear(); + cin.ignore(numeric_limits::max(), '\n'); + cout << "Selection must be between 1 and 6, lets try again." << endl; + } +} +//////////////////////////////////////////////////////////////// +int main() +{ + DoublyLinkedList theList; // make a new list + int action; // the driver action + double data; // the driver double Data + cout << "Demonstrating the infinite doubly linked list program" << endl; // little notice + while (true) { + displayMenu(action); // display the menu + if (action == 1) { // Insert first node + getUserInput("Enter a number", data); + theList.insertFirst(data); + } else if (action == 2) { // Insert last node + getUserInput("Enter a number", data); + theList.insertLast(data); + } else if (action == 3) { // Delete first node + if (!theList.isEmpty()) { + theList.removeFirst(); + } else { + cout << "The doubly linked list is empty, can not remove any items." << endl; + } + } else if (action == 4) { // Delete last node + if (!theList.isEmpty()) { + theList.removeLast(); + } else { + cout << "The doubly linked list is empty, can not remove any items." << endl; + } + } else if (action == 5) { // Display list forward + if (!theList.isEmpty()) { + theList.displayBackward(); + } else { + cout << "The doubly linked list is empty, no items to display backward." << endl; + } + } else if (action == 6) { // Display list backwards + if (!theList.isEmpty()) { + theList.displayForward(); + } else { + cout << "The doubly linked list is empty, no items to display forward." << endl; + } + } else { + break; // just to remove endless loop warning (should never happen) + } + } + return 0; +}