diff --git a/cpp/datastructs/queuelist/Makefile b/cpp/datastructs/queuelist/Makefile new file mode 100644 index 0000000..0197dd3 --- /dev/null +++ b/cpp/datastructs/queuelist/Makefile @@ -0,0 +1,23 @@ +CXX=g++ +CXXFLAGS=-g -Wall + +############################################################################### +# Driver +############################################################################### + +driver: driver.cpp queuelist.o + ${CXX} ${CXXFLAGS} driver.cpp queuelist.o -o driver + +############################################################################### +# QueueList +############################################################################### + +queuelist.o: queuelist.cpp queuelist.h + ${CXX} ${CXXFLAGS} -c queuelist.cpp -o queuelist.o + +############################################################################### +# Clean +############################################################################### + +clean: + rm -f *.o driver diff --git a/cpp/datastructs/queuelist/driver.cpp b/cpp/datastructs/queuelist/driver.cpp new file mode 100644 index 0000000..508a05c --- /dev/null +++ b/cpp/datastructs/queuelist/driver.cpp @@ -0,0 +1,68 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: A driver program to test a queue implementation using linked lists ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## driver.cpp +*/ + +#include "queuelist.h" +#include + +enum OPS { + EXIT, ENQUEUE, DEQUEUE, NEXT, PRINT, EMPTY +}; + +int main() +{ + std::cout << "Driver: \n"; + + QueueList testList; + bool exit = false; + int choice = -1; + int val; + + while (!exit) + { + std::cout << "##### Queues Using Linked Lists Menu #####\n\t0. Exit" + << "\n\t1. Enqueue\n\t2. Dequeue\n\t3. Next\n\t4. Print" + << "\n\t5. Empty\n\t"; + std::cin >> choice; + std::cin.clear(); + switch (choice) { + case EXIT: + exit = true; + break; + + case ENQUEUE: + std::cout << "Enter a value to add to the end of our queue: "; + std::cin >> val; + std::cin.clear(); + testList.enqueue(val); + break; + + case DEQUEUE: + testList.dequeue(); + break; + + case NEXT: + testList.next(); + break; + + case PRINT: + testList.print(); + break; + + case EMPTY: + testList.makeEmpty(); + break; + + default: + std::cout << "Invalid entry...\n"; + break; + } + } +} + diff --git a/cpp/datastructs/queuelist/queuelist.cpp b/cpp/datastructs/queuelist/queuelist.cpp new file mode 100644 index 0000000..ee01580 --- /dev/null +++ b/cpp/datastructs/queuelist/queuelist.cpp @@ -0,0 +1,255 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a queue implementation using linked lists ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## queuelist.cpp +*/ + +#include "queuelist.h" + + +/****************************************************************************** + * Constructors, Destructors, Operators + *****************************************************************************/ + +/** copy constructor + * @brief Construct a new QueueList::QueueList object from an existing one + * Creates a new deep copy of a given QueueList + * + * @param rhs QueueList object + */ +QueueList::QueueList(const QueueList& rhs) +{ + Node *cp = rhs.head; + Node *tempHead; + // If we are copying from an empty queue, create a new QueueList with a NULL head + if (cp == NULL) head = NULL; + else { + // If the queue has data, initialize a new queue with the head data + head = new Node(cp->data); + // Keep a temporary head node so we can return to it later + tempHead = head; + while (cp->next != NULL) { + // Until we hit an end, create new nodes with the next node data + cp = cp->next; + head->next = new Node(cp->data); + head = head->next; + } + tail = head; + head = tempHead; + } +} + +/** operator= + * @brief Assign two QueueList objects equal using copy constr and class destr + * Pass the rhs by value to create local copy, swap its contents + * Destructor called on previous QueueList data at the end of this scope + * + * @param rhs QueueList object passed by value + * @return QueueList A deep copy of the rhs QueueList object + */ +QueueList QueueList::operator=(QueueList rhs) +{ + if (this == &rhs) return *this; + // Swap the pointers, moving the previous head data to the local variable rhs + std::swap(head, rhs.head); + return *this; +} + +/** destructor + * @brief Destroy the QueueList::QueueList object + */ +QueueList::~QueueList() +{ + makeEmpty(head); +} + + +/****************************************************************************** + * Public Member Functions + *****************************************************************************/ + +/** enqueue + * @brief Queue a value to the tail of our linked list + * + * @param x The value to be inserted into the queue + */ +bool QueueList::enqueue(int val) +{ + bool inserted = enqueue(val, tail); + if (inserted) + std::cout << "[" << val << "] was inserted into the queue\n"; + else std::cout << "[" << val << "] could not be inserted into the queue\n"; + return inserted; +} + +/** dequeue + * @brief returns the value at the QueueList::head and moves head to the next in queue + * + * @return int The value held at the Node pointed to by QueueList::head + */ +int QueueList::dequeue() +{ + if (!isEmpty()) + std::cout << "[" << dequeue(head) << "] has been removed from our queue\n"; + else std::cout << "Nothing to dequeue, our queue is empty...\n"; + // If the queue has data we return it, otherwise we return the smallest possible int (error) + return (!isEmpty()) ? head->data : INT32_MIN; +} + +/** next + * @brief returns the value at the QueueList::head + * + * @return int The value held at the Node pointed to by QueueList::head + */ +int QueueList::next() const +{ + if (!isEmpty()) + std::cout << "[" << head->data << "] is next in queue\n"; + else std::cout << "Our queue is empty...\n"; + // If the queue has data we return it, otherwise we return the smallest possible int (error) + return (!isEmpty()) ? head->data : INT32_MIN; +} + +/** isEmpty + * @brief Determine if the QueueList is empty + * + * @return true If the QueueList::head is NULL + * @return false If the QueueList::head contains data + */ +bool QueueList::isEmpty() const +{ + return head == NULL; +} + +/** print + * @brief Output the data held by the QueueList object + * Calls to the private print() + */ +void QueueList::print() const +{ + if(!isEmpty()) print(head); + else std::cout << "Nothing to print, our queue is empty...\n"; +} + +/** makeEmpty + * @brief Empty this QueueList object, deleting all associated Nodes + */ +void QueueList::makeEmpty() +{ + Node *nextNode, *temp; + + if (head == NULL) std::cout << "Our queue is empty...\n"; + else { + nextNode = head->next; + delete head; + head = NULL; + tail = NULL; + while(nextNode != NULL) { + temp = nextNode; + nextNode = nextNode->next; + delete temp; + temp = NULL; + } + + } +} + +/****************************************************************************** + * Private Member Functions + *****************************************************************************/ + +/** queue + * @brief Private member to handle inserting value into the back of the queue + * + * @param val Value to be inserted + * @param tail The tail of the queue to insert into + * @return true If the value was inserted + * @return false If the value could not be inserted + */ +bool QueueList::enqueue(int val, Node *&tail) +{ + Node *newNode = new Node(val); + // If the queue is not empty, update next pointer to tail node + if (!isEmpty()) { + tail->next = newNode; + } + else head = newNode; + // Always set tail to our newNode + tail = newNode; + return true; +} + +/** dequeue + * @brief Removes a node from the front of the queue + * + * @param head The head of the queue to remove a node from + * @return int The value held at the node removed + */ +int QueueList::dequeue(Node *&head) +{ + // We already know the queue is not empty from public dequeue() + Node *temp = head; + // Store the data at the front of the queue before we delete the node + int data = head->data; + + // If there is only one item in the queue + if (temp == tail) { + tail = head = NULL; + delete temp; + return data; + } + + // Move the front of the queue to the next node + head = head->next; + // tail->next = NULL; + // Delete the previous head node + delete temp; + return data; +} + +/** print + * @brief Output the contents of a QueueList from the given Node to NULL + * + * @param start The Node to begin traversing output from + */ +void QueueList::print(Node *start) const +{ + Node *temp = start; + std::cout << "Queue Contents: "; + while (temp != NULL) { + std::cout << temp->data << " | "; + temp = temp->next; + } + std::cout << std::endl; +} + +/** makeEmpty + * @brief Private member to empty this QueueList object, deletes all Nodes in the queue + * Does not print any output. Avoids destructors printing to cout + * + * @param head The head of the queue to be deleted + * + */ +void QueueList::makeEmpty(Node *&head) +{ + Node *nextNode, *temp; + + if (head == NULL) return; + else { + nextNode = head->next; + delete head; + head = NULL; + tail = NULL; + while(nextNode != NULL) { + temp = nextNode; + nextNode = nextNode->next; + delete temp; + temp = NULL; + } + + } +} diff --git a/cpp/datastructs/queuelist/queuelist.h b/cpp/datastructs/queuelist/queuelist.h new file mode 100644 index 0000000..ecaa243 --- /dev/null +++ b/cpp/datastructs/queuelist/queuelist.h @@ -0,0 +1,44 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a queue implementation using linked lists ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## queuelist.h +*/ + +#ifndef QUEUELIST_H +#define QUEUELIST_H + +#include + +class QueueList { + public: + QueueList() : head(NULL), tail(NULL){}; + QueueList(const QueueList& rhs); + QueueList operator=(QueueList rhs); + ~QueueList(); + bool enqueue(int val); + int dequeue(); + int next() const; + bool isEmpty() const; + void print() const; + void makeEmpty(); + + private: + struct Node { + int data; + Node *next; + Node(): data(), next(NULL) {}; + Node(int val): data(val), next(NULL) {}; + }; + Node *head, *tail; + bool enqueue(int val, Node *&head); + int dequeue(Node *&tail); + void print(Node *start) const; + void makeEmpty(Node *&head); + +}; + +#endif