Skip to content

Instantly share code, notes, and snippets.

@willeccles
Last active May 9, 2017 16:33
Show Gist options
  • Save willeccles/11ad20b121355e02373215b8f9ba40c8 to your computer and use it in GitHub Desktop.
Save willeccles/11ad20b121355e02373215b8f9ba40c8 to your computer and use it in GitHub Desktop.
Node-based stack in C++ using C-style pointers vs. C++11 smart pointers.
/**
* This is the right way to do this in C++11+, which is a lot of +'s.
* This uses the std::shared_ptr type to manage memory and access to it magically.
*/
#ifndef STACK_H
#define STACK_H
#include <iostream>
#include <vector>
#include <memory> // std::shared_ptr
template <class T>
class stack {
private:
// the node class to be used in the stack
template <class nT = T>
class node {
private:
nT _value;
std::shared_ptr<node<nT>> _next;
public:
node(nT value): _value(value) { _next = nullptr; };
node(nT value, std::shared_ptr<node<nT>> next): _value(value), _next(next) {};
nT getValue() { return _value; };
void setValue(nT newValue) { _value = newValue; };
std::shared_ptr<node<nT>> getNext() { return _next; };
};
std::shared_ptr<node<T>> _top; // shouldn't change or we lose the list
size_t _numItems = 0;
public:
// constructors
stack() {
_top = nullptr; // set _top to nullptr
};
stack(T firstVal) {
_top = std::make_shared<node<T>>(firstVal);
_numItems = 1;
};
// push a new value to the stack
void push(T val) {
if (_top == nullptr) {
_top = std::make_shared<node<T>>(val);
} else {
std::shared_ptr<node<T>> newNext = _top;
_top = std::make_shared<node<T>>(val, newNext);
}
_numItems++;
};
// pop a value from the stack
T pop() {
if (_top == nullptr) {
return static_cast<T>(NULL);
} else {
std::shared_ptr<node<T>> old = _top;
_top = _top->getNext();
_numItems--;
T rval = old->getValue();
return rval;
}
};
// remove all the items from the stack
void popAll() {
std::shared_ptr<node<T>> curr = _top;
while (curr != nullptr) {
std::shared_ptr<node<T>> next = curr->getNext();
curr = next;
}
_top = nullptr;
_numItems = 0;
}
// peek at the top of the stack
T peek() {
return _top->getValue();
};
// for printing the stack out
void print() {
if (isEmpty()) {
std::cout << "Stack is empty." << std::endl;
} else {
std::shared_ptr<node<T>> curr = _top;
while (curr != nullptr) {
std::cout << curr->getValue() << ' ';
curr = curr->getNext();
}
std::cout << std::endl;
}
}
// if you want to loop through and apply an operation to each value in the stack
void doForEach(T (*op)(T)) {
std::shared_ptr<node<T>> curr = _top;
while (curr != nullptr) {
curr->setValue(op(curr->getValue()));
curr = curr->getNext();
}
};
// getSize and isEmpty are pretty self-explanatory
size_t getSize() { return _numItems; };
bool isEmpty() { return !_numItems; };
// destructor because we like having memory amirite
~stack() {
_top.reset();
};
};
#endif
/**
* This is the old way of doing a node-based stack, with old C-style pointers.
* newstack.h (included) uses the newer C++11 smart pointers.
*/
#ifndef STACK_H
#define STACK_H
#include <iostream>
#include <vector>
template <class T>
class stack {
private:
// the node class to be used in the stack
template <class nT = T>
class node {
private:
nT _value;
node<nT>* _next;
public:
node(nT value): _value(value) { _next = nullptr; };
node(nT value, node<nT>* next): _value(value), _next(next) {};
nT getValue() { return _value; };
void setValue(nT newValue) { _value = newValue; };
node<nT>* getNext() { return _next; };
};
node<T>* _top; // shouldn't change or we lose the list
size_t _numItems = 0;
public:
// constructors
stack() {
_top = nullptr; // set _top to nullptr
};
stack(T firstVal) {
_top = new node<T>(firstVal);
_numItems = 1;
};
// push a new value to the stack
void push(T val) {
if (_top == nullptr) {
_top = new node<T>(val);
} else {
node<T>* newNext = _top;
_top = new node<T>(val, newNext);
}
_numItems++;
};
// pop a value from the stack
T pop() {
if (_top == nullptr) {
return static_cast<T>(NULL);
} else {
node<T>* old = _top;
_top = _top->getNext();
_numItems--;
T rval = old->getValue();
delete old;
return rval;
}
};
// remove all the items from the stack
void popAll() {
node<T>* curr = _top;
while (curr != nullptr) {
node<T>* next = curr->getNext();
curr = next;
}
_top = nullptr;
_numItems = 0;
}
// peek at the top of the stack
T peek() {
return _top->getValue();
};
// for printing the stack out
void print() {
if (isEmpty()) {
std::cout << "Stack is empty." << std::endl;
} else {
node<T>* curr = _top;
while (curr != nullptr) {
std::cout << curr->getValue() << ' ';
curr = curr->getNext();
}
std::cout << std::endl;
}
}
// if you want to loop through and apply an operation to each value in the stack
void doForEach(T (*op)(T)) {
node<T>* curr = _top;
while (curr != nullptr) {
curr->setValue(op(curr->getValue()));
curr = curr->getNext();
}
};
// getSize and isEmpty are pretty self-explanatory
size_t getSize() { return _numItems; };
bool isEmpty() { return !_numItems; };
// destructor because we like having memory amirite
~stack() {
node<T>* curr = _top;
while (curr != nullptr) {
node<T>* next = curr->getNext();
delete curr;
curr = next;
}
delete _top;
};
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment