Stack and Queue
Stack and Queue
Stack ADT
Basic operations of stack
Pushing, popping etc.
Implementations of stacks using
array
linked list
The Stack ADT
top
B
top top
A A A
top
Push (ItemType newItem)
double Stack::Top() {
if (IsEmpty()) {
cout << "Error: the stack is empty." << endl;
return -1;
}
else
return values[top];
}
Printing all the elements
void DisplayStack()
Print all the elements
void Stack::DisplayStack() {
cout << "top -->";
for (int i = top; i >= 0; i--)
cout << "\t|\t" << values[i] << "\t|" << endl;
cout << "\t|---------------|" << endl;
}
Using Stack
result
int main(void) {
Stack stack(5);
stack.Push(5.0);
stack.Push(6.5);
stack.Push(-3.0);
stack.Push(-8.0);
stack.DisplayStack();
cout << "Top: " << stack.Top() << endl;
stack.Pop();
cout << "Top: " << stack.Top() << endl;
while (!stack.IsEmpty()) stack.Pop();
stack.DisplayStack();
return 0;
}
Implementation based on Linked List
Now let us implement a stack based on a
linked list
To make the best out of the code of List, we
implement Stack by inheriting List
To let Stack access private member head, we
make Stack as a friend of List
class List {
public:
List(void) { head = NULL; } // constructor
~List(void); // destructor
bool IsEmpty() { return head == NULL; }
Node* InsertNode(int index, double x);
int FindNode(double x);
int DeleteNode(double x);
void DisplayList(void);
private:
Node* head;
friend class Stack;
};
Implementation based on Linked List
class Stack : public List {
public:
Stack() {} // constructor
~Stack() {} // destructor
double Top() {
if (head == NULL) {
cout << "Error: the stack is empty." << endl;
return -1;
}
else
return head->data;
}
void Push(const double x) { InsertNode(0, x); }
double Pop() {
if (head == NULL) {
cout << "Error: the stack is empty." << endl;
return -1;
}
else {
double val = head->data;
DeleteNode(val); Note: the stack
return val;
} implementation
} based on a linked
void DisplayStack() { DisplayList(); }
}; list will never be full.
Balancing Symbols
To check that every right brace, bracket, and
parentheses must correspond to its left counterpart
e.g. [( )] is legal, but [( ] ) is illegal
Algorithm
(1) Make an empty stack.
(2) Read characters until end of file
i. If the character is an opening symbol, push it onto the stack
ii. If it is a closing symbol, then if the stack is empty, report an error
iii. Otherwise, pop the stack. If the symbol popped is not the
corresponding opening symbol, then report an error
(3) At end of file, if the stack is not empty, report an error
Postfix Expressions
Calculate 4.99 * 1.06 + 5.99 + 6.99 * 1.06
Need to know the precedence rules
Postfix (reverse Polish) expression
4.99 1.06 * 5.99 + 6.99 1.06 * +
Use stack to evaluate postfix expressions
When a number is seen, it is pushed onto the stack
When an operator is seen, the operator is applied to the 2
numbers that are popped from the stack. The result is pushed
onto the stack
Example
evaluate 6 5 2 3 + 8 * + 3 + *
The time to evaluate a postfix expression is O(N)
processing each element in the input consists of stack
operations and thus takes constant time
Queue Overview
Queue ADT
Basic operations of queue
Enqueuing, dequeuing etc.
Implementation of queue
Array
Linked list
Queue ADT
Like a stack, a queue is also a list. However,
with a queue, insertion is done at one end,
while deletion is performed at the other end.
Accessing the elements of queues follows a
First In, First Out (FIFO) order.
Like customers standing in a check-out line in a
store, the first customer in is the first customer
served.
The Queue ADT
Another form of restricted list
Insertion is done at one end, whereas deletion is
performed at the other end
Basic operations:
enqueue: insert an element at the rear of the list
dequeue: delete the element at the front of the list
Remove Insert
(Dequeue) front rear (Enqueue)
Implementation of Queue
3 3 6 3 6 9
6 9 9
void Queue::DisplayQueue() {
cout << "front -->";
for (int i = 0; i < counter; i++) {
if (i == 0) cout << "\t";
else cout << "\t\t";
cout << values[(front + i) % maxSize];
if (i != counter - 1)
cout << endl;
else
cout << "\t<-- rear" << endl;
}
}
Using Queue
int main(void) {
Queue queue(5);
cout << "Enqueue 5 items." << endl;
for (int x = 0; x < 5; x++)
queue.Enqueue(x);
cout << "Now attempting to enqueue again..." << endl;
queue.Enqueue(5);
queue.DisplayQueue();
double value;
queue.Dequeue(value);
cout << "Retrieved element = " << value << endl;
queue.DisplayQueue();
queue.Enqueue(7);
queue.DisplayQueue();
return 0;
}
Stack Implementation based on Linked
class Queue { List
public:
Queue() { // constructor
front = rear = NULL;
counter = 0;
}
~Queue() { // destructor
double value;
while (!IsEmpty()) Dequeue(value);
}
bool IsEmpty() {
if (counter) return false;
else return true;
}
void Enqueue(double x);
bool Dequeue(double & x);
void DisplayQueue(void);
private:
Node* front; // pointer to front node
Node* rear; // pointer to last node
int counter; // number of elements
};
Enqueue
void Queue::Enqueue(double x) {
Node* newNode = new Node;
newNode->data = x;
newNode->next = NULL;
if (IsEmpty()) {
front = newNode;
rear = newNode;
} rear
else { 8 5
rear->next = newNode;
rear = newNode;
rear
}
counter++; 8 5
} newNode
Dequeue
bool Queue::Dequeue(double & x) {
if (IsEmpty()) {
cout << "Error: the queue is empty." << endl;
return false;
}
else {
x = front->data;
Node* nextNode = front->next;
delete front;
front = nextNode;
counter--;
} front
}
3 8 5
front
8 5
Printing all the elements
void Queue::DisplayQueue() {
cout << "front -->";
Node* currNode = front;
for (int i = 0; i < counter; i++) {
if (i == 0) cout << "\t";
else cout << "\t\t";
cout << currNode->data;
if (i != counter - 1)
cout << endl;
else
cout << "\t<-- rear" << endl;
currNode = currNode->next;
}
}
Result
Queue implemented using linked list will be
never full