From 2c6400cc87b2c1ad0da784346d6ec7beec7593ce Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Thu, 23 Jul 2020 17:58:18 -0400 Subject: [PATCH] Initial commit for starting work on templates --- .../templates/binarysearchtree/CMakeLists.txt | 17 + .../templates/binarysearchtree/bst.cpp | 342 ++++++++++++++++++ .../templates/binarysearchtree/bst.h | 56 +++ .../templates/binarysearchtree/driver.cpp | 91 +++++ .../templates/doublelist/CMakeLists.txt | 18 + cpp/datastructs/templates/doublelist/Makefile | 23 ++ .../templates/doublelist/doublelist.cpp | 339 +++++++++++++++++ .../templates/doublelist/doublelist.h | 48 +++ .../templates/doublelist/driver.cpp | 106 ++++++ .../templates/queuelist/CMakeLists.txt | 18 + cpp/datastructs/templates/queuelist/Makefile | 23 ++ .../templates/queuelist/driver.cpp | 67 ++++ .../templates/queuelist/queuelist.cpp | 256 +++++++++++++ .../templates/queuelist/queuelist.h | 44 +++ .../templates/stacklist/CMakeLists.txt | 18 + cpp/datastructs/templates/stacklist/Makefile | 23 ++ .../templates/stacklist/driver.cpp | 67 ++++ .../templates/stacklist/stacklist.cpp | 238 ++++++++++++ .../templates/stacklist/stacklist.h | 44 +++ .../templates/vector/CMakeLists.txt | 18 + cpp/datastructs/templates/vector/Makefile | 23 ++ cpp/datastructs/templates/vector/driver.cpp | 111 ++++++ cpp/datastructs/templates/vector/vector.cpp | 319 ++++++++++++++++ cpp/datastructs/templates/vector/vector.h | 48 +++ 24 files changed, 2357 insertions(+) create mode 100644 cpp/datastructs/templates/binarysearchtree/CMakeLists.txt create mode 100644 cpp/datastructs/templates/binarysearchtree/bst.cpp create mode 100644 cpp/datastructs/templates/binarysearchtree/bst.h create mode 100644 cpp/datastructs/templates/binarysearchtree/driver.cpp create mode 100644 cpp/datastructs/templates/doublelist/CMakeLists.txt create mode 100644 cpp/datastructs/templates/doublelist/Makefile create mode 100644 cpp/datastructs/templates/doublelist/doublelist.cpp create mode 100644 cpp/datastructs/templates/doublelist/doublelist.h create mode 100644 cpp/datastructs/templates/doublelist/driver.cpp create mode 100644 cpp/datastructs/templates/queuelist/CMakeLists.txt create mode 100644 cpp/datastructs/templates/queuelist/Makefile create mode 100644 cpp/datastructs/templates/queuelist/driver.cpp create mode 100644 cpp/datastructs/templates/queuelist/queuelist.cpp create mode 100644 cpp/datastructs/templates/queuelist/queuelist.h create mode 100644 cpp/datastructs/templates/stacklist/CMakeLists.txt create mode 100644 cpp/datastructs/templates/stacklist/Makefile create mode 100644 cpp/datastructs/templates/stacklist/driver.cpp create mode 100644 cpp/datastructs/templates/stacklist/stacklist.cpp create mode 100644 cpp/datastructs/templates/stacklist/stacklist.h create mode 100644 cpp/datastructs/templates/vector/CMakeLists.txt create mode 100644 cpp/datastructs/templates/vector/Makefile create mode 100644 cpp/datastructs/templates/vector/driver.cpp create mode 100644 cpp/datastructs/templates/vector/vector.cpp create mode 100644 cpp/datastructs/templates/vector/vector.h diff --git a/cpp/datastructs/templates/binarysearchtree/CMakeLists.txt b/cpp/datastructs/templates/binarysearchtree/CMakeLists.txt new file mode 100644 index 0000000..afc9cbc --- /dev/null +++ b/cpp/datastructs/templates/binarysearchtree/CMakeLists.txt @@ -0,0 +1,17 @@ +############################################################################### +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: A basic CMakeLists configuration to test BST implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## CMakeLists.txt +# + +cmake_minimum_required(VERSION 3.2) +# Define the project name +project(BinarySearchTree) +# Define source files +set(SRC driver.cpp bst.cpp) +# Build an executable +add_executable(BSTDriver ${SRC}) diff --git a/cpp/datastructs/templates/binarysearchtree/bst.cpp b/cpp/datastructs/templates/binarysearchtree/bst.cpp new file mode 100644 index 0000000..4c8a7db --- /dev/null +++ b/cpp/datastructs/templates/binarysearchtree/bst.cpp @@ -0,0 +1,342 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a binary search tree implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## bst.cpp +*/ + +#include "bst.h" + + +/******************************************************************************** +* Constructors, Destructors, Operators +*********************************************************************************/ + +/** Copy Assignment Operator + * @brief Empty the calling object's root BinaryNode, and copy the rhs data + * + * @param rhs The BST to copy, beginning from its root BinaryNode + * @return const BinarySearchTree& The copied BinarySearchTree object + */ +const BinarySearchTree& BinarySearchTree::operator=(const BinarySearchTree& rhs) +{ + // If the objects are already equal, do nothing + if (this == &rhs) return *this; + + // Empty this->root + makeEmpty(); + // Copy rhs to this->root + root = clone(rhs.root); + return *this; +} + +/** Default Destructor + * @brief Destroy the Binary Search Tree:: Binary Search Tree object + */ +BinarySearchTree::~BinarySearchTree() +{ + makeEmpty(root); +} + + +/******************************************************************************** +* Public Member Functions +*********************************************************************************/ + +/** findMin + * @brief Find and return the minimum value of the calling BST object + * Calls to the private member findMin(BinaryNode* t) + * + * @return const int& The element of the BinaryNode that holds the lowest value in our tree + */ +const int & BinarySearchTree::findMin() const +{ + return findMin(root)->element; +} + +/** findMax + * @brief Find and return the maximum value of the calling BST object + * Calls to the private member findMax(BinaryNode* t) + * + * @return const int& The element of the BinaryNode that holds the highest value in our tree + */ +const int & BinarySearchTree::findMax() const +{ + return findMax(root)->element; +} + +/** contains + * @brief Determine whether or not a value exists within the calling BST object + * Calls to the private member contains(const int &x, BinaryNode* t) + * + * @param x The value to search for within our tree + * @return true If the value is found within any BinaryNode->element + * @return false If the value is not found within any BinaryNode->element + */ +bool BinarySearchTree::contains(const int &x) const +{ + return contains(x, root); +} + +/** isEmpty + * @brief Determine whether or not the calling BST object is empty + * + * @return true If this->root node points to an empty tree (NULL) + * @return false If this->root node points to a constructed BinaryNode + */ +bool BinarySearchTree::isEmpty() const +{ + return root == NULL; +} + +/** insert + * @brief Inserts a new value into the calling BST object + * Calls to the private member insert(const int &x, BinaryNode* t) + * + * @param x The new value to insert into our BinarySearchTree + */ +void BinarySearchTree::insert(const int & x) +{ + insert(x, root); +} + +/** remove + * @brief Remove a value from the calling BST object + * Calls to the private member remove(const int &x, BinaryNode* t) + * + * @param x The value to remove from our BST + */ +void BinarySearchTree::remove(const int &x) +{ + remove(x, root); +} + +/** makeEmpty + * @brief Delete the root BinaryNode and all of its children from the calling BST object + * Calls to the private member makeEmpty(BinaryNode* t) + */ +void BinarySearchTree::makeEmpty() +{ + makeEmpty(root); +} + +/** printInOrder + * @brief Output the element of each BinaryNode between their left and right subtrees + * Calls to the private member printInOrder(BinaryNode* t) + */ +void BinarySearchTree::printInOrder() const +{ + printInOrder(root); + std::cout << std::endl; +} + +/** printPostOrder + * @brief Output the element of each BinaryNode after their left and right subtrees + * Calls to the private member printPostOrder(BinaryNode* t) + */ +void BinarySearchTree::printPostOrder() const +{ + printPostOrder(root); + std::cout << std::endl; +} + +/** printPreOrder + * @brief Output the element of each BinaryNode before their left and right subtrees + * Calls to the private member printPreOrder(BinaryNode* t) + */ +void BinarySearchTree::printPreOrder() const +{ + printPreOrder(root); + std::cout << std::endl; +} + + +/******************************************************************************** +* Private Member Functions +*********************************************************************************/ + +/** clone + * @brief Clone a BST node and all its children + * + * @param t The node to begin cloning from + * @return BinarySearchTree::BinaryNode* The root node of the copied tree + */ +BinarySearchTree::BinaryNode * BinarySearchTree::clone(BinaryNode *t) const +{ + // If there is nothing to copy + if (t == NULL) return NULL; + + // Construct all child nodes through recursion, return root node + return new BinaryNode(t->element, clone(t->left), clone(t->right)); +} + +/** insert + * @brief Insert a value into the BST of the given BinaryNode + * + * @param x The value to be inserted + * @param t The BinaryNode to begin insertion + */ +void BinarySearchTree::insert(const int &x, BinarySearchTree::BinaryNode *&t) const +{ + if (t == NULL) + t = new BinaryNode(x, NULL, NULL); + else if (x < t->element) + insert (x, t->left); + else if (x > t->element) + insert (x, t->right); + else + return; +} + +/** remove + * @brief Removes a value from the BST of the given BinaryNode + * + * @param x The value to be removed + * @param t The BinaryNode to begin search and removal from + */ +void BinarySearchTree::remove(const int &x, BinarySearchTree::BinaryNode *&t) const +{ + if (t == NULL) + return; + + if (x < t->element) + remove(x, t->left); + else if (x > t->element) + remove(x, t->right); + else if (t->left != NULL && t->right != NULL) { + // If we found the node and there are two branches + t->element = findMin(t->right)->element; + std::cout << "Removing [" << t->element << "]...\n"; + remove(t->element, t->right); + } + else { + // If we found the value and there is only one branch + BinaryNode *oldNode = t; + t = (t->left != NULL) ? t->left : t->right; + std::cout << "Removing [" << oldNode->element << "]...\n"; + delete oldNode; + } +} + +/** findMin + * @brief Find the minimum value within the BST of the given BinaryNode + * + * @param t The root BinaryNode to begin checking values + * @return BinarySearchTree::BinaryNode* The BinaryNode which contains the smallest value (returns NULL if BST is empty) + */ +BinarySearchTree::BinaryNode * BinarySearchTree::findMin(BinarySearchTree::BinaryNode *t) const +{ + while (t != NULL) + t = t->left; + + // If our tree is empty + if (t == NULL) + return NULL; + + // If current node has no smaller children, it is min + if (t->left == NULL) + return t; + + // Move down the left side of our tree and check again + return findMin(t->left); +} + +/** findMax + * @brief Find the maximum value within the BST of the given BinaryNode + * + * @param t The root BinaryNode to begin checking values + * @return BinarySearchTree::BinaryNode* The BinaryNode which contains the largest value (returns NULL if BST is empty) + */ +BinarySearchTree::BinaryNode * BinarySearchTree::findMax(BinarySearchTree::BinaryNode *t) const +{ + // If our tree is empty + if (t == NULL) + return NULL; + + // If current node has no larger children, it is max + if (t->right == NULL) + return t; + + // Move down the right side of our tree and check again + return findMax(t->right); +} + +/** contains + * @brief Determines if the value exists within the given BinaryNode and its children + * + * @param x The value to search for within the BST + * @param t The root BinaryNode to begin the search + * @return true If the value is found within the root node or any of its children + * @return false If the value is not found within the root node or any of its children + */ +bool BinarySearchTree::contains(const int &x, BinarySearchTree::BinaryNode *t) const +{ + if (t == NULL) // If tree is empty + return false; + else if (x < t->element) // If x is smaller than our current value + return contains(x, t->left);// Check left node + else if (x > t->element) // If x is larger than our current value + return contains(x, t->right); // Check right node + else + return true; +} + +/** makeEmpty + * @brief Recursively delete the given root BinaryNode and all of its children + * + * @param t The root BinaryNode to delete, along with all child nodes + */ +void BinarySearchTree::makeEmpty(BinarySearchTree::BinaryNode * & t) +{ + if (t != NULL) { + makeEmpty(t->left); + makeEmpty(t->right); + delete t; + } + t = NULL; +} + +/** printInOrder + * @brief Output the element of the root nodes between printing their left and right subtrees + * + * @param t The root BinaryNode to begin the 'In Order' output + */ +void BinarySearchTree::printInOrder(BinaryNode *t) const +{ + if(t != NULL) { + printInOrder(t->left); + std::cout << t->element << " "; + printInOrder(t->right); + } +} + +/** printPostOrder + * @brief Output the value of the root nodes only after their subtrees + * + * @param t The root BinaryNode to begin the 'Post Order' output + */ +void BinarySearchTree::printPostOrder(BinaryNode *t) const +{ + if (t != NULL) { + printPostOrder(t->left); + printPostOrder(t->right); + std::cout << t->element << " "; + } +} + +/** printPreOrder + * @brief Output the value of the noot nodes before their subtrees + * + * @param t The root BinaryNode to begin the 'Pre Order' output + */ +void BinarySearchTree::printPreOrder(BinaryNode *t) const +{ + if (t != NULL) { + std::cout << t->element << " "; + printPreOrder(t->left); + printPreOrder(t->right); + } +} diff --git a/cpp/datastructs/templates/binarysearchtree/bst.h b/cpp/datastructs/templates/binarysearchtree/bst.h new file mode 100644 index 0000000..aa71e70 --- /dev/null +++ b/cpp/datastructs/templates/binarysearchtree/bst.h @@ -0,0 +1,56 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a binary search tree implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## bst.h +*/ + +#ifndef BST_H +#define BST_H + +#include + +// TODO: Add balance() method to balance overweight branches +class BinarySearchTree { + + public: + BinarySearchTree() : root(NULL) {}; + BinarySearchTree(const BinarySearchTree &rhs) : root(rhs.clone(rhs.root)) {}; + const BinarySearchTree& operator=(const BinarySearchTree& rhs); + ~BinarySearchTree(); + const int & findMin() const; + const int & findMax() const; + bool contains(const int &x) const; + bool isEmpty() const; + void insert(const int &x); + void remove(const int &x); + void makeEmpty(); + void printInOrder() const; + void printPostOrder() const; + void printPreOrder() const; + + private: + struct BinaryNode{ + int element; + BinaryNode *left; + BinaryNode *right; + BinaryNode(const int &el, BinaryNode *lt, BinaryNode *rt) + :element(el), left(lt), right(rt) {}; + }; + BinaryNode *root; + BinaryNode * clone(BinaryNode *t) const; + void insert(const int &x, BinaryNode *&t) const; + void remove(const int &x, BinaryNode *&t) const; + BinaryNode * findMin(BinaryNode *t) const; + BinaryNode * findMax(BinaryNode *t) const; + bool contains(const int &x, BinaryNode *t) const; + void makeEmpty(BinaryNode * & t); + void printInOrder(BinaryNode *t) const; + void printPostOrder(BinaryNode *t) const; + void printPreOrder(BinaryNode *t) const; +}; + +#endif //BST_H diff --git a/cpp/datastructs/templates/binarysearchtree/driver.cpp b/cpp/datastructs/templates/binarysearchtree/driver.cpp new file mode 100644 index 0000000..f1c85f0 --- /dev/null +++ b/cpp/datastructs/templates/binarysearchtree/driver.cpp @@ -0,0 +1,91 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: A driver program to test a binary search tree implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## driver.cpp +*/ + +#include "bst.h" +#include + +enum OPS { + EXIT, INSERT, REMOVE, CONTAINS, INFIX, PREFIX, POSTFIX, EMPTY, MIN, MAX +}; + +int main() +{ + std::cout << "Driver: \n"; + BinarySearchTree testList; + bool exit = false; + int choice = -1; + int val; + + while (!exit) + { + std::cout << "##### Binary Search Tree Menu #####\n\t0. Exit" + "\n\t1. Insert\n\t2. Remove\n\t3. Contains\n\t4. Infix\n\t5. Prefix" + << "\n\t6. Postfix\n\t7. Empty\n\t8. Min\n\t9. Max\n"; + std::cin >> choice; + std::cin.clear(); + switch (choice) { + case EXIT: + exit = true; + break; + + case INSERT: + std::cout << "Enter a value to insert to our tree: "; + std::cin >> val; + std::cin.clear(); + testList.insert(val); + break; + + case REMOVE: + std::cout << "Enter a value to remove from our tree: "; + std::cin >> val; + std::cin.clear(); + testList.remove(val); + break; + + case CONTAINS: + std::cout << "Enter a value to search for within our tree: "; + std::cin >> val; + std::cin.clear(); + if (testList.contains(val)) + std::cout << val << " exists within our tree\n"; + else std::cout << val << " does not exist within our tree\n"; + break; + + case INFIX: + testList.printInOrder(); + break; + + case PREFIX: + testList.printPreOrder(); + break; + + case POSTFIX: + testList.printPostOrder(); + break; + + case EMPTY: + testList.makeEmpty(); + break; + + case MIN: + std::cout << "Min value within our tree: " << testList.findMin(); + break; + + case MAX: + std::cout << "Max value within our tree: " << testList.findMax(); + break; + + default: + std::cout << "Invalid entry...\n"; + break; + } + } +} + diff --git a/cpp/datastructs/templates/doublelist/CMakeLists.txt b/cpp/datastructs/templates/doublelist/CMakeLists.txt new file mode 100644 index 0000000..fbf5123 --- /dev/null +++ b/cpp/datastructs/templates/doublelist/CMakeLists.txt @@ -0,0 +1,18 @@ +############################################################################### +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a doubly linked list implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## CMakeLists.txt +# + +CMAKE_MINIMUM_REQUIRED(VERSION 3.2) + +# Define the project name +project(DoubleList) +# Define source files +set(SRC driver.cpp doublelist.cpp) +# Build an executable +add_executable(DoubleListDriver ${SRC}) diff --git a/cpp/datastructs/templates/doublelist/Makefile b/cpp/datastructs/templates/doublelist/Makefile new file mode 100644 index 0000000..ac03db3 --- /dev/null +++ b/cpp/datastructs/templates/doublelist/Makefile @@ -0,0 +1,23 @@ +CXX=g++ +CXXFLAGS=-g -Wall + +############################################################################### +# Driver +############################################################################### + +driver: driver.cpp doublelist.o + ${CXX} ${CXXFLAGS} driver.cpp doublelist.o -o driver + +############################################################################### +# DoubleList +############################################################################### + +doublelist.o: doublelist.cpp doublelist.h + ${CXX} ${CXXFLAGS} -c doublelist.cpp -o doublelist.o + +############################################################################### +# Clean +############################################################################### + +clean: + rm -f *.o driver diff --git a/cpp/datastructs/templates/doublelist/doublelist.cpp b/cpp/datastructs/templates/doublelist/doublelist.cpp new file mode 100644 index 0000000..e106dac --- /dev/null +++ b/cpp/datastructs/templates/doublelist/doublelist.cpp @@ -0,0 +1,339 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a doubly linked list ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## doublelist.cpp +*/ + +#include "doublelist.h" + + +/****************************************************************************** + * Constructors, Destructors, Operators + *****************************************************************************/ + +/** copy constructor + * @brief Construct a new DoubleList::DoubleList object from an existing one + * + * @param rhs DoubleList object + */ +DoubleList::DoubleList(const DoubleList& rhs) +{ + Node *cp = rhs.head; + Node *tempHead; + if (cp == NULL) head = NULL; + else { + head = new Node(cp->data); + tempHead = head; + while (cp->next != NULL) { + cp = cp->next; + head->next = new Node(cp->data); + head = head->next; + } + head = tempHead; + } +} + +/** operator= + * @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 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 + */ +DoubleList DoubleList::operator=(DoubleList rhs) +{ + if (this == &rhs) return *this; + std::swap(head, rhs.head); + return *this; +} + +/** destructor + * @brief Destroy the DoubleList::DoubleList object + */ +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 DoubleList::insert(int val) +{ + bool inserted = insert(val, head); + 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; +} + +/** insert at + * @brief Inserts a value in the place of a given key + * Key Node found is moved to the newNode->next position + * + * @param key The value to search for to determine insert location + * @param val The value to be inserted into the list + */ +bool DoubleList::insert(int val, int key) +{ + bool inserted = insert(val, key, head); + 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; +} + +/** 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 DoubleList::remove(int val) +{ + bool removed = remove(val, head); + 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; +} + +/** 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 DoubleList::replace(int val, int key) +{ + bool replaced = replace(val, key, head); + 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 DoubleList object, deleting all associated Nodes + */ +void DoubleList::makeEmpty() +{ + Node *nextNode, *temp; + + if (head == NULL) return; + nextNode = head->next; + delete head; + head = NULL; + while(nextNode != NULL) { + temp = nextNode; + nextNode = nextNode->next; + delete temp; + temp = NULL; + } +} + +/** isEmpty + * @brief Determine if the DoubleList is empty + * + * @return true If the DoubleList::head is NULL + * @return false If the DoubleList::head contains data + */ +bool DoubleList::isEmpty() const +{ + return head == NULL; +} + +/** peek + * @brief returns the value at the DoubleList::head + * + * @return int The value held at the Node pointed to by DoubleList::head + */ +int DoubleList::peek() const +{ + 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"; + // If the list has data we return it, otherwise we return the smallest possible int (error) + return (!isEmpty()) ? head->data : INT32_MIN; +} + +/** print + * @brief Output the data held by the DoubleList object + * Calls to the private print() + */ +void DoubleList::print() const +{ + if(!isEmpty()) print(head); + else std::cout << "Nothing to print, our list is empty...\n"; +} + +/** find + * @brief Calls to the private member find() and handles return cases + * + * @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 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 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; + // Create a prev ptr for the head node + head->prev = newNode; + } + // Always set head to our 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 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 = 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; + // 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 DoubleList::remove(int val, Node *&head) +{ + if (head == NULL) return false; + else if (head->data == val) { + head = head->next; + return true; + } + + 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 DoubleList::replace(int val, int key, Node *&head) +{ + Node *replacee = find(key, head); + if (replacee == NULL) return false; + replacee->data = val; + return true; +} + +/** find + * @brief Find and return a Node which contains the given value + * + * @param val The value to search for within our DoubleList + * @return DoubleList::Node* A pointer to the Node containing the search value + */ +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 + if (start == NULL || start->data == val) return start; + + Node *foundNode = start; + while (foundNode->next != NULL) { + foundNode = foundNode->next; + if (foundNode->data == val) return foundNode; + } + // If we have not yet returned a foundNode, the key is not in our list + return NULL; +} + +/** print + * @brief Output the contents of a DoubleList from the given Node to NULL + * + * @param start The Node to begin traversing output from + */ +void DoubleList::print(Node *start) const +{ + Node *temp = start; + std::cout << "List Contents: "; + while (temp != NULL) { + std::cout << temp->data << " | "; + temp = temp->next; + } + std::cout << std::endl; +} diff --git a/cpp/datastructs/templates/doublelist/doublelist.h b/cpp/datastructs/templates/doublelist/doublelist.h new file mode 100644 index 0000000..b31798a --- /dev/null +++ b/cpp/datastructs/templates/doublelist/doublelist.h @@ -0,0 +1,48 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a doubly linked list ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## doublelist.h +*/ + +#ifndef DOUBLELIST_H +#define DOUBLELIST_H + +#include + +class DoubleList { + public: + 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; + int peek() const; + void print() const; + bool find(int val) const; + + private: + struct Node { + int data; + 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); + bool insert(int val, int key, Node *&head); + bool remove(int val, Node *&head); + bool replace(int val, int key, Node *&head); + Node* find(int val, Node *start) const; + void print(Node *start) const; +}; + +#endif diff --git a/cpp/datastructs/templates/doublelist/driver.cpp b/cpp/datastructs/templates/doublelist/driver.cpp new file mode 100644 index 0000000..d1dfac8 --- /dev/null +++ b/cpp/datastructs/templates/doublelist/driver.cpp @@ -0,0 +1,106 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: A driver program to test a doubly linked list ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## driver.cpp +*/ + +#include "doublelist.h" +#include + +enum OPS { + EXIT, INSERT, INSERTAT, EMPTY, PEEK, PRINT, FIND, REMOVE, REPLACE +}; + +int main() +{ + std::cout << "Driver: \n"; + + DoubleList testList; + bool exit = false; + int choice = -1; + int val, key; + + while (!exit) + { + std::cout << "##### Doubly Linked List Menu #####\n\t0. Exit" + << "\n\t1. Insert\n\t2. Insert at\n\t3. Empty list\n\t4. Peek top of list" + << "\n\t5. Print list\n\t6. Find\n\t7. Remove\n\t8. Replace\n"; + std::cin >> choice; + std::cin.clear(); + switch (choice) { + case EXIT: + exit = true; + break; + + case INSERT: + std::cout << "Enter a value to add to our list: "; + std::cin >> val; + std::cin.clear(); + testList.insert(val); + break; + + case INSERTAT: + std::cout << "Enter a new value to add to our list: "; + std::cin >> val; + std::cin.clear(); + std::cout << "Enter an existing value to insert at within our list: "; + std::cin >> key; + std::cin.clear(); + if (testList.insert(val, key)) { + std::cout << "List after inserting [" + << val << "] at [" << key << "]: \n"; + testList.print(); + } + break; + + case EMPTY: + testList.makeEmpty(); + break; + + case PEEK: + testList.peek(); + break; + + case PRINT: + testList.print(); + break; + + case FIND: + std::cout << "Enter an existing value to search for within our list: "; + std::cin >> val; + std::cin.clear(); + testList.find(val); + break; + + case REMOVE: + std::cout << "Enter an existing value to remove from our list: "; + std::cin >> val; + std::cin.clear(); + testList.remove(val); + break; + + case REPLACE: + std::cout << "Enter a new value to add to our list: "; + std::cin >> val; + std::cin.clear(); + std::cout << "Enter an existing value to replace within our list: "; + std::cin >> key; + std::cin.clear(); + if (testList.replace(val, key)) { + std::cout << "List after replacing [" + << key << "] by [" << val << "]: \n"; + testList.print(); + } + break; + + default: + std::cout << "Invalid entry...\n"; + break; + } + } +} + diff --git a/cpp/datastructs/templates/queuelist/CMakeLists.txt b/cpp/datastructs/templates/queuelist/CMakeLists.txt new file mode 100644 index 0000000..d88a2ab --- /dev/null +++ b/cpp/datastructs/templates/queuelist/CMakeLists.txt @@ -0,0 +1,18 @@ +############################################################################### +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a queue implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## CMakeLists.txt +# + +cmake_minimum_required(VERSION 3.2) + +# Define the project name +project(Queue) +# Define source files +set(SRC driver.cpp queuelist.cpp) +# Build an executable +add_executable(QueueDriver ${SRC}) diff --git a/cpp/datastructs/templates/queuelist/Makefile b/cpp/datastructs/templates/queuelist/Makefile new file mode 100644 index 0000000..0197dd3 --- /dev/null +++ b/cpp/datastructs/templates/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/templates/queuelist/driver.cpp b/cpp/datastructs/templates/queuelist/driver.cpp new file mode 100644 index 0000000..034bf89 --- /dev/null +++ b/cpp/datastructs/templates/queuelist/driver.cpp @@ -0,0 +1,67 @@ +/*############################################################################# +## 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/templates/queuelist/queuelist.cpp b/cpp/datastructs/templates/queuelist/queuelist.cpp new file mode 100644 index 0000000..35da3dd --- /dev/null +++ b/cpp/datastructs/templates/queuelist/queuelist.cpp @@ -0,0 +1,256 @@ +/*############################################################################# +## 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 val 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/templates/queuelist/queuelist.h b/cpp/datastructs/templates/queuelist/queuelist.h new file mode 100644 index 0000000..ecaa243 --- /dev/null +++ b/cpp/datastructs/templates/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 diff --git a/cpp/datastructs/templates/stacklist/CMakeLists.txt b/cpp/datastructs/templates/stacklist/CMakeLists.txt new file mode 100644 index 0000000..bbb5d55 --- /dev/null +++ b/cpp/datastructs/templates/stacklist/CMakeLists.txt @@ -0,0 +1,18 @@ +############################################################################### +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a stack implementation using linked lists ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## CMakeLists.txt +# + +cmake_minimum_required(VERSION 3.2) + +# Define the project name +project(Stack) +# Define source files +set(SRC driver.cpp stacklist.cpp) +# Build an executable +add_executable(StackDriver ${SRC}) diff --git a/cpp/datastructs/templates/stacklist/Makefile b/cpp/datastructs/templates/stacklist/Makefile new file mode 100644 index 0000000..a0e74d6 --- /dev/null +++ b/cpp/datastructs/templates/stacklist/Makefile @@ -0,0 +1,23 @@ +CXX=g++ +CXXFLAGS=-g -Wall + +############################################################################### +# Driver +############################################################################### + +driver: driver.cpp stacklist.o + ${CXX} ${CXXFLAGS} driver.cpp stacklist.o -o driver + +############################################################################### +# StackList +############################################################################### + +stacklist.o: stacklist.cpp stacklist.h + ${CXX} ${CXXFLAGS} -c stacklist.cpp -o stacklist.o + +############################################################################### +# Clean +############################################################################### + +clean: + rm -f *.o driver diff --git a/cpp/datastructs/templates/stacklist/driver.cpp b/cpp/datastructs/templates/stacklist/driver.cpp new file mode 100644 index 0000000..800d2b0 --- /dev/null +++ b/cpp/datastructs/templates/stacklist/driver.cpp @@ -0,0 +1,67 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: A driver program to test a stack implementation using linked lists ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## driver.cpp +*/ + +#include "stacklist.h" +#include + +enum OPS { + EXIT, PUSH, POP, TOP, PRINT, EMPTY +}; + +int main() +{ + std::cout << "Driver: \n"; + + StackList testList; + bool exit = false; + int choice = -1; + int val; + + while (!exit) + { + std::cout << "##### Stacks Using Linked Lists Menu #####\n\t0. Exit" + << "\n\t1. Push\n\t2. Pop\n\t3. Top\n\t4. Print" + << "\n\t5. Empty\n\t"; + std::cin >> choice; + std::cin.clear(); + switch (choice) { + case EXIT: + exit = true; + break; + + case PUSH: + std::cout << "Enter a value to push to our stack: "; + std::cin >> val; + std::cin.clear(); + testList.push(val); + break; + + case POP: + testList.pop(); + break; + + case TOP: + testList.top(); + break; + + case PRINT: + testList.print(); + break; + + case EMPTY: + testList.makeEmpty(); + break; + + default: + std::cout << "Invalid entry...\n"; + break; + } + } +} diff --git a/cpp/datastructs/templates/stacklist/stacklist.cpp b/cpp/datastructs/templates/stacklist/stacklist.cpp new file mode 100644 index 0000000..87ee96a --- /dev/null +++ b/cpp/datastructs/templates/stacklist/stacklist.cpp @@ -0,0 +1,238 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a stack implementation using linked lists ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## stacklist.cpp +*/ + +#include "stacklist.h" + + +/****************************************************************************** + * Constructors, Destructors, Operators + *****************************************************************************/ + +/** copy constructor + * @brief Construct a new StackList::StackList object from an existing one + * Creates a new deep copy of a given StackList + * + * @param rhs StackList object + */ +StackList::StackList(const StackList& rhs) +{ + Node *cp = rhs.head; + Node *tempHead; + // If we are copying from an empty stack, create a new StackList with a NULL head + if (cp == NULL) head = NULL; + else { + // If the stack has data, initialize a new stack 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; + } + head = tempHead; + } +} + +/** operator= + * @brief Assign two StackList objects equal using copy constr and class destr + * Pass the rhs by value to create local copy, swap its contents + * Destructor called on previous StackList data at the end of this scope + * + * @param rhs StackList object passed by value + * @return StackList A deep copy of the rhs StackList object + */ +StackList StackList::operator=(StackList 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 StackList::StackList object + */ +StackList::~StackList() +{ + makeEmpty(head); +} + + +/****************************************************************************** + * Public Member Functions + *****************************************************************************/ + +/** push + * @brief Push a value to the head of our linked list + * + * @param val The value to be inserted + */ +bool StackList::push(int val) +{ + bool inserted = push(val, head); + if (inserted) + std::cout << "[" << val << "] was inserted into the stack\n"; + else std::cout << "[" << val << "] could not be inserted into the stack\n"; + return inserted; +} + +/** pop + * @brief returns the value at the StackList::head + * + * @return int The value held at the Node pointed to by StackList::head + */ +int StackList::pop() +{ + if (!isEmpty()) + std::cout << "[" << pop(head) << "] has been popped from our stack\n"; + else std::cout << "Nothing to pop, our stack is empty...\n"; + // If the stack has data we return it, otherwise we return the smallest possible int (error) + return (!isEmpty()) ? head->data : INT32_MIN; +} + +/** top + * @brief returns the value at the StackList::head + * + * @return int The value held at the Node pointed to by StackList::head + */ +int StackList::top() const +{ + if (!isEmpty()) + std::cout << "[" << head->data << "] is at the top of our stack\n"; + else std::cout << "Our stack is empty...\n"; + // If the stack has data we return it, otherwise we return the smallest possible int (error) + return (!isEmpty()) ? head->data : INT32_MIN; +} + +/** makeEmpty + * @brief Empty this StackList object, deleting all associated Nodes + */ +void StackList::makeEmpty() +{ + Node *nextNode, *temp; + + if (head == NULL) std::cout << "Our stack is empty...\n"; + else { + nextNode = head->next; + delete head; + head = NULL; + while(nextNode != NULL) { + temp = nextNode; + nextNode = nextNode->next; + delete temp; + temp = NULL; + } + + } +} + +/** isEmpty + * @brief Determine if the StackList is empty + * + * @return true If the StackList::head is NULL + * @return false If the StackList::head contains data + */ +bool StackList::isEmpty() const +{ + return head == NULL; +} + +/** print + * @brief Output the data held by the StackList object + * Calls to the private print() + */ +void StackList::print() const +{ + if(!isEmpty()) print(head); + else std::cout << "Nothing to print, our stack is empty...\n"; +} + + +/****************************************************************************** + * Private Member Functions + *****************************************************************************/ + +/** push + * @brief Private member to handle inserting value into the stack + * + * @param val Value to be inserted + * @param head The head of the stack to push the value into + * @return true If the value was inserted + * @return false If the value could not be inserted + */ +bool StackList::push(int val, Node *&head) +{ + Node *newNode = new Node(val); + // If the stack is not empty, update next pointer to head node + if (!isEmpty()) newNode->next = head; + // Always set head to our newNode + head = newNode; + return true; +} + +/** pop + * @brief Private member to handle removing the head node from the stack + * + * @param head The head node of the stack + * @return The last known value held at the head node before removal + */ +int StackList::pop(Node *&head) +{ + // We already know the stack is not empty from public pop() + Node *temp = head; + int data = temp->data; + head = head->next; + delete temp; + return data; +} + +/** print + * @brief Output the contents of a StackList from the given Node to NULL + * + * @param start The Node to begin traversing output from + */ +void StackList::print(Node *start) const +{ + Node *temp = start; + std::cout << "Stack Contents: "; + while (temp != NULL) { + std::cout << temp->data << " | "; + temp = temp->next; + } + std::cout << std::endl; +} + +/** makeEmpty + * @brief Private member to empty this StackList object, deleting all associated Nodes + * Does not print any output. Avoids destructors printing to cout + * + * @param head The head of the stack to be deleted + * + */ +void StackList::makeEmpty(Node *&head) +{ + Node *nextNode, *temp; + + if (head == NULL) return; + else { + nextNode = head->next; + delete head; + head = NULL; + while(nextNode != NULL) { + temp = nextNode; + nextNode = nextNode->next; + delete temp; + temp = NULL; + } + + } +} diff --git a/cpp/datastructs/templates/stacklist/stacklist.h b/cpp/datastructs/templates/stacklist/stacklist.h new file mode 100644 index 0000000..e590811 --- /dev/null +++ b/cpp/datastructs/templates/stacklist/stacklist.h @@ -0,0 +1,44 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a stack implementation using linked lists ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## stacklist.h +*/ + +#ifndef STACKLIST_H +#define STACKLIST_H + +#include + +class StackList { + public: + StackList() : head(NULL) {}; + StackList(const StackList& rhs); + StackList operator=(StackList rhs); + ~StackList(); + bool push(int val); + int pop(); + int top() 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; + bool push(int val, Node *&head); + int pop(Node *&head); + void print(Node *start) const; + void makeEmpty(Node *&head); + +}; + +#endif diff --git a/cpp/datastructs/templates/vector/CMakeLists.txt b/cpp/datastructs/templates/vector/CMakeLists.txt new file mode 100644 index 0000000..bb20e44 --- /dev/null +++ b/cpp/datastructs/templates/vector/CMakeLists.txt @@ -0,0 +1,18 @@ +############################################################################### +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: A basic CMakeLists configuration to test Vector implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## vector.cpp +# + +cmake_minimum_required(VERSION 3.2) + +# Define the project name +project(VectorDriver) +# Define source files +set(SRC driver.cpp vector.cpp) +# Build an executable +add_executable(VectorDriver ${SRC}) diff --git a/cpp/datastructs/templates/vector/Makefile b/cpp/datastructs/templates/vector/Makefile new file mode 100644 index 0000000..ddd71fd --- /dev/null +++ b/cpp/datastructs/templates/vector/Makefile @@ -0,0 +1,23 @@ +CXX=g++ +CXXFLAGS=-g -Wall + +############################################################################### +# Driver +############################################################################### + +driver: driver.cpp vector.o + ${CXX} ${CXXFLAGS} driver.cpp vector.o -o driver + +############################################################################### +# Vector +############################################################################### + +vector.o: vector.cpp vector.h + ${CXX} ${CXXFLAGS} -c vector.cpp -o vector.o + +############################################################################### +# Clean +############################################################################### + +clean: + rm -f *.o driver diff --git a/cpp/datastructs/templates/vector/driver.cpp b/cpp/datastructs/templates/vector/driver.cpp new file mode 100644 index 0000000..332ae84 --- /dev/null +++ b/cpp/datastructs/templates/vector/driver.cpp @@ -0,0 +1,111 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: A driver program to test a vector implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## driver.cpp +*/ + +#include "vector.h" +#include + +enum OPS { + EXIT, PUSH, POP, TOP, PRINT, EMPTY, CONSTRUCT, COPY, ASSIGN, DESTRUCT +}; + +int main() +{ + std::cout << "Driver: \n"; + Vector testlist; + bool exit = false; + int choice = -1; + T val; + + while (!exit) + { + std::cout << "##### vectors menu #####\n\t0. exit" + << "\n\t1. push\n\t2. pop\n\t3. peek\n\t4. print\n\t5. empty" + << "\n\t6. construct\n\t7. copy\n\t8. assign\n\t9. destruct\n\t"; + std::cin >> choice; + std::cin.clear(); + switch (choice) { + case EXIT: + exit = true; + break; + + case PUSH: + std::cout << "enter a value to push to our vector: "; + std::cin >> val; + std::cin.clear(); + testlist.push(val); + break; + + case POP: + testList.pop(); + break; + + case TOP: + testList.peek(); + break; + + case PRINT: + testList.print(); + break; + + case EMPTY: + testList.makeEmpty(); + break; + + // If this test is successful, we build a default empty Vector object + // Will 'have nothing to print' because a default Vector contains no values + case CONSTRUCT: + { + Vector constrTest; + std::cout << "##### Constructor Test #####\n"; + constrTest.print(); + std::cout << "Deleting local constrTest Vector...\n"; + break; + } + + // If this is successful, we build a new Vector based on the existing Vector + // The new Vector output here should be identical to this session's Vector + case COPY: + { + Vector copyTest(testList); + std::cout << "##### Copy Constructor Test #####\n"; + copyTest.print(); + std::cout << "Deleting local copyTest Vector...\n"; + break; + } + + // Test assignment operator, setting new Vector object equal to the existing + case ASSIGN: + { + Vector assignTest; + assignTest = testList; + std::cout << "##### Assignment Test #####\n"; + assignTest.print(); + std::cout << "Deleting local assignTest Vector...\n"; + break; + } + + case DESTRUCT: + { + Vector destrTest(testList); + std::cout << "Current destrTest Vector contents...\n"; + destrTest.print(); + std::cout << "Deleting local destrTest Vector...\n"; + destrTest.~Vector(); // Implicitly called at the end of this scope {} + destrTest.print(); + break; + } + + default: + std::cout << "Invalid entry...\n"; + break; + } + } +} + diff --git a/cpp/datastructs/templates/vector/vector.cpp b/cpp/datastructs/templates/vector/vector.cpp new file mode 100644 index 0000000..f2fa8ad --- /dev/null +++ b/cpp/datastructs/templates/vector/vector.cpp @@ -0,0 +1,319 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a vector implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## vector.cpp +*/ + +#include "vector.h" + + +/****************************************************************************** + * Constructors, Destructors, Operators + *****************************************************************************/ + +/** copy constructor + * @brief Construct a new Vector::Vector object from an existing one + * Creates a new deep copy of a given Vector + * + * @param rhs Vector object + */ +template +Vector::Vector(const Vector& rhs) +{ + if (rhs.getIndex() >= 0) { + curIndex = rhs.getIndex(); + // Avoid copying over unused indices from parent Vector + maxSize = rhs.getSize(); + data = new T[curIndex]; + for (int i = 0; i <= rhs.getSize(); i++) { + data[i] = rhs.getValue(i); + } + } + else { + curIndex = -1; + maxSize = 0; + data = NULL; + } +} + +/** operator= + * @brief Assign two Vector objects equal using copy constr and class destr + * Pass the rhs by value to create local copy, swap its contents + * Destructor called on previous Vector data at the end of this scope + * + * @param rhs Vector object passed by value, creating a local variable + * @return Vector A deep copy of the rhs Vector object + */ +template +Vector Vector::operator=(Vector rhs) +{ + if (this == &rhs) return *this; + // Swap the pointers, moving the previous head data to the local variable rhs + std::swap(data, rhs.data); + curIndex = rhs.getIndex(); + // Use the current size of the vector we are equal to + // Avoids copying over unused indices + maxSize = rhs.getSize(); + return *this; +} + +/** destructor + * @brief Destroy the Vector::Vector object + */ +template +Vector::~Vector() +{ + if (!isEmpty()) makeEmpty(); +} + + +/****************************************************************************** + * Public Member Functions + *****************************************************************************/ + +/** push + * @brief Push a value to the end of our Vector + * + * @param val The value to be inserted + */ +template +bool Vector::push(T val) +{ + bool inserted = push(val, data); + if (inserted) + std::cout << "[" << val << "] was inserted into the vector\n"; + else std::cout << "[" << val << "] could not be inserted into the vector\n"; + return inserted; +} + +/** pop + * @brief returns the value at the Vector::data[curIndex] if it exists + * Once returned, the curIndex is decremented via data[curIndex--] + * If the vector is empty, returns INT32_MIN + * + * @return int The value held at the Node pointed to by Vector::data[index] + */ +template +T Vector::pop() +{ + T val; + if (!isEmpty()) { + val = pop(data); + std::cout << "[" << val << "] has been popped from our Vector\n"; + } + else std::cout << "Nothing to pop, our Vector is empty...\n"; + return val; +} + +/** makeEmpty + * @brief Empty this Vector object, deleting all associated data + */ +template +void Vector::makeEmpty() +{ + if (isEmpty()) { + std::cout << "Cannot makeEmpty, our Vector is already empty...\n"; + return; + } + else makeEmpty(data); +} + +/** peek + * @brief returns the value at the end of the vector + * If the vector is empty, returns INT32_MIN + * + * @return int The value held at the current data[index] of the vector + */ +template +T Vector::peek() const +{ + T val = NULL; + if (!isEmpty()) { + val = peek(data); + std::cout << "[" << peek(data) << "] is at the end of our vector\n"; + } + else std::cout << "Nothing to peek, our vector is empty...\n"; + return val; +} + +/** isEmpty + * @brief Determine if the Vector is empty + * + * @return true If the Vector::data is NULL + * @return false If the Vector::data contains any values + */ +template +bool Vector::isEmpty() const +{ + return data == NULL; +} + +/** isFull + * @brief Determine if the Vector is full + * + * @return true If the Vector::size is equal to the current index + * @return false If the Vector::size is greater than the current index + */ +template +bool Vector::isFull() const +{ + return getSize() == getMax() || data == NULL; +} + +/** print + * @brief Output the data held by the Vector object + * Calls to the private print() + */ +template +void Vector::print() const +{ + if(!isEmpty()) print(data); + else std::cout << "Nothing to print, our vector is empty...\n"; +} + +/** getMax + * @brief Returns the literal maximum size of the vector + * Not offset to match any index - Vector with max size 3 has indices 0-2 + * + * @return int at this->maxSize + */ +template +T Vector::getMax() const +{ + return maxSize; +} + +/** getSize + * @brief Returns the current size of the vector + * AKA the current number of indices being used, NOT the max indices + * + * @return int at this->curIndex + 1 + */ +template +T Vector::getSize() const +{ + return curIndex + 1; +} + +/** getIndex + * @brief Returns the current index of the vector + * AKA the last index the vector wrote to + * + * @return int at this->curIndex + */ +template +T Vector::getIndex() const +{ + return curIndex; +} + +// TODO: use operator[](){...} instead + +/** getValue + * @brief Get the value stored at a given index within the vector + * + * @param index The index containing the value to be returned + * @return int The value held at the index given + */ +template +T Vector::getValue(T index) const +{ + return data[index]; +} + + +/****************************************************************************** + * Private Member Functions + *****************************************************************************/ + +/** push + * @brief Private member to handle inserting value into the vector + * + * @param val Value to be inserted + * @param data The data of the vector to push the value into + * + * @return true If the value was inserted + * @return false If the value could not be inserted + */ +template +bool Vector::push(T val, T *&data) +{ + T *temp; + if (isFull()) { + if (maxSize <= 0) maxSize = 1; + else maxSize *= 2; + temp = new T[maxSize]; + for (int i = 0; i <= curIndex; i++) { + temp[i] = data[i]; + } + std::swap(data, temp); + } + curIndex += 1; + data[curIndex] = val; + return data[curIndex] == val; +} + +/** pop + * @brief Returns the value held at the last index within the Vector + * Decrements the curIndex after storing the value to be returned + * + * @param data The Vector data to modify + * @return int The value stored at the index removed from the end of the Vector + */ +template +T Vector::pop(T *&data) +{ + // We already know the vector is not empty from public pop() + T val = data[curIndex--]; + if (curIndex < 0) makeEmpty(data); + return val; +} + +/** makeEmpty + * @brief Private member to empty Vector object, deleting all associated data + * + * @param data The data of the Vector to be deleted + */ +template +void Vector::makeEmpty(T *&data) +{ + delete[] data; + maxSize = 0; + curIndex = -1; + data = NULL; +} + +/** peek + * @brief Private member to display the value at the end of our Vector + * + * @param data The Vector data to peek + * @return int The value stored at the end of the Vector + */ +template +T Vector::peek(T *data) const +{ + // We already know the vector is not empty from public peek() + return data[curIndex]; +} + +/** print + * @brief Output the contents of a Vector from the beginning to the end + * + * @param data The data within the Vector to output + */ +template +void Vector::print(T *data) const +{ + std::cout << "Vector Contents: "; + for (int i = 0; i <= curIndex; i++) { + std::cout << data[i] << " | "; + } + std::cout << std::endl; +} + +template class Vector; +template class Vector; diff --git a/cpp/datastructs/templates/vector/vector.h b/cpp/datastructs/templates/vector/vector.h new file mode 100644 index 0000000..ac9bf0b --- /dev/null +++ b/cpp/datastructs/templates/vector/vector.h @@ -0,0 +1,48 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ## +## About: An example of a vector implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +## vector.h +*/ + +#ifndef VECTOR_H +#define VECTOR_H + +#include +#include + +template +class Vector { + public: + Vector() : maxSize(0), curIndex(-1), data(NULL) {}; + Vector(const Vector& rhs); + Vector operator=(Vector rhs); + ~Vector(); + bool push(T val); + T pop(); + void makeEmpty(); + T peek() const; + bool isEmpty() const; + bool isFull() const; + void print() const; + T getMax() const; + T getSize() const; + T getIndex() const; + T getValue(T index) const; + + private: + T maxSize; + T curIndex; + T *data; + bool push(T val, T *&data); + T pop(T *&data); + void makeEmpty(T *&data); + T peek(T *data) const; + void print(T *data) const; + +}; + +#endif