/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Champlain College SDEV-345-81 * * C++ Week 5: Linked Lists (first semester) - linked list program (2020/09/20) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Write a menu driven program that simulates a simple linked list. The program * should give the user the following options and should run in an infinite loop: * 1) Insert node * 2) Delete node * 3) Display list * 4) Find node * * 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 5: Lectures // Demonstrates sorted linked list #include using namespace std; ///////////////////////////////////////////////////////////// class Node { public: int iData; // data item double dData; // data item Node *pNext; // ptr to next link in list //---------------------------------------------------------- Node(int id, double dd) : // constructor iData(id), dData(dd), pNext(NULL) {} //---------------------------------------------------------- void displayNode() // display ourselves {22, 2.99} { cout << "{" << iData << ", " << dData << "} "; } //---------------------------------------------------------- }; // end class Node ///////////////////////////////////////////////////////////// class NodeList { private: Node *pFirst; // ptr to first link on list public: //---------------------------------------------------------- NodeList() : pFirst(NULL) // constructor {} // no links on list yet //---------------------------------------------------------- ~NodeList(){ // destructor while(!isEmpty()){ // until it's empty, removeFirst(); // remove it } } //---------------------------------------------------------- bool isEmpty() // true if list is empty { return pFirst == NULL; } //---------------------------------------------------------- // insert at start of list void insertFirst(int id, double dd) { // make new link Node *pNewNode = new Node(id, dd); pNewNode->pNext = pFirst; // newNode-->old first pFirst = pNewNode; // first-->newNode } //---------------------------------------------------------- Node *getFirst() // return first link { return pFirst; } //---------------------------------------------------------- void insert(int key, double dd) // insert, in order { Node* pNewLink = new Node(key, dd); // make new link Node* pPrevious = NULL; // pointer to previous Node* pCurrent = pFirst; // start at first // Look for position prior to the end of the list while(pCurrent != NULL && key > pCurrent->iData) // We sort insert by key and not value { pPrevious = pCurrent; // adjust previous ptr pCurrent = pCurrent->pNext; // go to next item } // Insert link the link if(pPrevious==NULL) // at beginning of list pFirst = pNewLink; // first --> newLink else // not at beginning pPrevious->pNext = pNewLink; // old prev --> newLink pNewLink->pNext = pCurrent; // newLink --> old current } // end insert() //---------------------------------------------------------- void removeFirst() // delete first link { // (assumes list not empty) Node *pTemp = pFirst; // save first pFirst = pFirst->pNext; // unlink it: first-->old next delete pTemp; // delete old first } //----------------------------------------------------------- Node* find(int key) // find link with given key { // (assumes non-empty list) Node* pCurrent = pFirst; // start at 'first' while(pCurrent->iData != key) // while no match, { if(pCurrent->pNext == NULL) // if end of list, return NULL; // didn't find it else // not end of list, pCurrent = pCurrent->pNext; // go to next link } return pCurrent; // found it } //----------------------------------------------------------- Node* find(double key) // find link with given key { // (assumes non-empty list) Node* pCurrent = pFirst; // start at 'first' while(pCurrent->dData != key) // while no match, { if(pCurrent->pNext == NULL) // if end of list, return NULL; // didn't find it else // not end of list, pCurrent = pCurrent->pNext; // go to next link } return pCurrent; // found it } //----------------------------------------------------------- bool remove(int key) // remove link with given key { // (assumes non-empty list) Node* pCurrent = pFirst; // search for link Node* pPrevious = pFirst; while(pCurrent->iData != key) { if(pCurrent->pNext == NULL) return false; // didn't find it else { pPrevious = pCurrent; // go to next link pCurrent = pCurrent->pNext; } } // found it if(pCurrent == pFirst) // if first link, pFirst = pFirst->pNext; // change first else // otherwise, pPrevious->pNext = pCurrent->pNext; // bypass it delete pCurrent; // delete link return true; // successful removal } //----------------------------------------------------------- bool remove(double value) // remove link with given key { // (assumes non-empty list) Node* pCurrent = pFirst; // search for link Node* pPrevious = pFirst; while(pCurrent->dData != value) { if(pCurrent->pNext == NULL) return false; // didn't find it else { pPrevious = pCurrent; // go to next link pCurrent = pCurrent->pNext; } } // found it if(pCurrent == pFirst) { // if first link, if (pCurrent->pNext == NULL) { pFirst = pFirst->pNext; // change first } else { pFirst = NULL; // empty the list } } else { // otherwise, pPrevious->pNext = pCurrent->pNext; // bypass it } delete pCurrent; // delete link return true; // successful removal } //---------------------------------------------------------- void displayList() { cout << "List (first-->last): "; Node *pCurrent = pFirst; // start at beginning of list while (pCurrent != NULL) // until end of list, { pCurrent->displayNode(); // print data pCurrent = pCurrent->pNext; // move to next link } cout << endl; } //---------------------------------------------------------- }; // end class NodeList ///////////////////////////////////////////////////////////// void getUserInput(int &action, const string& act){ // get the user input cin.clear(); while (true) { cout << act << " a node by key or value." << endl; cout << "1] Key" << endl; // Select to find by key cout << "2] Value" << endl; // Select to find by value cout << "[1/2]: "; cin >> action; if (!cin.fail() && (action == 1 || action == 2)) { cin.ignore(numeric_limits::max(), '\n'); break; } cin.clear(); cin.ignore(numeric_limits::max(), '\n'); cout << "Selection must be between 1 or 2, lets try again." << endl; } } void getUserInput(const string& question, int &key){ cin.clear(); while (true) { cout << question << endl; cout << "[integer]: "; // get only an integer cin >> key; if (!cin.fail() && key > 0) { cin.ignore(numeric_limits::max(), '\n'); break; } cin.clear(); cin.ignore(numeric_limits::max(), '\n'); cout << "The key must be an integers above zero, lets try again." << endl; } } void getUserInput(const string& question, double &value){ cin.clear(); while (true) { cout << question << endl; cout << "[double]: "; 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, NodeList& theList){ while (true) { if (theList.isEmpty()) { cout << "Your link-list is empty, insert your first node." << endl; action = 1; break; } cin.clear(); cout << "1] Insert Node" << endl; // Select to insert node cout << "2] Delete Node" << endl; // Select to delete node cout << "3] Display List" << endl; // Select to display list cout << "4] Find node" << endl; // Select to display list cout << "[1-4]: "; cin >> action; action = (int) action; if (!cin.fail() && action > 0 && action < 5) { break; } cin.clear(); cin.ignore(numeric_limits::max(), '\n'); cout << "Selection must be between 1 and 4, lets try again." << endl; } } ///////////////////////////////////////////////////////////// int main() { NodeList theList; // make new list int action; // the driver action int idata; // the driver int Data double ddata; // the driver double Data cout << "Demonstrating the infinite link-list program" << endl; // little notice while (true) { displayMenu(action, theList); // display the menu if (action == 1){ // insert a node getUserInput("Enter a key", idata); getUserInput("Enter a value", ddata); theList.insert(idata, ddata); cout << "A node with this key(" << idata << ") and this value(" << ddata << ") was added." << endl; } else if (action == 2){ // delete node getUserInput(action, "Delete"); if (action == 1) { getUserInput("Enter a key to delete", idata); if (theList.remove(idata)){ cout << "The first node with this key(" << idata << ") was removed." << endl; } else { cout << "A node with this key(" << idata << ") was not found." << endl; } } else if (action == 2) { getUserInput("Enter a value to delete", ddata); if (theList.remove(ddata)){ cout << "The first node with this value(" << ddata << ") was removed." << endl; } else { cout << "A node with this value(" << ddata << ") was not found." << endl; } } } else if (action == 3){ // display list theList.displayList(); } else if (action == 4){ // find node getUserInput(action, "Find"); if (action == 1) { getUserInput("Enter a key to find", idata); Node* found = theList.find(idata); if (found){ cout << "The first node with this key(" << idata << ") was found. "; found->displayNode(); cout << endl; } else { cout << "A node with this key(" << idata << ") was NOT found." << endl; } } else if (action == 2) { getUserInput("Enter a value to find", ddata); Node* found = theList.find(ddata); if (found){ cout << "The first node with this value(" << ddata << ") was found. "; found->displayNode(); cout << endl; } else { cout << "A node with this value(" << ddata << ") was NOT found." << endl; } } } else { break; // just to remove endless loop warning (should never happen) } } return 0; } // end main()