SDEV-324-81/week-07/main.cpp

231 lines
9.5 KiB
C++

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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 <llewellyn.vandermerw@mymail.champlain.edu>, 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 <iostream>
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<streamsize>::max(), '\n');
break;
}
cin.clear();
cin.ignore(numeric_limits<streamsize>::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<streamsize>::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;
}