Reorganize files
This commit is contained in:
20
cpp/cmake/CMakeLists.txt
Normal file
20
cpp/cmake/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
###############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
|
||||
# Define the version of CMake
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
# Define the your project name
|
||||
project(cmake-template)
|
||||
|
||||
# Include any directories the compiler may need
|
||||
include_directories(./include)
|
||||
|
||||
# Point CMake to look for more CMakeLists within the following directories
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(apps)
|
||||
|
||||
17
cpp/cmake/apps/CMakeLists.txt
Normal file
17
cpp/cmake/apps/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
###############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## This directory is for storing / compiling our executable code
|
||||
|
||||
# Create a reference / variable to refer to our source code
|
||||
set(APP_SRC say-hello.cpp)
|
||||
|
||||
# Add our executable, naming it and linking it to our source code
|
||||
add_executable(execute-hello ${APP_SRC})
|
||||
|
||||
# Link to our custom library, defined in c-cmake/src/
|
||||
target_link_libraries(execute-hello lib-klips)
|
||||
|
||||
19
cpp/cmake/apps/say-hello.cpp
Normal file
19
cpp/cmake/apps/say-hello.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
*/
|
||||
|
||||
#include <lib-klips.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main () {
|
||||
PrintHello(5);
|
||||
std::cout << "Press enter to exit the application. \n";
|
||||
std::cin.ignore();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
14
cpp/cmake/include/lib-klips.hpp
Normal file
14
cpp/cmake/include/lib-klips.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints "Hello World!" \p n times to console.
|
||||
* @param n The number of times to print "Hello World!"
|
||||
*/
|
||||
void PrintHello(int n);
|
||||
|
||||
14
cpp/cmake/src/CMakeLists.txt
Normal file
14
cpp/cmake/src/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
###############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## This directory is for storing source code
|
||||
|
||||
# Create any links we might need
|
||||
set(LIB_SRC lib-klips.cpp)
|
||||
|
||||
# Define our library within CMake and link to the source code
|
||||
add_library(lib-klips ${LIB_SRC})
|
||||
|
||||
18
cpp/cmake/src/lib-klips.cpp
Normal file
18
cpp/cmake/src/lib-klips.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
*/
|
||||
|
||||
#include <lib-klips.hpp>
|
||||
#include <iostream>
|
||||
|
||||
void PrintHello(int n) {
|
||||
while (n) {
|
||||
std::cout << n << ". " << "Hello World!" << std::endl;
|
||||
--n;
|
||||
};
|
||||
}
|
||||
|
||||
23
cpp/datastructs/circledoublelist/Makefile
Normal file
23
cpp/datastructs/circledoublelist/Makefile
Normal file
@@ -0,0 +1,23 @@
|
||||
CXX=g++
|
||||
CXXFLAGS=-g -Wall
|
||||
|
||||
###############################################################################
|
||||
# Driver
|
||||
###############################################################################
|
||||
|
||||
driver: driver.cpp circledoublelist.o
|
||||
${CXX} ${CXXFLAGS} driver.cpp circledoublelist.o -o driver
|
||||
|
||||
###############################################################################
|
||||
# CircleDoubleList
|
||||
###############################################################################
|
||||
|
||||
circledoublelist.o: circledoublelist.cpp circledoublelist.h
|
||||
${CXX} ${CXXFLAGS} -c circledoublelist.cpp -o circledoublelist.o
|
||||
|
||||
###############################################################################
|
||||
# Clean
|
||||
###############################################################################
|
||||
|
||||
clean:
|
||||
rm -f *.o driver
|
||||
403
cpp/datastructs/circledoublelist/circledoublelist.cpp
Normal file
403
cpp/datastructs/circledoublelist/circledoublelist.cpp
Normal file
@@ -0,0 +1,403 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ##
|
||||
## About: An example of a circular doubly linked list ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## circledoublelist.cpp
|
||||
*/
|
||||
|
||||
#include "circledoublelist.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Constructors, Destructors, Operators
|
||||
*****************************************************************************/
|
||||
|
||||
/** copy constructor
|
||||
* @brief Construct a new CircleDoubleList::CircleDoubleList object from an existing one
|
||||
*
|
||||
* @param rhs CircleDoubleList object
|
||||
*/
|
||||
CircleDoubleList::CircleDoubleList(const CircleDoubleList& rhs)
|
||||
{
|
||||
Node *cp = rhs.tail;
|
||||
Node *tempHead;
|
||||
if (cp == NULL) tail = NULL;
|
||||
else {
|
||||
tail = new Node(cp->data);
|
||||
tempHead = tail;
|
||||
while (cp->next != NULL) {
|
||||
cp = cp->next;
|
||||
tail->next = new Node(cp->data);
|
||||
tail = tail->next;
|
||||
}
|
||||
tail = tempHead;
|
||||
}
|
||||
}
|
||||
|
||||
/** operator=
|
||||
* @brief Assign two CircleDoubleList objects equal using copy constr and class destr
|
||||
* Pass the rhs by value to create local copy, swap its contents
|
||||
* Destructor called on previous CircleDoubleList data at the end of this scope
|
||||
*
|
||||
* @param rhs CircleDoubleList object passed by value
|
||||
* @return CircleDoubleList A deep copy of the rhs CircleDoubleList object
|
||||
*/
|
||||
CircleDoubleList CircleDoubleList::operator=(CircleDoubleList rhs)
|
||||
{
|
||||
if (this != &rhs) return *this;
|
||||
std::swap(tail, rhs.tail);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** destructor
|
||||
* @brief Destroy the CircleDoubleList::CircleDoubleList object
|
||||
*/
|
||||
CircleDoubleList::~CircleDoubleList()
|
||||
{
|
||||
makeEmpty();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Public Member Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/** insert
|
||||
* @brief Inserts a value to the head of our linked list
|
||||
*
|
||||
* @param val The value to be inserted
|
||||
*/
|
||||
bool CircleDoubleList::insert(int val)
|
||||
{
|
||||
bool inserted = insert(val, tail);
|
||||
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 positon
|
||||
*
|
||||
* @param key The value to search for to determine insert location
|
||||
* @param val The value to be inserted into the list
|
||||
*/
|
||||
bool CircleDoubleList::insert(int val, int key)
|
||||
{
|
||||
// Check that we are not trying to insert at a position within an empty list
|
||||
if (tail == NULL) {
|
||||
std::cout << "Cannot insert at a key value using an empty list\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool inserted = insert(val, key, tail->next);
|
||||
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 overloaded 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 CircleDoubleList::remove(int val)
|
||||
{
|
||||
// Check that we are not trying to remove from an empty list
|
||||
if (isEmpty()) {
|
||||
std::cout << "Cannot remove from an empty list\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to remove the item
|
||||
bool removed = remove(val, tail->next);
|
||||
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 overloaded 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 CircleDoubleList::replace(int val, int key)
|
||||
{
|
||||
// Check that we are not trying to replace within an empty list
|
||||
if (isEmpty()) {
|
||||
std::cout << "Cannot replace anything within an empty list\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to replace the item
|
||||
bool replaced = replace(val, key, tail->next);
|
||||
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 CircleDoubleList object, deleting all associated Nodes
|
||||
*/
|
||||
void CircleDoubleList::makeEmpty()
|
||||
{
|
||||
Node *nextNode;
|
||||
if (isEmpty()) return;
|
||||
|
||||
// Start deletion from the head of the list
|
||||
nextNode = tail->next;
|
||||
while(!isEmpty()) {
|
||||
nextNode = nextNode->next;
|
||||
remove(nextNode->prev->data);
|
||||
}
|
||||
nextNode = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/** isEmpty
|
||||
* @brief Determine if the CircleDoubleList is empty
|
||||
*
|
||||
* @return true If the CircleDoubleList::tail is NULL
|
||||
* @return false If the CircleDoubleList::tail contains data
|
||||
*/
|
||||
bool CircleDoubleList::isEmpty() const
|
||||
{
|
||||
return tail == NULL;
|
||||
}
|
||||
|
||||
/** peek
|
||||
* @brief returns the value at the CircleDoubleList::head
|
||||
*
|
||||
* @return int The value held at the Node pointed to by CircleDoubleList::head
|
||||
*/
|
||||
int CircleDoubleList::peek() const
|
||||
{
|
||||
if (!isEmpty())
|
||||
std::cout << "[" << tail->next->data << "] is at the top of our list\n";
|
||||
else std::cout << "Nothing to peek, our list is empty...\n";
|
||||
return tail->data;
|
||||
}
|
||||
|
||||
/** print
|
||||
* @brief Output the data held by the CircleDoubleList object
|
||||
* Calls to the private print()
|
||||
*/
|
||||
void CircleDoubleList::print() const
|
||||
{
|
||||
// Print from the head of our list
|
||||
if(!isEmpty()) print(tail->next);
|
||||
else std::cout << "Nothing to print, our list is empty...\n";
|
||||
}
|
||||
|
||||
/** find
|
||||
* @brief Calls to overloaded private member find() and handles output
|
||||
*
|
||||
* @param val The value to search for within our CircleDoubleList
|
||||
* @return true If the value was found in this CircleDoubleList
|
||||
* @return false If the value was not found in this CircleDoubleList
|
||||
*/
|
||||
bool CircleDoubleList::find(int val) const
|
||||
{
|
||||
// Check that we are not trying to search an empty list
|
||||
if (isEmpty()) {
|
||||
std::cout << "Cannot search an empty list\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
Node *result = find(val, tail);
|
||||
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 tail The tail node 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 CircleDoubleList::insert(int val, Node *&tail)
|
||||
{
|
||||
Node *newNode = new Node(val);
|
||||
if (!isEmpty()) {
|
||||
// Relink the current head to the node after newNode
|
||||
newNode->next = tail->next;
|
||||
tail->next->prev = newNode;
|
||||
// Relink our head and tail nodes, makine newNode the head node
|
||||
tail->next = newNode;
|
||||
newNode->prev = tail;
|
||||
}
|
||||
else tail = 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 CircleDoubleList::insert(int val, int key, Node *&head)
|
||||
{
|
||||
Node *newNode = new Node(val);
|
||||
// Let insert() handle inserting at the head
|
||||
if (head->data == key) return insert(val);
|
||||
|
||||
// Get the node which contains our value
|
||||
Node *keyNode = find(key, head);
|
||||
// If there was no keyNode found, the key is not in our list, do nothing
|
||||
if (keyNode == NULL) return false;
|
||||
// Insert the newNode in front of the previous to the keyNode
|
||||
// [head]->[key]->[tail]
|
||||
// [head]->[new]->[key]->[tail]
|
||||
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 CircleDoubleList::remove(int val, Node *&head)
|
||||
{
|
||||
// If there is only one node in the list
|
||||
// Synonymous with: if (tail = tail->next)
|
||||
if (head == head->next) {
|
||||
delete tail;
|
||||
tail = NULL;
|
||||
// Nothing to relink, list is empty
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the head node contains the value to remove
|
||||
if (head->data == val) {
|
||||
Node *temp = head;
|
||||
// Move head to the next node in the list
|
||||
head = head->next;
|
||||
// Relink head and tail nodes
|
||||
head->prev = tail;
|
||||
tail->next = head;
|
||||
// Delete dangling pointer created by relinking
|
||||
delete temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the tail node contains the value to remove
|
||||
if (tail->data == val) {
|
||||
Node *temp = tail;
|
||||
// Move tail to the previous node in the list
|
||||
tail = tail->prev;
|
||||
// Relink head and tail nodes
|
||||
head->prev = tail;
|
||||
tail->next = head;
|
||||
// Delete dangling pointer created by relinking
|
||||
delete temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Search for the value further within our list
|
||||
Node *keyNode = find(val, head);
|
||||
// If NULL, the value does not exist within our list
|
||||
if (keyNode == NULL) return false;
|
||||
// Relink surrounding nodes to make keyNode a dangling ptr
|
||||
keyNode->next->prev = keyNode->prev;
|
||||
keyNode->prev->next = keyNode->next;
|
||||
// Delete the dangling node created by relinking above
|
||||
delete keyNode;
|
||||
keyNode = 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 node of the list to modify
|
||||
* @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 CircleDoubleList::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 CircleDoubleList
|
||||
* @param start The node to begin the search from, returns on the first found result
|
||||
* @return CircleDoubleList::Node* A pointer to the Node containing the search value
|
||||
*/
|
||||
CircleDoubleList::Node* CircleDoubleList::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;
|
||||
|
||||
// Copy our start position, check its value
|
||||
Node *foundNode = start;
|
||||
if (foundNode->data == val) return foundNode;
|
||||
// Keep checking the next node until we reach the start value again
|
||||
while (foundNode->next != start) {
|
||||
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 CircleDoubleList from the given Node to NULL
|
||||
*
|
||||
* @param start The Node to begin traversing output from
|
||||
*/
|
||||
void CircleDoubleList::print(Node *start) const
|
||||
{
|
||||
Node *temp = start;
|
||||
std::cout << "List Contents: " << temp->data << " | ";
|
||||
temp = temp->next;
|
||||
while (temp != start) {
|
||||
std::cout << temp->data << " | ";
|
||||
temp = temp->next;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
48
cpp/datastructs/circledoublelist/circledoublelist.h
Normal file
48
cpp/datastructs/circledoublelist/circledoublelist.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ##
|
||||
## About: An example of a circular doubly linked list ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## circledoublelist.h
|
||||
*/
|
||||
|
||||
#ifndef CIRCLEDOUBLELIST_H
|
||||
#define CIRCLEDOUBLELIST_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class CircleDoubleList {
|
||||
public:
|
||||
CircleDoubleList() : tail(NULL) {};
|
||||
CircleDoubleList(const CircleDoubleList& rhs);
|
||||
CircleDoubleList operator=(CircleDoubleList rhs);
|
||||
~CircleDoubleList();
|
||||
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(this), prev(this) {};
|
||||
};
|
||||
Node *tail;
|
||||
bool insert(int val, Node *&tail);
|
||||
bool insert(int val, int key, Node *&tail);
|
||||
bool remove(int val, Node *&tail);
|
||||
bool replace(int val, int key, Node *&tail);
|
||||
Node* find(int val, Node *start) const;
|
||||
void print(Node *start) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
104
cpp/datastructs/circledoublelist/driver.cpp
Normal file
104
cpp/datastructs/circledoublelist/driver.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ##
|
||||
## About: A driver program to test a circular doubly linked list ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## driver.cpp
|
||||
*/
|
||||
|
||||
#include "circledoublelist.h"
|
||||
#include <iostream>
|
||||
|
||||
enum OPS {
|
||||
EXIT, INSERT, INSERTAT, EMPTY, PEEK, PRINT, FIND, REMOVE, REPLACE
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
CircleDoubleList testList;
|
||||
bool exit = false;
|
||||
int choice = -1;
|
||||
int val, key;
|
||||
|
||||
while (!exit)
|
||||
{
|
||||
std::cout << "##### Circular 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
cpp/datastructs/circlesinglelist/Makefile
Normal file
23
cpp/datastructs/circlesinglelist/Makefile
Normal file
@@ -0,0 +1,23 @@
|
||||
CXX=g++
|
||||
CXXFLAGS=-g -Wall
|
||||
|
||||
###############################################################################
|
||||
# Driver
|
||||
###############################################################################
|
||||
|
||||
driver: driver.cpp circlesinglelist.o
|
||||
${CXX} ${CXXFLAGS} driver.cpp circlesinglelist.o -o driver
|
||||
|
||||
###############################################################################
|
||||
# CircleSingleList
|
||||
###############################################################################
|
||||
|
||||
circlesinglelist.o: circlesinglelist.cpp circlesinglelist.h
|
||||
${CXX} ${CXXFLAGS} -c circlesinglelist.cpp -o circlesinglelist.o
|
||||
|
||||
###############################################################################
|
||||
# Clean
|
||||
###############################################################################
|
||||
|
||||
clean:
|
||||
rm -f *.o driver
|
||||
401
cpp/datastructs/circlesinglelist/circlesinglelist.cpp
Normal file
401
cpp/datastructs/circlesinglelist/circlesinglelist.cpp
Normal file
@@ -0,0 +1,401 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ##
|
||||
## About: An example of a circular singly linked list ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## circlesinglelist.cpp
|
||||
*/
|
||||
|
||||
#include "circlesinglelist.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Constructors, Destructors, Operators
|
||||
*****************************************************************************/
|
||||
|
||||
/** copy constructor
|
||||
* @brief Construct a new CircleSingleList::CircleSingleList object from an existing one
|
||||
*
|
||||
* @param rhs CircleSingleList object
|
||||
*/
|
||||
CircleSingleList::CircleSingleList(const CircleSingleList& rhs)
|
||||
{
|
||||
Node *cp = rhs.tail;
|
||||
Node *tempTail;
|
||||
if (cp == NULL) tail = NULL;
|
||||
else {
|
||||
tail = new Node(cp->data);
|
||||
tempTail = tail;
|
||||
while (cp->next != NULL) {
|
||||
cp = cp->next;
|
||||
tail->next = new Node(cp->data);
|
||||
tail = tail->next;
|
||||
}
|
||||
tail = tempTail;
|
||||
}
|
||||
}
|
||||
|
||||
/** operator=
|
||||
* @brief Deep copy of the rhs CircleSingleList object
|
||||
* Pass rhs by value to create local copy, swap its data with our tail
|
||||
* Swapped local copy now with previous tail data deleted at end of scope using destr
|
||||
*
|
||||
* @param rhs CircleSingleList object
|
||||
* @return CircleSingleList& A deep copy of the rhs CircleSingleList
|
||||
*/
|
||||
CircleSingleList CircleSingleList::operator=(CircleSingleList rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
else std::swap(tail, rhs.tail);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** destructor
|
||||
* @brief Destroy the CircleSingleList::CircleSingleList object
|
||||
*/
|
||||
CircleSingleList::~CircleSingleList()
|
||||
{
|
||||
makeEmpty();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Public Member Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/** insert
|
||||
* @brief Inserts a value to the head of our linked list
|
||||
*
|
||||
* @param x The value to be inserted
|
||||
*/
|
||||
bool CircleSingleList::insert(int val)
|
||||
{
|
||||
bool inserted = insert(val, tail);
|
||||
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 positon
|
||||
*
|
||||
* @param key The value to search for to determine insert location
|
||||
* @param val The value to be inserted into the list
|
||||
*/
|
||||
bool CircleSingleList::insert(int val, int key)
|
||||
{
|
||||
if (isEmpty()) {
|
||||
std::cout << "Cannot insert at an existing value using an empty list...\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool inserted = insert(val, key, tail);
|
||||
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 CircleSingleList::remove(int val)
|
||||
{
|
||||
if (isEmpty()) {
|
||||
std::cout << "Cannot remove any values from an empty list...\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool removed = remove(val, tail);
|
||||
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 CircleSingleList::replace(int val, int key)
|
||||
{
|
||||
if (isEmpty()) {
|
||||
std::cout << "Cannot replace any values from an empty list...\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool replaced = replace(val, key, tail);
|
||||
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 CircleSingleList object, deleting all associated Nodes
|
||||
*/
|
||||
void CircleSingleList::makeEmpty()
|
||||
{
|
||||
Node *nextNode, *temp;
|
||||
|
||||
// If the list is empty
|
||||
if (tail == NULL) return;
|
||||
|
||||
// If the list has members other than itself, keep a pointer to them
|
||||
if (tail != tail->next) nextNode = tail->next;
|
||||
// Delete the list nodes until we hit the tail
|
||||
while(nextNode != tail) {
|
||||
// Save pointer to delete previous node
|
||||
temp = nextNode;
|
||||
// Move to the next node
|
||||
nextNode = nextNode->next;
|
||||
// Delete the previous node and set it to NULL
|
||||
delete temp;
|
||||
temp = NULL;
|
||||
}
|
||||
|
||||
// Always delete the tail node and set it to NULL
|
||||
delete tail;
|
||||
tail = NULL;
|
||||
}
|
||||
|
||||
/** isEmpty
|
||||
* @brief Determine if the CircleSingleList is empty
|
||||
*
|
||||
* @return true If the CircleSingleList::tail is NULL
|
||||
* @return false If the CircleSingleList::tail contains data
|
||||
*/
|
||||
bool CircleSingleList::isEmpty() const
|
||||
{
|
||||
return tail == NULL;
|
||||
}
|
||||
|
||||
/** peek
|
||||
* @brief return the value at the head of the list
|
||||
*
|
||||
* @return int The value held at the Node at the head of our linked list
|
||||
*/
|
||||
int CircleSingleList::peek() const
|
||||
{
|
||||
// If there is only one data member, a circular list node will point to itself
|
||||
if (!isEmpty())
|
||||
std::cout << "[" << tail->next->data << "] is at the top of our list\n";
|
||||
else std::cout << "Nothing to peek, our list is empty...\n";
|
||||
return tail->next->data;
|
||||
}
|
||||
|
||||
/** print
|
||||
* @brief Output the data held by the CircleSingleList object
|
||||
* Calls to the private print()
|
||||
*/
|
||||
void CircleSingleList::print() const
|
||||
{
|
||||
// Print the list starting from the head node
|
||||
if(!isEmpty()) print(tail->next);
|
||||
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 CircleSingleList
|
||||
* @return true If the value was found in this CircleSingleList
|
||||
* @return false If the value was not found in this CircleSingleList
|
||||
*/
|
||||
bool CircleSingleList::find(int val) const
|
||||
{
|
||||
Node *result = find(val, tail);
|
||||
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 tail The tail 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 CircleSingleList::insert(int val, Node *&tail)
|
||||
{
|
||||
Node *newNode = new Node(val);
|
||||
// If the list is not empty, update next pointer to head node
|
||||
if (!isEmpty()) newNode->next = tail->next;
|
||||
else tail = newNode;
|
||||
// Always set head to our newNode
|
||||
tail->next = 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 tail Tail node of the list to insert to
|
||||
* @return true If the value was inserted
|
||||
* @return false If the value was not inserted
|
||||
*/
|
||||
bool CircleSingleList::insert(int val, int key, Node *&tail)
|
||||
{
|
||||
Node *newNode = new Node(val);
|
||||
if (isEmpty()) return false;
|
||||
// Let insert() handle inserting at the head
|
||||
else if (tail->next->data == key) return insert(val);
|
||||
|
||||
Node *keyNode = findPrevious(key);
|
||||
// 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 between the keyNode and the Node we are inserting at
|
||||
// [keyNode]->[next]
|
||||
// [keyNode]->[newNode]->[next]
|
||||
// Where (keyNode->next->data == key) and keyNode is given by findPrevious()
|
||||
newNode->next = keyNode->next;
|
||||
keyNode->next = newNode;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** remove
|
||||
* @brief Private member to remove values from the list
|
||||
*
|
||||
* @param val Value to be removed
|
||||
* @param tail Tail 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 CircleSingleList::remove(int val, Node *&tail)
|
||||
{
|
||||
Node *exile, *tempHead;
|
||||
Node *prevNode = findPrevious(val);
|
||||
// If findPrevious returns NULL, the value was not found
|
||||
if (prevNode == NULL) return false;
|
||||
|
||||
// If the node found is the only member of the list
|
||||
if (prevNode == prevNode->next) {
|
||||
// Delete, reset list to NULL
|
||||
delete tail;
|
||||
tail = NULL;
|
||||
return true;
|
||||
}
|
||||
// If the node to remove is the tail and the list has > 1 members
|
||||
else if (prevNode->next == tail) {
|
||||
tempHead = tail->next;
|
||||
exile = prevNode->next;
|
||||
// Create the new tail
|
||||
tail = prevNode;
|
||||
// Link the head Node, skipping over the exile Node
|
||||
tail->next = tempHead;
|
||||
}
|
||||
else {
|
||||
// Get a ptr to the member we are removing from the list
|
||||
exile = prevNode->next;
|
||||
// Relink the list, skipping the exile node
|
||||
prevNode->next = prevNode->next->next;
|
||||
}
|
||||
|
||||
// Delete the dangling ptr to the exile Node we removed from the list
|
||||
delete exile;
|
||||
exile = 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 tail Tail 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 CircleSingleList::replace(int val, int key, Node *&tail)
|
||||
{
|
||||
Node *replacee = find(key, tail);
|
||||
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 CircleSingleList
|
||||
* @param start The Node to begin the search at within the linked list, usually the head node
|
||||
* @return CircleSingleList::Node* A pointer to the Node containing the search value
|
||||
*/
|
||||
CircleSingleList::Node* CircleSingleList::find(int val, Node *start) const
|
||||
{
|
||||
// Check the first Node, return if it is the value requested
|
||||
if (start->data == val) return start;
|
||||
Node *foundNode = start->next;
|
||||
// Move through the list, checking each member until we reach the start Node
|
||||
while (foundNode != start) {
|
||||
if (foundNode->data == val) return foundNode;
|
||||
foundNode = foundNode->next;
|
||||
}
|
||||
// If we have not yet returned a foundNode, the key is not in our list
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** findPrevious
|
||||
* @brief Find and return the Node before a given value
|
||||
*
|
||||
* @param val The value to search for within our CircleSingleList
|
||||
* @return CircleSingleList::Node* A pointer to the Node previous to the given value
|
||||
*/
|
||||
CircleSingleList::Node* CircleSingleList::findPrevious(int val) const
|
||||
{
|
||||
if (isEmpty()) return NULL;
|
||||
else if (tail->next->data == val) return tail;
|
||||
|
||||
// Create temp ptr to the head of our list
|
||||
Node *tempHead = tail->next;
|
||||
// Move through the list until we reach the head node again
|
||||
while (tempHead->next != tail->next) {
|
||||
// Check the value within the next node, if found return it
|
||||
if (tempHead->next->data == val) return tempHead;
|
||||
else tempHead = tempHead->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** print
|
||||
* @brief Output the contents of a CircleSingleList until we hit a matching node
|
||||
*
|
||||
* @param start The Node to begin traversing output from
|
||||
*/
|
||||
void CircleSingleList::print(Node *start) const
|
||||
{
|
||||
Node *temp = start;
|
||||
std::cout << "List Contents: " << temp->data << " | ";
|
||||
temp = temp->next;
|
||||
// Until we reach the start node again, print the list contents
|
||||
while (temp != start) {
|
||||
std::cout << temp->data << " | ";
|
||||
temp = temp->next;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
49
cpp/datastructs/circlesinglelist/circlesinglelist.h
Normal file
49
cpp/datastructs/circlesinglelist/circlesinglelist.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ##
|
||||
## About: An example of a circular singly linked list ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## circlesinglelist.h
|
||||
*/
|
||||
|
||||
#ifndef CIRCLESINGLELIST_H
|
||||
#define CIRCLESINGLELIST_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class CircleSingleList {
|
||||
public:
|
||||
CircleSingleList() : tail(NULL) {};
|
||||
CircleSingleList(const CircleSingleList& rhs);
|
||||
CircleSingleList operator=(CircleSingleList rhs);
|
||||
~CircleSingleList();
|
||||
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;
|
||||
Node(): data(), next(NULL) {};
|
||||
Node(int val): data(val), next(this) {};
|
||||
};
|
||||
Node *tail;
|
||||
bool insert(int val, Node *&tail);
|
||||
bool insert(int val, int key, Node *&tail);
|
||||
bool remove(int val, Node *&tail);
|
||||
bool replace(int val, int key, Node *&tail);
|
||||
Node* find(int val, Node *start) const;
|
||||
Node* findPrevious(int val) const;
|
||||
void print(Node *start) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
106
cpp/datastructs/circlesinglelist/driver.cpp
Normal file
106
cpp/datastructs/circlesinglelist/driver.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ##
|
||||
## About: A driver program to test a circular singly linked list ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## driver.cpp
|
||||
*/
|
||||
|
||||
#include "circlesinglelist.h"
|
||||
#include <iostream>
|
||||
|
||||
enum OPS {
|
||||
EXIT, INSERT, INSERTAT, EMPTY, PEEK, PRINT, FIND, REMOVE, REPLACE
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Driver: \n";
|
||||
|
||||
CircleSingleList testList;
|
||||
bool exit = false;
|
||||
int choice = -1;
|
||||
int val, key;
|
||||
|
||||
while (!exit)
|
||||
{
|
||||
std::cout << "##### Circular Singly 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
cpp/datastructs/doublelist/Makefile
Normal file
23
cpp/datastructs/doublelist/Makefile
Normal file
@@ -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
|
||||
338
cpp/datastructs/doublelist/doublelist.cpp
Normal file
338
cpp/datastructs/doublelist/doublelist.cpp
Normal file
@@ -0,0 +1,338 @@
|
||||
/*#############################################################################
|
||||
## 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 positon
|
||||
*
|
||||
* @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";
|
||||
return head->data;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
}
|
||||
48
cpp/datastructs/doublelist/doublelist.h
Normal file
48
cpp/datastructs/doublelist/doublelist.h
Normal file
@@ -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 <iostream>
|
||||
|
||||
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
|
||||
106
cpp/datastructs/doublelist/driver.cpp
Normal file
106
cpp/datastructs/doublelist/driver.cpp
Normal file
@@ -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 <iostream>
|
||||
|
||||
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 << "##### Singly 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
cpp/datastructs/singlelist/Makefile
Normal file
23
cpp/datastructs/singlelist/Makefile
Normal file
@@ -0,0 +1,23 @@
|
||||
CXX=g++
|
||||
CXXFLAGS=-g -Wall
|
||||
|
||||
###############################################################################
|
||||
# Driver
|
||||
###############################################################################
|
||||
|
||||
driver: driver.cpp singlelist.o
|
||||
${CXX} ${CXXFLAGS} driver.cpp singlelist.o -o driver
|
||||
|
||||
###############################################################################
|
||||
# SingleList
|
||||
###############################################################################
|
||||
|
||||
singlelist.o: singlelist.cpp singlelist.h
|
||||
${CXX} ${CXXFLAGS} -c singlelist.cpp -o singlelist.o
|
||||
|
||||
###############################################################################
|
||||
# Clean
|
||||
###############################################################################
|
||||
|
||||
clean:
|
||||
rm -f *.o driver
|
||||
106
cpp/datastructs/singlelist/driver.cpp
Normal file
106
cpp/datastructs/singlelist/driver.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ##
|
||||
## About: A driver program to test a singly linked list ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## driver.cpp
|
||||
*/
|
||||
|
||||
#include "singlelist.h"
|
||||
#include <iostream>
|
||||
|
||||
enum OPS {
|
||||
EXIT, INSERT, INSERTAT, EMPTY, PEEK, PRINT, FIND, REMOVE, REPLACE
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Driver: \n";
|
||||
|
||||
SingleList testList;
|
||||
bool exit = false;
|
||||
int choice = -1;
|
||||
int val, key;
|
||||
|
||||
while (!exit)
|
||||
{
|
||||
std::cout << "##### Singly 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
349
cpp/datastructs/singlelist/singlelist.cpp
Normal file
349
cpp/datastructs/singlelist/singlelist.cpp
Normal file
@@ -0,0 +1,349 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2020 Shaun Reed, all rights reserved ##
|
||||
## About: An example of a singly linked list ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## singlelist.cpp
|
||||
*/
|
||||
|
||||
#include "singlelist.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Constructors, Destructors, Operators
|
||||
*****************************************************************************/
|
||||
|
||||
/** copy constructor
|
||||
* @brief Construct a new SingleList::SingleList object from an existing one
|
||||
*
|
||||
* @param rhs SingleList object
|
||||
*/
|
||||
SingleList::SingleList(const SingleList& 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 SingleList 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
|
||||
*/
|
||||
SingleList SingleList::operator=(SingleList rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
std::swap(head, rhs.head);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** destructor
|
||||
* @brief Destroy the SingleList::SingleList object
|
||||
*/
|
||||
SingleList::~SingleList()
|
||||
{
|
||||
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 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 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 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 SingleList::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 SingleList::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 SingleList object, deleting all associated Nodes
|
||||
*/
|
||||
void SingleList::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 SingleList is empty
|
||||
*
|
||||
* @return true If the SingleList::head is NULL
|
||||
* @return false If the SingleList::head contains data
|
||||
*/
|
||||
bool SingleList::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
|
||||
*/
|
||||
int SingleList::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";
|
||||
return head->data;
|
||||
}
|
||||
|
||||
/** print
|
||||
* @brief Output the data held by the SingleList object
|
||||
* Calls to the private print()
|
||||
*/
|
||||
void SingleList::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 SingleList
|
||||
* @return true If the value was found in this SingleList
|
||||
* @return false If the value was not found in this SingleList
|
||||
*/
|
||||
bool SingleList::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)
|
||||
{
|
||||
Node *newNode = new Node(val);
|
||||
// If the list is not empty, update next pointer to head node
|
||||
if (!isEmpty()) newNode->next = head;
|
||||
// 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 SingleList::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);
|
||||
// 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;
|
||||
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)
|
||||
{
|
||||
|
||||
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;
|
||||
delete gtfo;
|
||||
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)
|
||||
{
|
||||
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 SingleList
|
||||
* @return SingleList::Node* A pointer to the Node containing the search value
|
||||
*/
|
||||
SingleList::Node* SingleList::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;
|
||||
}
|
||||
|
||||
/** 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
|
||||
*
|
||||
* @param start The Node to begin traversing output from
|
||||
*/
|
||||
void SingleList::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;
|
||||
}
|
||||
54
cpp/datastructs/singlelist/singlelist.h
Normal file
54
cpp/datastructs/singlelist/singlelist.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*#############################################################################
|
||||
## 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 ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## singlelist.h
|
||||
*/
|
||||
|
||||
#ifndef SINGLELIST_H
|
||||
#define SINGLELIST_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class SingleList{
|
||||
public:
|
||||
SingleList() : head(NULL) {};
|
||||
SingleList(const SingleList& rhs);
|
||||
SingleList operator=(SingleList rhs);
|
||||
~SingleList();
|
||||
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;
|
||||
Node(): data(), next(NULL) {};
|
||||
Node(int val): data(val), next(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;
|
||||
Node* findPrevious(int val, Node *start) const;
|
||||
void print(Node *start) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
27
cpp/opengl/.vscode/launch.json
vendored
Normal file
27
cpp/opengl/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/test-gl",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
30
cpp/opengl/.vscode/tasks.json
vendored
Normal file
30
cpp/opengl/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "cpp build active file",
|
||||
"command": "/usr/bin/g++",
|
||||
"args": [
|
||||
"${file}",
|
||||
"-lGL",
|
||||
"-lGLU",
|
||||
"-lglut",
|
||||
"-o",
|
||||
"${fileDirname}/build/${fileBasenameNoExtension}"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "/usr/bin"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
192
cpp/opengl/test-gl.cpp
Normal file
192
cpp/opengl/test-gl.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## ##
|
||||
## Testing building OpenGL projects with source code from lazyfoo - ##
|
||||
## https://lazyfoo.net/tutorials/OpenGL/ ##
|
||||
##############################################################################
|
||||
## test-gl.cpp
|
||||
*/
|
||||
#include <GL/freeglut.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//Screen constants
|
||||
const int SCREEN_WIDTH = 640;
|
||||
const int SCREEN_HEIGHT = 480;
|
||||
const int SCREEN_FPS = 60;
|
||||
|
||||
//Color modes
|
||||
const int COLOR_MODE_CYAN = 0;
|
||||
const int COLOR_MODE_MULTI = 1;
|
||||
|
||||
//The current color rendering mode
|
||||
int gColorMode = COLOR_MODE_CYAN;
|
||||
|
||||
//The projection scale
|
||||
GLfloat gProjectionScale = 1.f;
|
||||
|
||||
bool initGL()
|
||||
{
|
||||
//Initialize Projection Matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glOrtho( 0.0, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0, 1.0, -1.0 );
|
||||
|
||||
//Initialize Modelview Matrix
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
|
||||
//Initialize clear color
|
||||
glClearColor( 0.f, 0.f, 0.f, 1.f );
|
||||
|
||||
//Check for error
|
||||
GLenum error = glGetError();
|
||||
if( error != GL_NO_ERROR )
|
||||
{
|
||||
printf( "Error initializing OpenGL! %s\n", gluErrorString( error ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void render()
|
||||
{
|
||||
//Clear color buffer
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
//Reset modelview matrix
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
|
||||
//Move to center of the screen
|
||||
glTranslatef( SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 0.f );
|
||||
|
||||
//Render quad
|
||||
if( gColorMode == COLOR_MODE_CYAN )
|
||||
{
|
||||
//Solid Cyan
|
||||
glBegin( GL_QUADS );
|
||||
glColor3f( 0.f, 1.f, 1.f );
|
||||
glVertex2f( -50.f, -50.f );
|
||||
glVertex2f( 50.f, -50.f );
|
||||
glVertex2f( 50.f, 50.f );
|
||||
glVertex2f( -50.f, 50.f );
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
//RYGB Mix
|
||||
glBegin( GL_QUADS );
|
||||
glColor3f( 1.f, 0.f, 0.f ); glVertex2f( -50.f, -50.f );
|
||||
glColor3f( 1.f, 1.f, 0.f ); glVertex2f( 50.f, -50.f );
|
||||
glColor3f( 0.f, 1.f, 0.f ); glVertex2f( 50.f, 50.f );
|
||||
glColor3f( 0.f, 0.f, 1.f ); glVertex2f( -50.f, 50.f );
|
||||
glEnd();
|
||||
}
|
||||
|
||||
//Update screen
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
void handleKeys( unsigned char key, int x, int y )
|
||||
{
|
||||
//If the user presses q
|
||||
if( key == 'q' )
|
||||
{
|
||||
//Toggle color mode
|
||||
if( gColorMode == COLOR_MODE_CYAN )
|
||||
{
|
||||
gColorMode = COLOR_MODE_MULTI;
|
||||
}
|
||||
else
|
||||
{
|
||||
gColorMode = COLOR_MODE_CYAN;
|
||||
}
|
||||
}
|
||||
else if( key == 'e' )
|
||||
{
|
||||
//Cycle through projection scales
|
||||
if( gProjectionScale == 1.f )
|
||||
{
|
||||
//Zoom out
|
||||
gProjectionScale = 2.f;
|
||||
}
|
||||
else if( gProjectionScale == 2.f )
|
||||
{
|
||||
//Zoom in
|
||||
gProjectionScale = 0.5f;
|
||||
}
|
||||
else if( gProjectionScale == 0.5f )
|
||||
{
|
||||
//Regular zoom
|
||||
gProjectionScale = 1.f;
|
||||
}
|
||||
|
||||
//Update projection matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glOrtho( 0.0, SCREEN_WIDTH * gProjectionScale, SCREEN_HEIGHT * gProjectionScale, 0.0, 1.0, -1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
void runMainLoop( int val );
|
||||
/*
|
||||
Pre Condition:
|
||||
-Initialized freeGLUT
|
||||
Post Condition:
|
||||
-Calls the main loop functions and sets itself to be called back in 1000 / SCREEN_FPS milliseconds
|
||||
Side Effects:
|
||||
-Sets glutTimerFunc
|
||||
*/
|
||||
|
||||
int main( int argc, char* args[] )
|
||||
{
|
||||
//Initialize FreeGLUT
|
||||
glutInit( &argc, args );
|
||||
|
||||
//Create OpenGL 2.1 context
|
||||
glutInitContextVersion( 2, 1 );
|
||||
|
||||
//Create Double Buffered Window
|
||||
glutInitDisplayMode( GLUT_DOUBLE );
|
||||
glutInitWindowSize( SCREEN_WIDTH, SCREEN_HEIGHT );
|
||||
glutCreateWindow( "OpenGL" );
|
||||
|
||||
//Do post window/context creation initialization
|
||||
if( !initGL() )
|
||||
{
|
||||
printf( "Unable to initialize graphics library!\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Set keyboard handler
|
||||
glutKeyboardFunc( handleKeys );
|
||||
|
||||
//Set rendering function
|
||||
glutDisplayFunc( render );
|
||||
|
||||
//Set main loop
|
||||
glutTimerFunc( 1000 / SCREEN_FPS, runMainLoop, 0 );
|
||||
|
||||
//Start GLUT main loop
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void runMainLoop( int val )
|
||||
{
|
||||
//Frame logic
|
||||
update();
|
||||
render();
|
||||
|
||||
//Run frame one more time
|
||||
glutTimerFunc( 1000 / SCREEN_FPS, runMainLoop, val );
|
||||
}
|
||||
27
cpp/sdl-cmake/.vscode/launch.json
vendored
Normal file
27
cpp/sdl-cmake/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/inherited",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
70
cpp/sdl-cmake/CMakeLists.txt
Normal file
70
cpp/sdl-cmake/CMakeLists.txt
Normal file
@@ -0,0 +1,70 @@
|
||||
###############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
# Root CMakeLists.txt of cpp practice 4-inheritance
|
||||
|
||||
# Define CMake version
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project( # Define project
|
||||
inheritance # Project name
|
||||
DESCRIPTION "Example project for class inheritance"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
# Pass this to program to control debug output
|
||||
option (DB_CONF "Should we debug and configure files with cmake values?" ON)
|
||||
option (DB_BUILD "Should we run the build in debug mode?" OFF)
|
||||
option (EXE_BUILD "Should we build the executable?" ON)
|
||||
|
||||
add_library( # Add Library
|
||||
lib-inherit # Library Name
|
||||
"src/lib-inherit.cpp" # Sources..
|
||||
"src/lib-inherit.h"
|
||||
)
|
||||
|
||||
target_include_directories( # When calling library, include a directory
|
||||
lib-inherit # Library name
|
||||
PUBLIC #
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}" # Source directory of exe including our library
|
||||
)
|
||||
|
||||
if (EXE_BUILD)
|
||||
set(BUILD_STATUS "Building default executable")
|
||||
include(FindPkgConfig)
|
||||
pkg_search_module(SDL2 REQUIRED sdl2)
|
||||
include_directories(${SDL2_INCLUDE_DIRS})
|
||||
|
||||
add_executable( # Creating executable
|
||||
inherited # Exe name
|
||||
"apps/inherited.cpp" # Exe Source(s)
|
||||
)
|
||||
target_link_libraries( # Linking the exe to library
|
||||
inherited # Executable to link
|
||||
PRIVATE #
|
||||
lib-inherit # Library to link
|
||||
${SDL2_LIBRARIES}
|
||||
)
|
||||
elseif(DB_BUILD)
|
||||
set(BUILD_STATUS "Building in debug mode")
|
||||
|
||||
# Create compile_commands.json for linter
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
target_compile_definitions(inherited PRIVATE BUILD_STATUS=${BUILD_STATUS})
|
||||
elseif(DB_CONF)
|
||||
set(BUILD_STATUS "Building in debug mode, configuring files")
|
||||
|
||||
# Configure header file with CMake variables defined in src/lib-inherit.h.in
|
||||
# @ONLY is specified, only variables of the form @VAR@ will be replaced and ${VAR} will be ignored.
|
||||
# configure_file(src/lib-inherit.h src/lib-inherit.h @ONLY)
|
||||
configure_file(apps/inherited.cpp apps/inherited.cpp @ONLY)
|
||||
|
||||
# Create compile_commands.json for linter
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
endif()
|
||||
#target_compile_definitions(inherited PRIVATE BUILD_STATUS=${BUILD_STATUS})
|
||||
|
||||
40
cpp/sdl-cmake/apps/inherited.cpp
Normal file
40
cpp/sdl-cmake/apps/inherited.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## apps/inherited.cpp
|
||||
*/
|
||||
|
||||
#include <src/lib-inherit.h>
|
||||
#include <iostream>
|
||||
//#include <string>
|
||||
|
||||
int main (int argc, char const * argv[]) {
|
||||
// Cast cli arguments to void since they are unused in this exe
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
// Ensure SDL is initialized before continuing
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
|
||||
exit(2);
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_Renderer *renderer;
|
||||
|
||||
if (InitScreen(window, renderer) < 0)
|
||||
std::cout << "Error - Unable to initialize SDL screen\n";
|
||||
|
||||
DrawDelay(renderer, 3000);
|
||||
|
||||
std::cout << "Test\n";
|
||||
Shape shape(4,4), dShape;
|
||||
Rectangle rect(4,8), dRect;
|
||||
std::cout << dShape.PrintInfo() << std::endl;
|
||||
std::cout << shape.PrintInfo() << std::endl;
|
||||
std::cout << dRect.PrintInfo() << std::endl;
|
||||
std::cout << rect.PrintInfo() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
71
cpp/sdl-cmake/src/lib-inherit.cpp
Normal file
71
cpp/sdl-cmake/src/lib-inherit.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/*##############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## src/lib-inherit.cpp
|
||||
*/
|
||||
|
||||
#include <src/lib-inherit.h>
|
||||
|
||||
// Shape class definitions
|
||||
|
||||
Shape::Shape(double w, double h) {
|
||||
height = h;
|
||||
width = w;
|
||||
};
|
||||
|
||||
Shape::Shape() {
|
||||
height = 2;
|
||||
width = 2;
|
||||
};
|
||||
|
||||
Shape::~Shape() { /* Shape destructor */};
|
||||
|
||||
const std::string Shape::PrintInfo() {
|
||||
info = name + " HxW: " + std::to_string(height) + "x" + std::to_string(width);
|
||||
return info;
|
||||
};
|
||||
|
||||
// Rectangle Class definitions
|
||||
|
||||
Rectangle::Rectangle(double w, double h) {
|
||||
height = h;
|
||||
width = w;
|
||||
};
|
||||
|
||||
Rectangle::Rectangle() {
|
||||
height = 2;
|
||||
width = 4;
|
||||
};
|
||||
|
||||
Rectangle::~Rectangle() { /* Rectangle destructor */ };
|
||||
|
||||
/// SDL Helper Definitions
|
||||
int InitScreen(SDL_Window* &window, SDL_Renderer* &renderer) {
|
||||
int state = 0;
|
||||
|
||||
// Create window, renderer to draw to screen
|
||||
if (SDL_CreateWindowAndRenderer(500, 500, 0, &window, &renderer) < 0) {
|
||||
std::cout << "Error - Unable to create SDL screen and renderer objects\n";
|
||||
state = -1;
|
||||
}
|
||||
|
||||
// Set render DrawColor, fill screen with color
|
||||
if (SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255) < 0 || SDL_RenderClear(renderer) < 0) {
|
||||
std::cout << "Error - Unable to set renderer draw color\n";
|
||||
state = -1;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void DrawDelay(SDL_Renderer* renderer, int delay) {
|
||||
// Show what we have rendered
|
||||
SDL_RenderPresent(renderer);
|
||||
// Wait 3000ms, then continue
|
||||
SDL_Delay(delay);
|
||||
|
||||
return;
|
||||
}
|
||||
42
cpp/sdl-cmake/src/lib-inherit.h
Normal file
42
cpp/sdl-cmake/src/lib-inherit.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## src/lib-inherit.h
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <vector>
|
||||
|
||||
class Shape {
|
||||
private:
|
||||
double width, height;
|
||||
std::string info;
|
||||
const std::string name = "Shape";
|
||||
|
||||
public:
|
||||
Shape(double w, double h);
|
||||
Shape();
|
||||
~Shape();
|
||||
virtual const std::string PrintInfo();
|
||||
};
|
||||
|
||||
class Rectangle: public Shape {
|
||||
private:
|
||||
double width, height;
|
||||
std::string info;
|
||||
|
||||
public:
|
||||
Rectangle(double w, double h);
|
||||
Rectangle();
|
||||
~Rectangle();
|
||||
|
||||
};
|
||||
|
||||
int InitScreen(SDL_Window* &window, SDL_Renderer* &renderer);
|
||||
|
||||
void DrawDelay(SDL_Renderer* renderer, int delay);
|
||||
29
cpp/sdl/.vscode/launch.json
vendored
Normal file
29
cpp/sdl/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/inherited",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
26
cpp/sdl/.vscode/tasks.json
vendored
Normal file
26
cpp/sdl/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "cpp build active file",
|
||||
"command": "g++",
|
||||
"args": [
|
||||
"${workspaceFolder}/inherited.cpp",
|
||||
"-lSDL2",
|
||||
"-o",
|
||||
"${workspaceFolder}/build/inherited",
|
||||
],
|
||||
"options": {
|
||||
"cwd": "/usr/bin"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
108
cpp/sdl/inherited.cpp
Normal file
108
cpp/sdl/inherited.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/*#############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2019 Shaun Reed, all rights reserved ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
## apps/inherited.cpp
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <vector>
|
||||
|
||||
class Shape {
|
||||
private:
|
||||
double width, height;
|
||||
std::string info;
|
||||
const std::string name = "Shape";
|
||||
|
||||
public:
|
||||
Shape(double w, double h) {
|
||||
height = h;
|
||||
width = w;
|
||||
};
|
||||
Shape() {
|
||||
height = 2;
|
||||
width = 2;
|
||||
};
|
||||
~Shape() { /* Shape destructor */};
|
||||
virtual const std::string PrintInfo() {
|
||||
info = name + " HxW: " + std::to_string(height) + "x" + std::to_string(width);
|
||||
return info;
|
||||
};
|
||||
};
|
||||
|
||||
class Rectangle: public Shape {
|
||||
private:
|
||||
double width, height;
|
||||
std::string info;
|
||||
|
||||
public:
|
||||
Rectangle(double w, double h) {
|
||||
height = h;
|
||||
width = w;
|
||||
};
|
||||
Rectangle() {
|
||||
height = 2;
|
||||
width = 4;
|
||||
};
|
||||
~Rectangle() { /* Rectangle destructor */ };
|
||||
|
||||
};
|
||||
|
||||
int InitScreen(SDL_Window* &window, SDL_Renderer* &renderer) {
|
||||
int state = 0;
|
||||
|
||||
// Create window, renderer to draw to screen
|
||||
if (SDL_CreateWindowAndRenderer(500, 500, 0, &window, &renderer) < 0) {
|
||||
std::cout << "Error - Unable to create SDL screen and renderer objects\n";
|
||||
state = -1;
|
||||
}
|
||||
|
||||
// Set render DrawColor, fill screen with color
|
||||
if (SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255) < 0 || SDL_RenderClear(renderer) < 0) {
|
||||
std::cout << "Error - Unable to set renderer draw color\n";
|
||||
state = -1;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void DrawDelay(SDL_Renderer* renderer, int delay) {
|
||||
// Show what we have rendered
|
||||
SDL_RenderPresent(renderer);
|
||||
// Wait 3000ms, then continue
|
||||
SDL_Delay(delay);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main (int argc, char const * argv[]) {
|
||||
// Cast cli arguments to void since they are unused in this exe
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
// Ensure SDL is initialized before continuing
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
|
||||
exit(2);
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_Renderer *renderer;
|
||||
|
||||
if (InitScreen(window, renderer) < 0)
|
||||
std::cout << "Error - Unable to initialize SDL screen\n";
|
||||
|
||||
DrawDelay(renderer, 3000);
|
||||
|
||||
std::cout << "Test\n";
|
||||
Shape shape(4,4), dShape;
|
||||
Rectangle rect(4,8), dRect;
|
||||
std::cout << dShape.PrintInfo() << std::endl;
|
||||
std::cout << shape.PrintInfo() << std::endl;
|
||||
std::cout << dRect.PrintInfo() << std::endl;
|
||||
std::cout << rect.PrintInfo() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user