unit-3-stacks-and-queues
unit-3-stacks-and-queues
Stacks
A stack is a linear data structure that can be accessed only at one of its ends for storing and retrieving
data. Such a stack resembles piles of trays in a cafeteria. New trays are put on the top of the pile and top
tray is the first tray removed from the stack. For this reason, a stack is called an LIFO structure: last in
/first out.
The operations on stack are as follows:
Clear (): Clear the stack
isEmpty() : Check to see if the stack is empty.
Push (el): Put the element el on the top of stack.
Pop(): Take the topmost element from the stack.
topEl() : Return the topmost element in the stack without removing it.
Stack can be implemented in two ways:
Array Implementation of stack
Algorithm for stack implementation using arrays
This algorithm pushes an ITEM into a stack; MAXSTK is the maximum size of the stack.
1. Is Stack full? If TOP = MAXSTK then PRINT “Overflow” and return.
2. Set TOP = TOP+1
3. Set STACK [TOP] = ITEM.
4. Return
Algorithm for stack implementation using arrays
This algorithm pushes an ITEM into a stack; MAXSTK is the maximum size of the stack.
1. If TOP =0 then PRINT “Underflow” and return.
2. Set ITEM = STACK[TOP].
3. Set TOP = TOP-1.
4. Return
The stack can be implemented in Java using array
class Stack{
private char[] data;
private int tos;
public Stack(){}
public Stack(int size){
data = new char[size];
tos = 0;
}
public void push(char ch){
if(isFull()){
System.out.println("--------Stack is Full------");
return;
}
data[tos++] = ch;
1
}
public char pop(){
if(isEmpty()){
System.out.println("-----The stack is empty---------");
return(char) 0;
}
return data[--tos];
}
public boolean isFull(){
return tos ==data.length;
}
public boolean isEmpty(){
return tos==0;
}
}
public class StackDemo {
public static void main(String[] args) {
Stack s = new Stack(30);
for(int i=0;i<26;i++)
s.push((char)('A'+i));
System.out.println("Popping Data Items from the stack");
while(!s.isEmpty())
System.out.print(s.pop()+ " ");
}
}
The output of the above program is:
Popping Data Items from the stack
Z->Y->X->W->V->U->T->S->R->Q->P->O->N->M->L->K->J->I->H->G->F->E->D->C->B->A->
2
public Node(int d){
data = d;
next = null;
}
}
The stack can be implemented in using linked list as follows:
class Node{
protected int data;
protected Node next;
public Node(){
next = null;
data = 0;
}
public Node(int d){
data = d;
next = null;
}
}
class linkedStack{
protected Node top ;
protected int size ;
public linkedStack(){
top = null;
size = 0;
}
public boolean isEmpty(){
return top == null;
}
public int getSize(){
return size;
}
public void push(int data){
Node ptr = new Node (data);
if (top == null)
top = ptr;
else
{
ptr.next = top;
top = ptr;
}
size++ ;
}
3
public int pop()
{
if (isEmpty() )
return 0;
Node ptr = top;
top = ptr.next;
size-- ;
return ptr.data;
}
4
ls.display();
System.out.println("The size of linked list is "+ls.getSize());
}
}
class ArrayQueue {
private int capacity;
5
int queueArr[];
int front;
int rear;
int currentSize;
public ArrayQueue(int queueSize){
this.capacity = queueSize;
queueArr = new int[this.capacity];
front =0;
rear = -1;
currentSize = 0;
}
public boolean isQueueFull(){
return currentSize==capacity;
}
public boolean isQueueEmpty(){
return currentSize==0;
}
public void enqueue(int item) {
if (isQueueFull()) {
System.out.println("Overflow ! Unable to add element: "+item);
} else {
rear++;
if(rear == capacity-1){
rear = 0;
}
queueArr[rear] = item;
currentSize++;
System.out.println("Element " + item+ " is added to Queue !");
}
}
public void dequeue() {
if (isQueueEmpty()) {
System.out.println("Underflow ! Unable to remove element from Queue");
} else {
front++;
if(front == capacity-1){
System.out.println("Deletion operation done ! removed: "+queueArr[front-1]);
front = 0;
}
else {
System.out.println("Deletion operation done ! removed: "+queueArr[front-1]);
}
6
currentSize--;
}
}
public static void main(String a[]){
ArrayQueue queue = new ArrayQueue(4);
queue.enqueue(4);
queue.dequeue();
queue.enqueue(56);
queue.enqueue(2);
queue.enqueue(67);
queue.dequeue();
queue.dequeue();
queue.enqueue(24);
queue.dequeue();
queue.enqueue(98);
queue.enqueue(45);
queue.enqueue(23);
queue.enqueue(435);
}
}
The output of the above program is:
Element 4 is added to Queue!
Deletion operation done ! removed: 4
Element 56 is added to Queue!
Element 2 is added to Queue!
Element 67 is added to Queue!
Deletion operation done! removed: 56
Deletion operation done! removed: 2
Element 24 is added to Queue!
Deletion operation done! removed: 67
Element 98 is added to Queue!
Element 45 is added to Queue!
Element 23 is added to Queue!
Overflow! Unable to add element: 435
7
protected int data;
protected Node next;
public Node(){
next = null;
data = 0;
}
public Node(int d){
data = d;
next = null;
}
}
The following program uses linked list to implement queue in java
class QNode
{
public int info;
public QNode next;
public QNode(){
info = 0;
next = null;
}
public QNode(int el){
info = el;
next = null;
}
}
class Queue
{
private QNode front;
private QNode rear;
public Queue(){
front = null;
rear = null;
}
public boolean isEmpty(){
return front==null;
}
public void enqueue(int el){
QNode temp = new QNode(el);
if(rear==null)
{
rear = temp;
front = rear;
8
}
else
{
rear.next = temp;
rear = temp;
}
}
public void dequeue()
{
QNode temp;
if(front==null){
System.out.println("Queue is empty");
front = rear = null;
}
else
{
front = front.next;
}
}
public void display()
{
QNode temp;
for(temp=front;temp!=rear;temp = temp.next)
System.out.print(temp.info+ "-");
System.out.print(temp.info);
}
}
public class LinkedListQueue {
public static void main(String[] args) {
Queue q = new Queue();
q.enqueue(10);
q.enqueue(20);
q.enqueue(30);
q.enqueue(40);
q.enqueue(50);
q.enqueue(60);
System.out.println("Queue before deletion");
q.display();
System.out.println("\nQueue after deletion");
q.dequeue();
q.display();
}
9
}
The output of the above program is:
Queue before deletion
10-20-30-40-50-60
Queue after deletion
20-30-40-50-60
Priority Queues
In many situations, simple queues are inadequate, as when first in /first out scheduling has to be
overruled using some priority criteria. In a post office example, a handicapped person may have priority
over others. Therefore, when a clear is available, a handicapped person is served instead of someone
from the front of the queue.
In a sequence of processes, process p2 may need to be executed before process p1 for the proper
functioning of the system, even though p1 was put on the queue of waiting processes before p2. In
situations like these, a modified queue or priority queue is needed. In priority queues, elements are
dequeued according to their priority and current position.
The problem with a priority queue is in finding an efficient implementation that allows relatively fast
enquiring. Because elements may arrive randomly to the queue, there is no guarantee that the front
element will be most likely to be dequeued and that the elements put at the end will be the most likely
to be dequeued. The situation is complicated because a wide spectrum of possible priority criteria can
be used in different cases such as frequency of use, birthday, salary, position, status, and others.
Priority queues can be represented by two variations of linked lists. In one type of linked list, all
elements are entry ordered, and in another, order is maintained by putting a new element in its proper
position according to its priority. In both cases, the total operational times are O(n) because, for an
unordered list, adding an element is immediate but searching is O(n), and in a sorted list, taking an
element is immediate but adding an element is O(n).
class PQNode
{
public int info;
public int prt;
public PQNode next;
public PQNode(){
info = 0;
prt = 0;
next = null;
}
public PQNode(int el,int p){
info = el;
prt = p;
}
10
}
class PriorityQueue
{
private PQNode front;
private PQNode rear;
public PriorityQueue(){
front = null;
rear = null;
}
public boolean isEmpty(){
return front == null;
}
public void dequeue(){
if(front==null)
front = rear = null;
else
{
front = front.next;
if(front == null)
rear=null;
}
}
public void display(){
PQNode temp;
for(temp=front;temp!=rear;temp = temp.next)
System.out.print(temp.info+ "-");
System.out.print(temp.info);
}
public void enqueue(int el,int p){
PQNode temp = new PQNode(el,p);
PQNode temp1,temp2;
temp1 =temp2 = front;
if(rear==null){
rear = temp;
front = rear;
}
else if(p<=rear.prt)
{
rear.next = temp;
rear = temp;
}
else if(p>front.prt)
11
{
temp.next = front;
front = temp;
}
else
{
while(temp2.prt>=p){
temp1 = temp2;
temp2 = temp2.next;
if(temp2==null)return;
}
temp1.next = temp;
temp.next = temp2;
if(temp2 == null){
rear.next = temp;
rear = temp;
}
}
}
}
public class PriorityQueueDemo {
public static void main(String[] args) {
PriorityQueue q = new PriorityQueue();
q.enqueue(50, 0);
q.enqueue(40, 1);
q.enqueue(30, 0);
q.enqueue(20, 0);
q.enqueue(10, 0);
q.enqueue(0, 2);
System.out.println("Priority Queue before deletion");
q.display();
q.dequeue();
System.out.println("\nPriority Queue after deletion");
q.display();
}
}
The output of the above program is:
Priority Queue before deletion
0-40-50-30-20-10
Priority Queue after deletion
40-50-30-20-10
12
Exiting a Maze
Consider the problem of a trapped mouse that tries to find its way to an exit in a maze. The mouse
hopes to escape from the maze by systematically trying all the routes. If it reaches a dead end, it
retraces its steps to the last position and begins at least one more untried path. For each position, the
mouse can go in one of four directions: left, right, up, down. Regardless of how close it is to the exit, it
always tries the open paths in this order, which may lead to some unnecessary detours. By retaining
information that allows for resuming the search after a dead end is reached, the mouse uses a method
called backtracking.
The maze is implemented as a two dimensional character array in which passages are marked with 0s
and walls by 1s, exit position by the letter e, and the initial positions of the mouse by the letter m. In this
program, the maze problem is slightly generalized by allowing the exit to be in any position of the maze
and allowing passages to be on the borderline. To protect itself from falling off the array by trying to
continue its path when an open cell is reached on one of the borderlines, the mouse also has to
constantly check whether it is in such a borderline position or not. To avoid it, the program
automatically puts a frame of 1s around the maze entered by the user.
The program uses two stacks: one to initialize the maze and another to implement backtracking.
The user enters a maze one line at a time. The maze entered by the user can have any number of rows
and any number of columns. The only assumption the program makes is that all rows are of the same
length and that it uses only these characters: any number of 1s, any number of 0s, one e, and one m.
The rows are pushed on the stack mazeRows in the order they are entered after attaching one 1 at the
beginning and one 1 at the end. After all rows are entered, the size of the array store can be determined
and then the rows from the stack are transferred to the array.
A second stack, mazeStack, is used in the process of escaping the maze. To remember untried paths for
subsequent tries, the positions of the untried neighbors of the current position (if any) are stored on a
stack and always in the same order, first upper neighbor, then lower, then left, and finally right.
Here is a pseudo code of an algorithm for escaping a maze
exitMaze()
initialize stack, exitCell, entryCell, currentCell = entryCell;
while currentCell isnot exitCell
mark currentCell as visited;
push onto the stack the unvisited neighbours of currentCell;
if stack is empty
failure;
else pop off a cell from the stack and make it currentCell;
success
13