Here I have C++ code to implement a stack push() and pop() using a linked list. I delete / pop() one data and it works fine, but I want to pop()/ delete many data items. Assume the data is 6 5 4 3 2 1, and I want to delete 6 5 4 3, what can I do to achieve this?
#include <iostream>
using namespace std;
//Structure of the Node
struct Node
{
int data;
Node *next;
};
// top pointer to keep track of the top of the stack
Node *top = NULL;
//Function to check if stack is empty or not
bool isempty()
{
if (top == NULL){
return true;
} else {
}
return false;
}
void pushStack(int value){
Node *ptr = new Node();
ptr->data = value;
ptr->next = top;
top = ptr;
}
//Function to delete an element from the stack
void pop ( )
{
if ( isempty() )
cout << "Stack is Empty";
else
{
Node *ptr = top;
top = top->next;
delete(ptr);
}
}
// Function to Display the stack
void displayStack()
{
if ( isempty() )
cout << "Stack is Empty";
else
{
Node *temp = top;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
cout << "\n";
}
}
int main()
{
pushStack(1);
pushStack(2);
pushStack(3);
pushStack(4);
pushStack(5);
pushStack(6);
pop();
displayStack();
return 0;
}
You have 6 items pushed on the stack, and you are asking to remove the last 4 items that were pushed. Simply call pop() 4 times, eg:
int main()
{
pushStack(1);
pushStack(2);
pushStack(3);
pushStack(4);
pushStack(5);
pushStack(6);
displayStack(); // displays "6 5 4 3 2 1"
pop();
pop();
pop();
pop();
displayStack(); // displays "2 1"
return 0;
}
Online Demo
UPDATE:
In comments, you are asking how to remove specific nodes from the middle of the stack. While that is easy to accomplish with a linked list, that is not how a stack is meant to operate. A stack is a First-In-Last-Out (FILO) container, meaning the first value pushed is the last value popped. So, you should only be pushing and popping values from the top of the stack, nowhere else.
But, if you really want to do this, it would look something like this:
#include <iostream>
using namespace std;
//Structure of the Node
struct Node
{
int data;
Node *next;
};
// top pointer to keep track of the top of the stack
Node *top = NULL;
//Function to check if stack is empty or not
bool isEmpty()
{
return (top == NULL);
}
//Function to add an element to the top of the stack
void pushStack(int value){
Node *ptr = new Node();
ptr->data = value;
ptr->next = top;
top = ptr;
}
//Function to delete the top element from the stack
void pop()
{
if ( isEmpty() )
cout << "Stack is Empty\n";
else
{
Node *ptr = top;
top = top->next;
delete ptr;
}
}
void removeValue(int value)
{
if ( isEmpty() )
cout << "Stack is Empty\n";
else
{
Node *temp = top, **ptr = ⊤
while (temp != NULL)
{
if (temp->data == value)
{
*ptr = temp->next;
delete temp;
return;
}
ptr = &(temp->next);
temp = temp->next;
}
cout << "Value not found\n";
}
}
// Function to display the stack
void displayStack()
{
if ( isEmpty() )
cout << "Stack is Empty\n";
else
{
Node *temp = top;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
cout << "\n";
}
}
int main()
{
pushStack(1);
pushStack(2);
pushStack(3);
pushStack(4);
pushStack(5);
pushStack(6);
displayStack(); // displays "6 5 4 3 2 1"
removeValue(4);
removeValue(5);
displayStack(); // displays "6 3 2 1"
return 0;
}
Online Demo
Related
This is the interface file
#ifndef STACK_H
#define STACH_H
#include<iostream>
using namespace std;
class Stack
{
struct StackFrame{
char data;
StackFrame* next;
};
StackFrame* head;
public:
Stack();
void push(char);
char pop();
void empty();
bool check_empty();
void print();
//Note:This code prints the data in stack format !!!
~Stack();
};
#endif // !STACK_H
This is the implementation file
#include "Stack.h"
Stack::Stack():head(nullptr){}
void Stack::push(char c)
{
StackFrame* temp = new StackFrame;
temp->data = c;
temp->next = nullptr;
if (head == nullptr)
{
head = temp;
return;
}
temp->next = head;
head = temp;
}
char Stack::pop()
{
if (head == nullptr)
{
cerr << "There is nothing in the stack to pop at the moment!!!" << endl;
return '\0';
}
StackFrame* holder = head;
char temp_chr = holder->data;
head = head->next;
free(holder);
holder = nullptr;
return temp_chr;
}
void Stack::empty()
{
StackFrame* holder;
while(head!=nullptr)
{
holder = head;
head = head->next;
free(holder);
}
holder = nullptr;
head = nullptr;
}
bool Stack::check_empty()
{
return head==nullptr;
}
void Stack::print() {
if (head == nullptr)
{
cerr << "Nothing in stack at the moment :( " << endl;
return;
}
StackFrame* holder = head;
while (holder != nullptr)
{
cout << holder->data;
holder = holder->next;
}
cout << endl;
}
Stack::~Stack()
{
empty();
}
This is the application file
#include"Stack.h"
#include<string>
int main()
{
int num;
string push;
Stack st;
cout << "Enter your name = ";
getline(cin, push);
for (int i = 0; i < push.length(); i++)
{
st.push(push[i]);
}
st.print();
cout << "How many times do you want to pop? = ";
cin >> num;
for (int i = 0; i < num; i++)
{
st.pop();
}
st.print();
return EXIT_SUCCESS;
}
Can someone help me out on how to reverse iterate in this stack class which i made myself using the concept of linked list, i googled a bit and got the gist of things to use tail , Can someone elaborate another way if possible please or share a link to a site. It will help me out later a lot when i start working on binary trees and if i ever need to reverse iterate in the binary tree nodes.
First of all as mentioned above, stack is LIFO data structure and thus should use another data structure for that purpose.
Second, you can use second stack and copy data over to new stack, which is expensive.
Third option would be to go from the top and kip a track and store pointer to the previous node and to the pointer that point to the previous of previous node. Something like this:
struct reverseStack {
StackFrame* node;
reverseStack* previousPointer;
reverseStack (StackFrame* n, ReverseStack* p) :
node (n), previousPointer(p) { }
}
than using simple for loop you create pointer to the top, and go to the next and store that info into this structure. In your code you have something like this:
reverseStack top (nullptr, topFrame);
StackFrame currentFrame = top->next();
ReverseStack current; = top;
while (currentFrame != nullptr) {
// alghoritm for linking previous nodes.
}
I think you should add a second Stack object rather than a second list.
Recursive algorithm would have worked fine (use the recursive call stack as your "reverse" stack).
void Stack::print(StackFrame *pCurr) {
if (pCurr != nullptr)
{
print(pCurr->Next);
cout << pCurr->ch;
}
}
void Stack::print() {
if (head == nullptr)
{
cerr << "Nothing in stack at the moment :( " << endl;
return;
}
print(head);
cout << endl;
}
I have implemented a stack by linked list as you can see below, but I can't get a max size to work. I want the stack to hold a maximum of 20 items and also display when the stack is full.
#include <iostream>
using namespace std;
struct Node
{
int data;
Node *link;
};
Node *top = NULL;
bool isempty()
{
if(top == NULL)
return true; else
return false;
}
void push (int value)
{
Node *ptr = new Node();
ptr->data = value;
ptr->link = top;
top = ptr;
}
void pop ( )
{
if ( isempty() )
cout<<"Stack is Empty";
else
{
cout << "pop element" << endl;
Node *ptr = top;
top = top -> link;
delete(ptr);
}
}
void showTop()
{
if ( isempty() )
cout<<"Stack is Empty";
else
cout<<"Element at top is : "<< top->data << endl;
}
void displayStack()
{
//print stack
if ( isempty() )
cout<<"Stack is Empty" << endl;
else
{
cout << "Stack: " << endl;
Node *temp=top;
while(temp!=NULL)
{ cout<<temp->data<<" ";
temp=temp->link;
}
cout<<"\n";
}
}
I would like to have a function like my isEmpty() but isFull() to display the stack is full when 20 items are in the stack. I have not included my main function in the above snippet as I just call my functions.
Thanks for all suggestions much appreciated :) I'm fairly knew to c++ so take it easy.
You essentially want to wrap things up in a class that has a size variable.
struct Stack
{
struct Node
{
int data;
Node * link;
};
Node * top = NULL;
size_t size = 0U;
void push(int val)
{
// stuff you already have
++size;
}
void pop()
{
// stuff you already have
--size;
}
// other methods you have
};
Node doesn't know about how many are in the list, so you need to use Node as a building block, not the structure itself.
So I would use some sort of struct with a pointer to the head node and a value to capture the maximum size of the stack. When you push onto the stack you need to increment that value and check to ensure it has not exceeded the maximum stack size prior to pushing. Also, peek is usually the accepted function name for showTop().
Truth be told, this is an assignment that I'm trying to complete. The basic thing that we have to do is create a Stack and Queue without STL and then create Stack and Queue with STL. I pretty much finished up creating my custom Stack, and it works perfectly. However, with Queue, whenever I try to shift strings into it and print it out, the console will only print out the string that was the last to be shifted. On top of that, whenever I try to unshift the last thing entered into the Queue with the code that I have, I end up getting a read access violation, that of which I am completely stumped on resolving.
If you don't mind, can you look through my code and help me understand what I did that is causing this error and the last entry in my Queue to be the only one printed out? Thanks in advance.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
struct Node {
//create a node struct
string data;
Node *next;
};
class Stack {
public:
Stack();
~Stack();
void push(string a);
string pop();
string toString();
bool isEmpty();
private:
Node * top;
};
class Queue {
public:
Queue();
~Queue();
void shift(string a);
string unshift();
string toString();
bool isEmpty();
private:
Node * top;
Node * bottom;
int count;
};
Stack::Stack() {
//initializes stack to be empty
top = NULL;
}
Queue::Queue() {
//initializes stack to be empty
top = NULL;
}
Stack::~Stack() {
//deconstructor to delete all of the dynamic variable
if (top == NULL) {
cout << "Nothing to clean up" << endl;
}
else {
cout << "Should be deleting..." << endl;
}
}
Queue::~Queue() {
//deconstructor to delete all of the dynamic variable
if (bottom == NULL) {
cout << "Nothing to clean up" << endl;
}
else {
cout << "Should be deleting..." << endl;
}
}
void Stack::push(string a) {
//Need a new node to store d in
Node *temp = new Node;
temp->data = a;
temp->next = top;//point the new node's next to the old top of the stack
top = temp;//point top to the new top of the stack
}
void Queue::shift(string a) {
//Need a new node to store d in
Node *temp = new Node;
temp->data = a;
temp->next = NULL;//point the new node's next to the old top of the stack
if (isEmpty()) {
top = temp;
}
else {
top->next = temp;
count++;
}
top = temp;//point top to the new top of the stack
}
string Stack::pop() {
if (!isEmpty()) {
string value = top->data;
Node *oldtop = top;
top = oldtop->next;
delete oldtop;
return value;
}
else {
cout << "You can't pop from an empty stack!" << endl;
exit(1);
}
}
string Queue::unshift() {
if (isEmpty()) {
cout << "You can't unshift an empty Queue!" << endl;
exit(1);
}
else{
Node *oldbot = top;
if (top == bottom) {
top = NULL;
bottom = NULL;
}
else {
string value = top->data;
}
delete oldbot;
count--;
}
}
string Stack::toString() {
string result = "top ->";
if (isEmpty()) {
result = result + "NULL";
return result;
}
else {
Node *current = top;
while (current != NULL) {
result = result + current->data + "->";
current = current->next;
}
result = result + "(END)";
return result;
}
}
string Queue::toString() {
string result = "top ->";
if (isEmpty()) {
result = result + "NULL";
return result;
}
else {
Node *current =top;
while (current != NULL) {
result = result + current->data + "->";
current = current->next;
}
result = result + "(END)";
return result;
}
}
bool Stack::isEmpty() {
return(top == NULL);
}
bool Queue::isEmpty() {
return(top == NULL);
}
int main()
{
Stack *s = new Stack();
cout << "Output when empty: " << endl << s->toString() << endl;
s->push("Cheeseburger");
s->push("Pizza");
s->push("Large coffee");
s->pop();
cout << "Output when not empty: " << endl << s->toString() << endl;
delete s;
cin.get();
Queue *b = new Queue();
cout << "Output when empty: " << endl << b->toString() << endl;
b->shift("Cheeseburger");
b->shift("Pizza");
b->shift("Large coffee");
cout << "Output when not empty: " << endl << b->toString() << endl;
b->unshift();
delete b;
cin.get();
}
You have to comment below statement in Queue::shift method -
top = temp;
I keep getting a Segmentation fault (core dumped) error every time I try to run my code with g++ on Linux. It compiles fine, but then that happens ... All the functions (remove, add and print) seem to have the same problem, I can't seem to figure out what's wrong... Please heeeelppp.
#include <iostream>
#include <string>
using namespace std;
//Create a node struct
struct Node {
int data;
Node *next;
Node *prev;
};
class Queue {
private:
Node *head;
Node *tail;
int size;
public:
Queue();
~Queue();
void add(int d);
int remove();
bool isEmpty();
void printQueue(bool o);
};
//set to NULL
Queue::Queue() {
head = tail = NULL;
size = 0;
}
//destructor
//call remove until empty
Queue::~Queue() {
while (!isEmpty())
remove();
}
//adds a node with the given data at the back of the queue
void Queue::add(int d) {
Node *temp = new Node();
temp->data = d;
temp->next = NULL;
if (isEmpty()) {
//add to head
head = temp;
} else {
//append
tail->next = temp;
tail = temp;
cout << "Added: " << tail->data << endl;
}
size++;
}
//removes the node at the head of the queue and returns its data
int Queue::remove() {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *temp = new Node;
temp = head;
int value = head->data;
//moves pointer to next node
head = head->next;
cout << "Removed: " << head->data << endl;
size--;
delete temp;
return value;
}
}
//determines if the queue is empty
bool Queue::isEmpty() {
return (size == 0);
}
//prints the contents of the queue from front to back, or front
//to back, depending on the value of the parameter
void Queue::printQueue(bool o) {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *p = new Node;
if (o == true) {
cout << "Printing in front to back:" << endl;
//print front to back
while(p != NULL) {
p = head;
cout << p->data << " ";
p = p->next;
}
} else if (o == false) {
cout << "Printing in back to front:" << endl;
//print back to front
while (p != NULL) {
p = tail;
cout << p->data << " ";
p = p->prev;
}
}
}
}
int main() {
Queue q;
q.add(8);
return 0;
}
EDIT: I've made some changes to the code... But I'm still getting the same error. I assume I'm not updating the head and the tail and/or the next and prev nodes correctly... I don't know why it's wrong or what I'm missing, though.
#include <iostream>
#include <string>
using namespace std;
struct Node {
int data;
Node *next;
Node *prev;
};
class Queue {
private:
Node *head;
Node *tail;
int size;
public:
Queue();
~Queue();
void add(int d);
int remove();
bool isEmpty();
void printQueue(bool o);
};
Queue::Queue() {
head = tail = NULL;
size = 0;
}
Queue::~Queue() {
while (!isEmpty())
remove();
}
void Queue::add(int d) {
Node *temp = new Node;
temp->data = d;
temp->next = NULL;
temp->prev = tail;
if (isEmpty()) {
//add to head
head = temp;
} else {
//append
tail->next = temp;
tail = temp;
cout << "Added: " << tail->data << endl;
}
size++;
}
int Queue::remove() {
if (isEmpty()) {
cout << "The queue is empty." << endl;
return 0;
} else {
Node *temp = head;
int value = head->data;
cout << "Removed: " << head->data << endl;
//moves pointer to next node
head = head->next;
head->prev = NULL;
size--;
delete temp;
return value;
}
}
bool Queue::isEmpty() {
return (size == 0);
}
void Queue::printQueue(bool o) {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *p;
if (o == true) {
p = head;
cout << "Printing in front to back:" << endl;
//print front to back
while(p != NULL) {
cout << p->data << " ";
p = p->next;
}
} else if (o == false) {
p = tail;
cout << "Printing in back to front:" << endl;
//print back to front
while (p != NULL) {
cout << p->data << " ";
p = p->prev;
}
}
}
}
int main() {
Queue q;
q.add(9);
q.add(10);
q.add(11);
q.add(12);
q.add(13);
q.add(14);
q.add(15);
q.add(16);
q.remove();
q.remove();
q.printQueue(true);
q.printQueue(false);
return 0;
}
Lots of problems:
You have a double-linked Node but never update its prev member in the add/remove methods.
You are keeping track of both the Queue head/tail but don't properly update them when you add/remove nodes.
Both your forward and reverse loops in printQueue() are wrong and result in an infinite loop for any queue with 2 or more elements. Queue output should be just something like:
Node *p = head;
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
Possible null pointer deference in remove() at cout << "Removed: " << head->data << endl; since you've already moved the head pointer by this time. Move the head after the cout.
Memory leak in Queue::remove() at Node *temp = new Node;. Just do Node* temp = head;.
Memory leak in Queue::printQueue() at Node *p = new Node;. You don't need to allocate a node here.
No return value in remove() for an empty queue.
Edit
Don't forget to initialize the tail when adding a node to an empty list:
if (isEmpty()) {
head = temp;
tail = temp;
}
To remove a node from the head of a non-empty list it should be something like:
Node *temp = head;
head = head->next;
if (head) head->prev = NULL;
size--;
delete temp;
if (isEmpty()) tail = NULL;
I'm getting a Segmentation Fault - Core Dump during runtime.
I'm trying to figure out how to get rid of the Segmentation Fault.
It's a class homework.
EDIT: Added Input and Output below.
//client.cpp
#include <iostream>
#include "stack.h"
using namespace std;
int main(void){
stack unsorted;
stack stack1;
stack stack2;
stack stack3;
int const MAX_VALUES = 5;
int input;
cout << "Please input "<< MAX_VALUES << " unique integers.\n";
cout << "Click the ENTER key after each integer inputted." <<endl;
for (int i = 0; i < MAX_VALUES; i++)
{
cin >> input;
stack1.Push(input);
unsorted.Push(input);
}
cout << "Unsorted Stack: " <<endl;
for (int i = 0; i < MAX_VALUES; i++)
{
cout<<unsorted.Pop()<<endl;
}
cout << "Sorted Stack: "<<endl;
while((!stack1.IsEmpty())&&(!stack3.IsEmpty())){
if ((stack1.IsEmpty())&&(!stack3.IsEmpty()))
{
stack2.Push(stack3.Pop());
}
if (stack2.Top() > stack1.Top())
{
stack3.Push(stack2.Pop());
}
if (stack3.Top() < stack1.Top())
{
stack2.Push(stack3.Pop());
}
else
{
stack2.Push(stack1.Pop());
}
}
while (!stack2.IsEmpty()){
cout << stack2.Pop() << endl;
}
}
//stack.h
#include <cstddef>
struct node;
class stack
{
public:
stack();
~stack();
bool IsFull();
bool IsEmpty();
void Push(int input);
int Pop();
int Top();
private:
node* top;
int const MAX_VALUES = 5;
int count;
};
//stack.cpp
#include "stack.h"
struct node
{
int input;
node* next;
};
stack::stack()
{
top = NULL;
count = 0;
}
bool stack::IsFull()
{
if (MAX_VALUES > count)
{
return false;
}
return true;
}
bool stack::IsEmpty(){
if (top == NULL){
return true;
}
else{
return false;
}
}
void stack::Push(int num)
{
if(IsFull() == false)
{
node* newNode = new node;
newNode->input = num;
newNode->next = top;
top = newNode;
count ++;
}
}
int stack::Top()
{
int topval;
topval = top->input;
return topval;
}
int stack::Pop()
{
int Popped;
if (top != NULL)
{
node* temp = top;
top = top->next;
Popped = temp->input;
delete temp;
return Popped;
}
count--;
}
stack::~stack()
{
node* current = top;
while( top != NULL)
{
node* next = current->next;
delete current;
current = next;
}
top = NULL;
}
Input:
Please input 5 unique integers.
Click the ENTER key after each integer inputted.
7
1
56
67
8
Output:
Unsorted Stack:
8
67
56
1
7
Sorted Stack:
Segmentation fault (core dumped)
There are several problems.
First, your Pop:
int stack::Pop()
{
int Popped;
if (top != NULL)
{
node* temp = top;
top = top->next;
Popped = temp->input;
delete temp;
return Popped;
}
count--;
}
which decrements count only when the stack is empty, but doesn't return anything if it is.
You need something more like this:
int stack::Pop()
{
int Popped = -1; // Make sure the return value is well-defined
if (!IsEmpty())
{
node* temp = top;
top = top->next;
Popped = temp->input;
delete temp;
count--; // Only decrement if we actually popped something.
}
return Popped;
}
and the destructor:
stack::~stack()
{
node* current = top;
while( top != NULL)
{
node* next = current->next;
delete current;
current = next;
}
top = NULL;
}
The loop will never stop because you have the wrong termination condition - unless the stack is empty, top will never become NULL.
It should be
stack::~stack()
{
node* current = top;
while (current != NULL)
{
node* next = current->next;
delete current;
current = next;
}
top = NULL;
}
And the loop in main starts like this (I've removed some unnecessary parentheses):
while (!stack1.IsEmpty() && !stack3.IsEmpty()) {
if (stack1.IsEmpty() && !stack3.IsEmpty())
where the if condition will never be true if the while condition is - stack1 can't be both empty and not empty.
Side note: having a size limit when you implement a stack as a linked list is a bit odd.