From 4eb25a22b189ecf37657657729babad46335e55d Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Thu, 30 Apr 2020 23:43:25 -0400 Subject: [PATCH] RD of doubly linked list class --- plates/doublelist/Makefile | 10 +- plates/doublelist/doublelist.cpp | 185 +++++++++++++++---------------- plates/doublelist/doublelist.h | 32 +++--- plates/doublelist/driver.cpp | 10 +- 4 files changed, 112 insertions(+), 125 deletions(-) diff --git a/plates/doublelist/Makefile b/plates/doublelist/Makefile index dde1fa7..ac03db3 100644 --- a/plates/doublelist/Makefile +++ b/plates/doublelist/Makefile @@ -5,15 +5,15 @@ CXXFLAGS=-g -Wall # Driver ############################################################################### -driver: driver.cpp singlelist.o - ${CXX} ${CXXFLAGS} driver.cpp singlelist.o -o driver +driver: driver.cpp doublelist.o + ${CXX} ${CXXFLAGS} driver.cpp doublelist.o -o driver ############################################################################### -# SingleList +# DoubleList ############################################################################### -singlelist.o: singlelist.cpp singlelist.h - ${CXX} ${CXXFLAGS} -c singlelist.cpp -o singlelist.o +doublelist.o: doublelist.cpp doublelist.h + ${CXX} ${CXXFLAGS} -c doublelist.cpp -o doublelist.o ############################################################################### # Clean diff --git a/plates/doublelist/doublelist.cpp b/plates/doublelist/doublelist.cpp index d4b2a75..06df49e 100644 --- a/plates/doublelist/doublelist.cpp +++ b/plates/doublelist/doublelist.cpp @@ -1,25 +1,26 @@ /*############################################################################# ## Author: Shaun Reed ## ## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## -## About: An example of a singly linked list ## +## About: An example of a doubly linked list ## ## ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ############################################################################## -## singlelist.cpp +## doublelist.cpp */ -#include "singlelist.h" +#include "doublelist.h" + /****************************************************************************** * Constructors, Destructors, Operators - *****************************************************************************/ + *****************************************************************************/ /** copy constructor - * @brief Construct a new SingleList::SingleList object from an existing one - * - * @param rhs SingleList object + * @brief Construct a new DoubleList::DoubleList object from an existing one + * + * @param rhs DoubleList object */ -SingleList::SingleList(const SingleList& rhs) +DoubleList::DoubleList(const DoubleList& rhs) { Node *cp = rhs.head; Node *tempHead; @@ -37,14 +38,14 @@ SingleList::SingleList(const SingleList& rhs) } /** operator= - * @brief Assign two SingleList objects equal using copy constr and class destr + * @brief Assign two DoubleList objects equal using copy constr and class destr * Pass the rhs by value to create local copy, swap its contents - * Destructor called on previous SingleList data at the end of this scope - * - * @param rhs SingleList object passed by value - * @return SingleList A deep copy of the rhs SingleList object + * Destructor called on previous DoubleList data at the end of this scope + * + * @param rhs DoubleList object passed by value + * @return DoubleList A deep copy of the rhs DoubleList object */ -SingleList SingleList::operator=(SingleList rhs) +DoubleList DoubleList::operator=(DoubleList rhs) { if (this == &rhs) return *this; std::swap(head, rhs.head); @@ -52,26 +53,27 @@ SingleList SingleList::operator=(SingleList rhs) } /** destructor - * @brief Destroy the SingleList::SingleList object + * @brief Destroy the DoubleList::DoubleList object */ -SingleList::~SingleList() +DoubleList::~DoubleList() { makeEmpty(); } + /****************************************************************************** * Public Member Functions - *****************************************************************************/ + *****************************************************************************/ /** insert * @brief Inserts a value to the head of our linked list - * + * * @param x The value to be inserted */ -bool SingleList::insert(int val) +bool DoubleList::insert(int val) { bool inserted = insert(val, head); - if (inserted) + if (inserted) std::cout << "[" << val << "] was inserted into the list\n"; else std::cout << "[" << val << "] could not be inserted into the list\n"; return inserted; @@ -80,14 +82,14 @@ bool SingleList::insert(int val) /** insert at * @brief Inserts a value in the place of a given key * Key Node found is moved to the newNode->next positon - * + * * @param key The value to search for to determine insert location * @param val The value to be inserted into the list */ -bool SingleList::insert(int val, int key) +bool DoubleList::insert(int val, int key) { bool inserted = insert(val, key, head); - if (inserted) + if (inserted) std::cout << "[" << val << "] was inserted into the list\n"; else std::cout << "[" << val << "] could not be inserted into the list\n"; return inserted; @@ -95,15 +97,15 @@ bool SingleList::insert(int val, int key) /** remove * @brief Removes a value in the list by calling a private member and handling output - * + * * @param val Value to be removed from the list * @return true If the value was removed from the list * @return false If the value was not removed from the list */ -bool SingleList::remove(int val) +bool DoubleList::remove(int val) { bool removed = remove(val, head); - if (removed) + if (removed) std::cout << "[" << val << "] was removed from the list\n"; else std::cout << "[" << val << "] could not be removed from the list\n"; return removed; @@ -111,25 +113,25 @@ bool SingleList::remove(int val) /** replace * @brief Replaces a value in the list by calling a private member and handling output - * + * * @param val Value to insert into the list * @param key Value to be replaced within the list * @return true If the key has been replaced in the list by val * @return false If the key has not been replaced in the list by val */ -bool SingleList::replace(int val, int key) +bool DoubleList::replace(int val, int key) { bool replaced = replace(val, key, head); - if (replaced) + if (replaced) std::cout << "[" << key << "] was replaced by [" << val << "] in the list\n"; else std::cout << "[" << key << "] could not be replaced by [" << val << "] in the list\n"; return replaced; } /** makeEmpty - * @brief Empty this SingleList object, deleting all associated Nodes + * @brief Empty this DoubleList object, deleting all associated Nodes */ -void SingleList::makeEmpty() +void DoubleList::makeEmpty() { Node *nextNode, *temp; @@ -146,33 +148,34 @@ void SingleList::makeEmpty() } /** isEmpty - * @brief Determine if the SingleList is empty - * - * @return true If the SingleList::head is NULL - * @return false If the SingleList::head contains data + * @brief Determine if the DoubleList is empty + * + * @return true If the DoubleList::head is NULL + * @return false If the DoubleList::head contains data */ -bool SingleList::isEmpty() const +bool DoubleList::isEmpty() const { return head == NULL; } /** peek - * @brief returns the value at the SingleList::head - * - * @return int The value held at the Node pointed to by SingleList::head + * @brief returns the value at the DoubleList::head + * + * @return int The value held at the Node pointed to by DoubleList::head */ -void SingleList::peek() const +int DoubleList::peek() const { - if (!isEmpty()) + if (!isEmpty()) std::cout << "[" << head->data << "] is at the top of our list\n"; else std::cout << "Nothing to peek, our list is empty...\n"; + return head->data; } /** print - * @brief Output the data held by the SingleList object + * @brief Output the data held by the DoubleList object * Calls to the private print() */ -void SingleList::print() const +void DoubleList::print() const { if(!isEmpty()) print(head); else std::cout << "Nothing to print, our list is empty...\n"; @@ -180,106 +183,116 @@ void SingleList::print() const /** find * @brief Calls to the private member find() and handles return cases - * - * @param val The value to search for within our SingleList - * @return true If the value was found in this SingleList - * @return false If the value was not found in this SingleList + * + * @param val The value to search for within our DoubleList + * @return true If the value was found in this DoubleList + * @return false If the value was not found in this DoubleList */ -bool SingleList::find(int val) const +bool DoubleList::find(int val) const { Node *result = find(val, head); if( result == NULL) { std::cout << "[" << val << "] Was not found in our list\n"; return false; } - + std::cout << "[" << result->data << "] Was found in our list\n"; return true; } + /****************************************************************************** * Private Member Functions - *****************************************************************************/ + *****************************************************************************/ /** insert * @brief Private member to handle inserting value into the list - * + * * @param val Value to be inserted * @param head The head of the list to insert the value into * @return true If the value was inserted * @return false If the value could not be inserted */ -bool SingleList::insert(int val, Node *&head) +bool DoubleList::insert(int val, Node *&head) { Node *newNode = new Node(val); // If the list is not empty, update next pointer to head node - if (!isEmpty()) newNode->next = head; + if (!isEmpty()) { + newNode->next = head; + // Create a prev ptr for the head node + head->prev = newNode; + } // Always set head to our newNode - head = newNode; + head = newNode; return true; } /** insert at * @brief Private member to handle inserting a value at a key within our list - * + * * @param val Value to be inserted * @param key Key value to search for within the list * @param head Head node of the list to insert to * @return true If the value was inserted * @return false If the value was not inserted */ -bool SingleList::insert(int val, int key, Node *&head) +bool DoubleList::insert(int val, int key, Node *&head) { Node *newNode = new Node(val); if (isEmpty()) return false; // Let insert() handle inserting at the head else if (head->data == key) return insert(val); - Node *keyNode = findPrevious(key, head); + Node *keyNode = find(key, head); // If there was no keyNode found, the key does is not in our list // Don't insert anything, return false and let caller decide whats next if (keyNode == NULL) return false; - // Set the newNode to come BEFORE our keyNode - newNode->next = keyNode->next; - keyNode->next = newNode; + // Insert the newNode infront of the previous to the keyNode + newNode->prev = keyNode->prev; + keyNode->prev->next = newNode; + + // Change the keyNode->prev ptr to newNode + newNode->next = keyNode; + keyNode->prev = newNode; return true; } /** remove * @brief Private member to remove values from the list - * + * * @param val Value to be removed * @param head Head of the list to remove the value from * @return true If the value has been removed from the list * @return false If the value has not been removed from the list */ -bool SingleList::remove(int val, Node *&head) +bool DoubleList::remove(int val, Node *&head) { - if (head == NULL) return false; else if (head->data == val) { head = head->next; return true; } - Node *prevNode = findPrevious(val, head); - if (prevNode == NULL) return false; - Node *gtfo = prevNode->next; - prevNode->next = prevNode->next->next; + Node *keyNode = find(val, head); + if (keyNode == NULL) return false; + Node *gtfo = keyNode; + if (keyNode->next != NULL) keyNode->next->prev = keyNode->prev; + if (keyNode->prev != NULL) keyNode->prev->next = keyNode->next; delete gtfo; + gtfo = NULL; return true; } /** replace * @brief Private member to replace values within the list - * + * * @param val Value to insert into the list * @param key Value to be replaced within the list * @param head Head of the list to replace the value * @return true If the key has been replaced by val within the list * @return false If the key has not been replaced by val within the list */ -bool SingleList::replace(int val, int key, Node *&head) +bool DoubleList::replace(int val, int key, Node *&head) { Node *replacee = find(key, head); if (replacee == NULL) return false; @@ -289,11 +302,11 @@ bool SingleList::replace(int val, int key, Node *&head) /** find * @brief Find and return a Node which contains the given value - * - * @param val The value to search for within our SingleList - * @return SingleList::Node* A pointer to the Node containing the search value + * + * @param val The value to search for within our DoubleList + * @return DoubleList::Node* A pointer to the Node containing the search value */ -SingleList::Node* SingleList::find(int val, Node *start) const +DoubleList::Node* DoubleList::find(int val, Node *start) const { // If given a NULL list, return NULL // If given a head which contains the requested value, return the foundNode @@ -308,32 +321,12 @@ SingleList::Node* SingleList::find(int val, Node *start) const return NULL; } -/** findPrevious - * @brief Find and return the Node before a given value - * - * @param val The value to search for within our SingleList - * @return SingleList::Node* A pointer to the Node previous to the given value - */ -SingleList::Node* SingleList::findPrevious(int val, Node *start) const -{ - if (isEmpty()) return NULL; - else if (start->data == val) return start; - - Node *temp = start; - while (temp->next != NULL) { - if (temp->next->data == val) return temp; - temp = temp->next; - } - - return NULL; -} - /** print - * @brief Output the contents of a SingleList from the given Node to NULL - * + * @brief Output the contents of a DoubleList from the given Node to NULL + * * @param start The Node to begin traversing output from */ -void SingleList::print(Node *start) const +void DoubleList::print(Node *start) const { Node *temp = start; std::cout << "List Contents: "; diff --git a/plates/doublelist/doublelist.h b/plates/doublelist/doublelist.h index 24bcda2..b31798a 100644 --- a/plates/doublelist/doublelist.h +++ b/plates/doublelist/doublelist.h @@ -1,45 +1,40 @@ /*############################################################################# ## Author: Shaun Reed ## ## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## -## About: An example of a singly linked list ## -## ## -## Structure: Remove: Insert: Insert at: Replace: ## -## o-o-o-o-o-o o-o--x-->o-o-o o o o ## -## | /| / \ ## -## o-o-o-o-o-o o-o~o-o-o-o o-o~x~o-o-o ## +## About: An example of a doubly linked list ## ## ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ############################################################################## -## singlelist.h +## doublelist.h */ -#ifndef LINKEDLIST_H -#define LINKEDLIST_H +#ifndef DOUBLELIST_H +#define DOUBLELIST_H #include -class SingleList{ +class DoubleList { public: - SingleList() : head(NULL) {}; - SingleList(const SingleList& rhs); - SingleList operator=(SingleList rhs); - ~SingleList(); + DoubleList() : head(NULL) {}; + DoubleList(const DoubleList& rhs); + DoubleList operator=(DoubleList rhs); + ~DoubleList(); bool insert(int val); bool insert(int val, int key); bool remove(int val); bool replace(int val, int key); void makeEmpty(); bool isEmpty() const; - void peek() const; + int peek() const; void print() const; bool find(int val) const; private: struct Node { int data; - Node *next; - Node(): data(), next(NULL) {}; - Node(int val): data(val), next(NULL) {}; + Node *next, *prev; + Node(): data(), next(NULL), prev(NULL) {}; + Node(int val): data(val), next(NULL), prev(NULL) {}; }; Node *head; bool insert(int val, Node *&head); @@ -47,7 +42,6 @@ class SingleList{ bool remove(int val, Node *&head); bool replace(int val, int key, Node *&head); Node* find(int val, Node *start) const; - Node* findPrevious(int val, Node *start) const; void print(Node *start) const; }; diff --git a/plates/doublelist/driver.cpp b/plates/doublelist/driver.cpp index be746e1..9959add 100644 --- a/plates/doublelist/driver.cpp +++ b/plates/doublelist/driver.cpp @@ -1,14 +1,14 @@ /*############################################################################# ## Author: Shaun Reed ## ## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## -## About: A driver program to test a singly linked list ## +## About: A driver program to test a doubly linked list ## ## ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ############################################################################## ## driver.cpp */ -#include "singlelist.h" +#include "doublelist.h" #include enum OPS { @@ -19,7 +19,7 @@ int main() { std::cout << "Driver: \n"; - SingleList testList; + DoubleList testList; bool exit = false; int choice = -1; int val, key; @@ -51,7 +51,7 @@ int main() std::cin >> key; std::cin.clear(); if (testList.insert(val, key)) { - std::cout << "List after inserting [" + std::cout << "List after inserting [" << val << "] at [" << key << "]: \n"; testList.print(); } @@ -91,7 +91,7 @@ int main() std::cin >> key; std::cin.clear(); if (testList.replace(val, key)) { - std::cout << "List after replacing [" + std::cout << "List after replacing [" << key << "] by [" << val << "]: \n"; testList.print(); }