Stack¶
Code for Stack Clone¶
#include <iostream>
#include <string>
using namespace std;
// Node class for the linked list
template <typename T>
class Node {
public:
T data;
Node* next;
Node(T value) : data(value), next(nullptr) {}
};
// Stack class
template <typename T>
class Stack {
private:
Node<T>* top_node;
public:
Stack() : top_node(nullptr) {}
// Push: Adds an element to the top of the stack
void push(T value) {
Node<T>* new_node = new Node<T>(value);
new_node->next = top_node;
top_node = new_node;
std::cout << value << " pushed to stack." << std::endl;
}
// Pop: Removes the top element from the stack
void pop() {
if (isEmpty()) {
std::cout << "Stack Underflow! Cannot pop from an empty stack." << std::endl;
return;
}
Node<T>* temp = top_node;
top_node = top_node->next;
std::cout << temp->data << " popped from stack." << std::endl;
delete temp; // Free memory
}
// Peek: Returns the top element without removing it
T peek() {
if (isEmpty()) {
std::cout << "Stack is empty. Cannot peek." << std::endl;
// You may want to throw an exception here in a real application
return T(); // Return a default value
}
return top_node->data;
}
// IsEmpty: Checks if the stack is empty
bool isEmpty() {
return top_node == nullptr;
}
// Destructor to free memory
~Stack() {
while (!isEmpty()) {
pop();
}
}
};
int main() {
Stack<int> int_stack;
std::cout << "Is stack empty? " << (int_stack.isEmpty() ? "Yes" : "No") << std::endl;
int_stack.push(10);
int_stack.push(20);
int_stack.push(30);
std::cout << "Top element is: " << int_stack.peek() << std::endl;
int_stack.pop();
std::cout << "Top element after pop is: " << int_stack.peek() << std::endl;
int_stack.pop();
int_stack.pop();
int_stack.pop(); // This will trigger the underflow message
std::cout << "Is stack empty? " << (int_stack.isEmpty() ? "Yes" : "No") << std::endl;
// Kaleb's Test code
Stack<string> nameStack;
std::cout << "Is stack empty? " << (nameStack.isEmpty() ? "Yes" : "No") << std::endl;
nameStack.push("Fletcher");
nameStack.push("Valerie");
nameStack.push("Alanna");
nameStack.push("Lucio");
nameStack.push("Tucker");
nameStack.push("Medina");
nameStack.push("Mai");
nameStack.push("Kerri");
std::cout << "Is stack empty? " << (nameStack.isEmpty() ? "Yes" : "No") << std::endl;
std::cout << "Top element is: " << nameStack.peek() << std::endl;
nameStack.pop();
nameStack.pop();
nameStack.pop();
std::cout << "Top element after pop is: " << nameStack.peek() << std::endl;
nameStack.pop();
nameStack.pop();
std::cout << "Top element after pop is: " << nameStack.peek() << std::endl;
nameStack.~Stack();
std::cout << "Is stack empty? " << (nameStack.isEmpty() ? "Yes" : "No") << std::endl;
std::cout << "Top element is: " << nameStack.peek() << std::endl;
nameStack.push("Mitchell");
nameStack.push("Nikola");
nameStack.push("Chance");
std::cout << "Is stack empty? " << (nameStack.isEmpty() ? "Yes" : "No") << std::endl;
std::cout << "Top element is: " << nameStack.peek() << std::endl;
nameStack.pop();
nameStack.pop();
std::cout << "Is stack empty? " << (nameStack.isEmpty() ? "Yes" : "No") << std::endl;
std::cout << "Top element is: " << nameStack.peek() << std::endl;
nameStack.pop();
nameStack.pop();
nameStack.pop();
std::cout << "Is stack empty? " << (nameStack.isEmpty() ? "Yes" : "No") << std::endl;
std::cout << "Top element is: " << nameStack.peek() << std::endl;
return 0;
}
Journaling¶
The stack seems to work similarly to a linked list, but you can only access the most recently added element. You can either add an element to the top of the stack by using the push() method, or remove the top element from the stack by using the pop() method. This is called a “Last in First out” method and it can be useful for undo/redo systems as it allows the computer to store data in a set order while only needing to use the most recent data.