Created
July 31, 2016 16:26
-
-
Save goldsborough/c173c7f5d07f3f983228caacac3f9713 to your computer and use it in GitHub Desktop.
Quick and dirty stack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cassert> | |
#include <iostream> | |
template <typename T> | |
class ArrayStack { | |
public: | |
using size_t = unsigned long; | |
static constexpr size_t MINIMUM_CAPACITY = 8; | |
static constexpr size_t GROWTH_FACTOR = 2; | |
static constexpr size_t SHRINK_THRESHOLD = 4; | |
explicit ArrayStack(size_t capacity = MINIMUM_CAPACITY) | |
: _data(new T[capacity]), _size(0), _capacity(capacity) { | |
} | |
~ArrayStack() { | |
delete[] _data; | |
} | |
void push(const T& element) { | |
if (_size == _capacity) { | |
_reallocate(_size * GROWTH_FACTOR); | |
} | |
_data[_size++] = element; | |
} | |
const T& top() const noexcept { | |
assert(_size > 0); | |
return _data[_size - 1]; | |
} | |
T pop() { | |
assert(_size > 0); | |
auto value = _data[_size - 1]; | |
if (--_size == _capacity / SHRINK_THRESHOLD) { | |
_reallocate(_size * GROWTH_FACTOR); | |
} | |
return value; | |
} | |
size_t size() const noexcept { | |
return _size; | |
} | |
bool isEmpty() const noexcept { | |
return size() == 0; | |
} | |
private: | |
void _reallocate(size_t new_capacity) { | |
if (new_capacity < MINIMUM_CAPACITY) { | |
new_capacity = MINIMUM_CAPACITY; | |
} | |
if (new_capacity == _capacity) return; | |
auto old = _data; | |
_data = new T[new_capacity]; | |
for (size_t i = 0; i < _size; ++i) { | |
_data[i] = old[i]; | |
} | |
delete[] old; | |
_capacity = new_capacity; | |
} | |
T* _data; | |
size_t _size; | |
size_t _capacity; | |
}; | |
template <typename T> | |
class ListStack { | |
public: | |
using size_t = unsigned long; | |
ListStack() : _head(nullptr), _size(0) { | |
} | |
~ListStack() { | |
while (_head) { | |
auto next = _head->next; | |
delete _head; | |
_head = next; | |
} | |
} | |
void push(const T& element) { | |
auto node = new Node{element, _head}; | |
++_size; | |
_head = node; | |
} | |
const T& top() const noexcept { | |
assert(_head != nullptr); | |
return _head->element; | |
} | |
T pop() { | |
assert(_head != nullptr); | |
auto node = _head; | |
_head = node->next; | |
auto element = node->element; | |
delete node; | |
--_size; | |
return element; | |
} | |
size_t size() const noexcept { | |
return _size; | |
} | |
bool isEmpty() const noexcept { | |
return size() == 0; | |
} | |
private: | |
struct Node { | |
T element; | |
Node* next; | |
}; | |
Node* _head; | |
size_t _size; | |
}; | |
auto main() -> int { | |
ListStack<int> stack; | |
for (int i = 0; i < 10; ++i) { | |
stack.push(i); | |
} | |
for (int i = 0; i < 10; ++i) { | |
std::cout << stack.pop() << " " << stack.size() << std::endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment