Commit 03853203 authored by Rachel Wil Sha Singh's avatar Rachel Wil Sha Singh 💬
Browse files

Stacks lab

parent 7e6943b2
#ifndef ARRAY_QUEUE_HPP
#define ARRAY_QUEUE_HPP
#include "Vector.hpp"
#include "../Utilities/Logger.hpp"
#include "../Exceptions/NotImplementedException.hpp"
template <typename T>
class ArrayStack
{
public:
//! Push a new item into the back of the queue
void Push(const T& newData );
//! Remove the item at the front of the queue
void Pop() noexcept;
//! Access the data at the front of the queue
T& Top();
//! Get the amount of items in the queue
int Size();
//! Return whether the queue is empty
bool IsEmpty();
private:
Vector<T> m_vector;
friend class StackTester;
};
template <typename T>
void ArrayStack<T>::Push( const T& newData )
{
Logger::Out( "Function Begin", "ArrayQueue::Push" );
throw NotImplementedException( "ArrayQueue::Push is not implemented" );
}
template <typename T>
void ArrayStack<T>::Pop() noexcept
{
Logger::Out( "Function Begin", "ArrayQueue::Pop" );
throw NotImplementedException( "ArrayQueue::Pop is not implemented" );
}
template <typename T>
T& ArrayStack<T>::Top()
{
Logger::Out( "Function Begin", "ArrayQueue::Front" );
throw NotImplementedException( "ArrayQueue::Front is not implemented" );
}
template <typename T>
int ArrayStack<T>::Size()
{
Logger::Out( "Function Begin", "ArrayQueue::Size" );
throw NotImplementedException( "ArrayQueue::Size is not implemented" );
}
template <typename T>
bool ArrayStack<T>::IsEmpty()
{
Logger::Out( "Function Begin", "ArrayQueue::IsEmpty" );
return m_vector.IsEmpty();
}
#endif
#ifndef LINKED_LIST_HPP
#define LINKED_LIST_HPP
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
#include "../Utilities/Logger.hpp"
#include "../Utilities/StringUtil.hpp"
template <typename T>
struct Node
{
public:
Node();
Node( T data );
Node<T>* m_ptrNext;
Node<T>* m_ptrPrev;
T m_data;
};
template <typename T>
class LinkedList
{
private:
/* Member Variables */
//! A pointer to the first item in the list
Node<T>* m_ptrFirst;
//! A pointer to the last item in the list
Node<T>* m_ptrLast;
//! The amount of items stored in the list
int m_itemCount;
public:
/* Member Functions */
LinkedList();
~LinkedList();
//! Add a new item to the front of the list
void PushFront( const T& newData );
//! Add a new item to the back of the list
void PushBack(const T& newData );
//! Remove the front-most item
void PopFront() noexcept;
//! Remove the last item
void PopBack() noexcept;
//! Get the data of the front-most item
T& GetFront();
//! Get the data of the back-most item
T& GetBack();
//! Subscript operator to get an item at an arbitrary index
T& operator[]( const int index );
//! Clear all items out of the list
void Clear();
//! Returns true if the list is empty, or false otherwise
bool IsEmpty();
//! Returns the amonut of items stored in the list
int Size();
//! Returns whether the given index is invalid.
bool IsInvalidIndex( int index ) const;
//! Returns whether the list contains this item.
bool Contains( const T& otherItem ) const; // new
void NotImplemented() const;
friend class LinkedListTester;
};
/**
Set the next and previous pointers to nullptr
*/
template <typename T>
Node<T>::Node()
{
Logger::Out( "Function Begin", "Node::Node" );
m_ptrNext = nullptr;
m_ptrPrev = nullptr;
}
template <typename T>
Node<T>::Node( T data )
{
Logger::Out( "Function Begin", "Node::Node( T )" );
m_data = data;
m_ptrNext = nullptr;
m_ptrPrev = nullptr;
}
/**
- Initialize the first and last pointers to nullptr.
- Set the item count to 0.
*/
template <typename T>
LinkedList<T>::LinkedList() /* LinkedList */
{
Logger::Out( "Function Begin", "LinkedList::LinkedList" );
m_ptrFirst = nullptr;
m_ptrLast = nullptr;
m_itemCount = 0;
}
/**
Call the Clear function
*/
template <typename T>
LinkedList<T>::~LinkedList() /* ~LinkedList */
{
Logger::Out( "Function Begin", "LinkedList::~LinkedList" );
Clear();
}
/**
@return void
- While the list is not empty...
- Pop the front most item.
*/
template <typename T>
void LinkedList<T>::Clear() /* Clear */
{
Logger::Out( "Function Begin", "LinkedList::Clear" );
// throw runtime_error( "Clear() not yet implemented" );
while ( !IsEmpty() )
{
Logger::Out( "Total items: " + StringUtil::ToString( m_itemCount ), "LinkedList::Clear" );
PopFront();
}
}
/**
@param T newData New item to add to the list
@return void
Add a new item to the beginning of the list.
- Create a Node<T>* pointer, and allocate new memory via it.
- Set the new node's data to the newData.
- Increment the item count
- If the list is currently empty...
- Set the first and last pointers to this new pointer.
- Otherwise...
- Set the first pointer's previous item to this new pointer.
- Set the new node's next pointer to the first item.
- Update the first pointer to point to the new item.
*/
template <typename T>
void LinkedList<T>::PushFront(const T& newData ) /* PushFront */
{
Logger::Out( "Function Begin", "LinkedList::PushFront" );
// throw runtime_error( "PushFront() not yet implemented" );
Node<T>* newNode = new Node<T>;
newNode->m_data = newData;
if ( IsEmpty() )
{
m_ptrFirst = newNode;
m_ptrLast = newNode;
}
else
{
newNode->m_ptrNext = m_ptrFirst;
m_ptrFirst->m_ptrPrev = newNode;
m_ptrFirst = newNode;
}
m_itemCount++;
}
/**
@param T newData New item to add to the list
@return void
Add a new item to the end of the list.
- Create a Node<T>* pointer, and allocate new memory via it.
- Set the new node's data to the newData.
- Increment the item count
- If the list is currently empty...
- Set the first and last pointers to this new pointer.
- Otherwise...
- Set the last pointer's next item to this new pointer.
- Set the new node's previous pointer to the last item.
- Update the last pointer to point to the new item.
*/
template <typename T>
void LinkedList<T>::PushBack( const T& newData ) /* PushBack */
{
Logger::Out( "Function Begin", "LinkedList::PushBack" );
// throw runtime_error( "PusBack() not yet implemented" );
Node<T>* newNode = new Node<T>;
newNode->m_data = newData;
if ( IsEmpty() )
{
m_ptrFirst = newNode;
m_ptrLast = newNode;
}
else
{
m_ptrLast->m_ptrNext = newNode;
newNode->m_ptrPrev = m_ptrLast;
m_ptrLast = newNode;
}
m_itemCount++;
}
/**
@return void
Remove the first-most item in the list, and update the m_ptrFirst to point
to the new first item.
- If the list is Empty... do nothing
- Else, if there is only one item in the list:
- Delete (either the first or last) node in the list (only one).
- Set the first and last pointer to nullptr
- Decrement the item count
- Else:
- Create a pointer to point to the second item.
- Set the second item's next pointer to nullptr.
- Delete the first item
- Set the m_ptrFirst pointer to that second item.
- Decrement the item count
*/
template <typename T>
void LinkedList<T>::PopFront() noexcept /* PopFront */
{
Logger::Out( "Function Begin", "LinkedList::PopFront" );
if ( m_itemCount == 0 )
{
// ignore
Logger::Out( "0 items in list", "LinkedList::PopFront" );
}
else if ( m_itemCount == 1 )
{
Logger::Out( "1 item in list", "LinkedList::PopFront" );
delete m_ptrFirst;
m_ptrFirst = nullptr;
m_ptrLast = nullptr;
m_itemCount--;
}
else
{
Logger::Out( "size > 1", "LinkedList::PopFront" );
Node<T>* ptrSecond = m_ptrFirst->m_ptrNext;
ptrSecond->m_ptrPrev = nullptr;
delete m_ptrFirst;
m_ptrFirst = ptrSecond;
m_itemCount--;
}
}
/**
@return void
Remove the last-most item in the list, and update the m_ptrLast to point
to the new last item.
- If the list is Empty... do nothing
- Else, if there is only one item in the list:
- Delete (either the first or last) node in the list (only one).
- Set the first and last pointer to nullptr
- Decrement the item count
- Else:
- Create a pointer to point to the second-to-last item.
- Set the second-to-last item's next pointer to nullptr.
- Delete the last item
- Set the m_ptrLast pointer to that second-to-last item.
- Decrement the item count
*/
template <typename T>
void LinkedList<T>::PopBack() noexcept /* PopBack */
{
Logger::Out( "Function Begin", "LinkedList::PopBack" );
// throw runtime_error( "PopBack() not yet implemented" );
if ( m_itemCount == 0 )
{
// ignore
Logger::Out( "0 items in list", "LinkedList::PopBack" );
}
else if ( m_itemCount == 1 )
{
Logger::Out( "1 item in list", "LinkedList::PopBack" );
delete m_ptrFirst;
m_ptrFirst = nullptr;
m_ptrLast = nullptr;
m_itemCount--;
}
else
{
Node<T>* ptrSecond = m_ptrLast->m_ptrPrev;
ptrSecond->m_ptrNext = nullptr;
delete m_ptrLast;
m_ptrLast = ptrSecond;
m_itemCount--;
}
}
/**
@return T& The front item in the list is returned
Error checks:
- If the list is empty, throw an exception.
Otherwise, return the data that belongs to the front pointer (m_ptrFirst).
*/
template <typename T>
T& LinkedList<T>::GetFront() /* GetFront */
{
Logger::Out( "Function Begin", "LinkedList::GetFront" );
// throw runtime_error( "GetFront() not yet implemented" );
if ( m_ptrFirst == nullptr )
{
throw out_of_range( "Cannot GET an item from an empty list!" );
}
else
{
return m_ptrFirst->m_data;
}
}
/**
@return T& The back item in the list is returned
Error checks:
- If the list is empty, throw an exception.
Otherwise, return the data that belongs to the last pointer (m_ptrLast).
*/
template <typename T>
T& LinkedList<T>::GetBack() /* GetBack */
{
Logger::Out( "Function Begin", "LinkedList::GetBack" );
// throw runtime_error( "GetBack() not yet implemented" );
if ( IsEmpty() )
{
throw out_of_range( "Cannot GET an item from an empty list!" );
}
else
{
return m_ptrLast->m_data;
}
}
/**
@param int index The position of the item to return.
@return T& Returns the item at the given index.
Error checks:
- If the list is empty, throw an exception.
- If the index is invalid, throw an exception.
Functionality:
You'll need to traverse through the list, starting at the beginning and moving forward, one-by-one.
- Create a Node<T>* "walker" pointer to walk through the items. Start it at the m_ptrFirst position.
- Make a loop that will loop 'index' amount of times. Within the loop...
- Move your walking pointer forward by one (current = current->m_ptrNext)
- Once done, return the data of the item (access via the walker pointer.)
*/
template <typename T>
T& LinkedList<T>::operator[]( const int index ) /* operator[] */
{
Logger::Out( "Function Begin", "LinkedList::operator[]" );
// throw runtime_error( "operator[]() not yet implemented" );
if ( IsEmpty() )
{
throw out_of_range( "Cannot GET an item from an empty list!" );
}
else if ( IsInvalidIndex( index ) )
{
throw out_of_range( "Invalid index passed into [ ]" );
}
int counter = 0;
Node<T>* current = m_ptrFirst;
while ( current != nullptr && counter < index )
{
current = current->m_ptrNext;
counter++;
}
return current->m_data;
}
/**
@return bool Return true if there are no items stored in the list, and false otherwise.
*/
template <typename T>
bool LinkedList<T>::IsEmpty() /* IsEmpty */
{
Logger::Out( "Function Begin", "LinkedList::IsEmpty" );
// throw runtime_error( "IsEmpty() not yet implemented" );
return ( m_itemCount == 0 );
}
/**
@return int The amount of items stored in the List. Use m_itemCount here.
*/
template <typename T>
int LinkedList<T>::Size() /* Size */
{
Logger::Out( "Function Begin", "LinkedList::Size" );
// throw runtime_error( "Size() not yet implemented" );
return m_itemCount;
}
/**
@param int index The index to look at.
@return bool true if invalid index (less than 0 or >= m_arraySize),
or false if not invalid.
*/
template <typename T>
bool LinkedList<T>::IsInvalidIndex( int index ) const /* IsInvalidIndex */
{
Logger::Out( "Function Begin", "LinkedList::IsInvalidIndex" );
return ( index < 0 || index >= m_itemCount );
// NotImplemented();
}
/**
@param const T& otherItem An item to try to find in the Linked List
@param bool Returns true if item is found in the list, false otherwise.
*/
template <typename T>
bool LinkedList<T>::Contains( const T& otherItem ) const
{
Logger::Out( "Function Begin", "LinkedList::Contains" );
Node<T>* current = m_ptrFirst;
while ( current != nullptr )
{
if ( current->m_data == otherItem )
{
return true;
}
current = current->m_ptrNext;
}
return false;
// NotImplemented();
}
/* ****************************************************************************/
/* ************************************************* FUNCTION TO THROW ERRORS */
/* ****************************************************************************/
//! Marks when a function hasn't been implemented yet.
template <typename T>
void LinkedList<T>::NotImplemented() const /* NotImplemented */
{
throw runtime_error( "Function not implemented yet!" );
}
#endif
This diff is collapsed.
#ifndef LINKED_QUEUE_HPP
#define LINKED_QUEUE_HPP
#include "LinkedList.hpp"
#include "../Utilities/Logger.hpp"
#include "../Exceptions/NotImplementedException.hpp"
template <typename T>
class LinkedStack
{
public:
//! Push a new item into the back of the queue
void Push(const T& newData );
//! Remove the item at the front of the queue
void Pop() noexcept;
//! Access the data at the front of the queue
T& Top();
//! Get the amount of items in the queue
int Size();
//! Return whether the queue is empty
bool IsEmpty();
private:
LinkedList<T> m_list;
friend class StackTester;
};