Data Structures C++ II-Unit

Download as pdf or txt
Download as pdf or txt
You are on page 1of 24

UNIT-II

ADT (ABSTRACT DATA TYPE):

 Abstract Data type (ADT) is a type (or class) for objects whose behavior is defined by a set of value and a
set of operations.
 The definition of ADT only mentions what operations are to be performed but not how these operations
will be implemented. It does not specify how data will be organized in memory and what algorithms will
be used for implementing the operations.
 It is called “abstract” because it gives an implementation-independent view. The process of providing only
the essentials and hiding the details is known as abstraction.
 The user of data type does not need to know how that data type is implemented, for example, we have been
using Primitive values like int, float, char data types only with the knowledge that these data type can
operate and be performed on without any idea of how they are implemented. So a user only needs to know
what a data type can do, but not how it will be implemented.
 Think of ADT as a black box which hides the inner structure and design of the data type.
 Consider the following examples of ADTs namely List ADT, Stack ADT, Queue ADT.

List ADT

 A list contains elements of the same type arranged in sequential order and following operations can
be performed on the list.
o get() – Return an element from the list at any given position.
o insert() – Insert an element at any position of the list.
o remove() – Remove the first occurrence of any element from a non-empty list.
o removeAt() – Remove the element at a specified location from a non-empty list.
o replace() – Replace an element at any position by another element.
o size() – Return the number of elements in the list.
o isEmpty() – Return true if the list is empty, otherwise return false.
o isFull() – Return true if the list is full, otherwise return false.

Stack ADT

 A Stack contains elements of the same type arranged in sequential order. All operations take place
at a single end that is top of the stack and following operations can be performed:
o push() – Insert an element at one end of the stack called top.
o pop() – Remove and return the element at the top of the stack, if it is not empty.
o peek() – Return the element at the top of the stack without removing it, if the stack is not
empty.
o size() – Return the number of elements in the stack.
o isEmpty() – Return true if the stack is empty, otherwise return false.
o isFull() – Return true if the stack is full, otherwise return false.

Queue ADT

 A Queue contains elements of the same type arranged in sequential order. Operations take place at
both ends, insertion is done at the end and deletion is done at the front. Following operations can be
performed:
o enqueue() – Insert an element at the end of the queue.
o dequeue() – Remove and return the first element of the queue, if the queue is not empty.
o peek() – Return the element of the queue without removing it, if the queue is not empty.
o size() – Return the number of elements in the queue.
o isEmpty() – Return true if the queue is empty, otherwise return false.
o isFull() – Return true if the queue is full, otherwise return false.

 From these definitions, it is clear that the definitions do not specify how these ADTs will be
represented and how the operations will be carried out.
 There can be different ways to implement an ADT, for example, the List ADT can be implemented
using arrays, or singly linked list or doubly linked list.
 Similarly, stack ADT and Queue ADT can be implemented using arrays or linked lists.

STACK
 A stack is a linear data structure in which insertions (also called additions and pushes) and removals (also
called deletion and pops) take place at the same end. This end is called as the top of the stack.
 The other end is known as bottom of the stack.
 In a stack insertion and deletion of elements will be performed in LIFO fashion (Last In First Out).

Examples for stack:


1) Paper tray of the printer (or copy machine), where the sheets of papers are stacked in the tray. The next
sheet that gets used is always selected from top of the tray. Additional sheets will be added at the top. The
printer tray maintains a stack of papers and it works in a LIFO manner.
2) Plates in canteen are stacked for use. Students in food line picks up a plate from the top the stack. And new
plates to the stack will be added at the top of the stack. Here also the plates stacked work in LIFO manner.

Stack Errors:
Two things can go wrong with stacks:
 Underflow: An attempt was made to pop an empty stack. It doesn't make sense to remove something from
an empty collection. Stack underflow is a common error - calls to isEmpty should be used to guard against
it.
 Overflow: An attempt was made to push an item onto a full stack. Items can only be added to a collection
if there is enough available memory to store it into the collection.

Stack ADT
 A Stack contains elements of the same type arranged in sequential order. All operations take place at a
single end that is top of the stack and following operations can be performed:
o push() – Insert an element at one end of the stack called top, if it is not full.
o pop() – Remove and return the element at the top of the stack, if it is not empty.
o peek() – Return the element at the top of the stack without removing it, if the stack is not empty.
o size() – Return the number of elements in the stack.
o isEmpty() – Return true if the stack is empty, otherwise return false.
o isFull() – Return true if the stack is full, otherwise return false.
Array representation of Stack – using template
#include <iostream>
using namespace std;
// Class for stack
template <class T>
class StackDemo
{
T* arr;
int top;
int capacity;

public:
StackDemo(int); // constructor

void push(T);
T pop();
T peek();

int size();
bool isEmpty();
bool isFull();

// destructor
~ StackDemo(){
delete[] arr;
}
};

// Constructor to initialize stack


template <class T>
StackDemo<T>::StackDemo(int size)
{
arr = new T[size];
capacity = size;
top = -1;
}

// function to add an element t in the stack


template <class T>
void StackDemo<T>::push(T t)
{
if (isFull())
{
cout << "OverFlow\nProgram Terminated\n";
exit(1);
}

cout << "Inserting " << t << endl;


arr[++top] = t;
}

// function to pop top element from the stack


template <class T>
T StackDemo<T>::pop()
{
// check for stack underflow
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(1);
}

cout << "Removing " << peek() << endl;

// decrease stack size by 1 and (optionally) return the popped element


return arr[top--];
}

// function to return top element in a stack


template <class T>
T StackDemo<T>::peek()
{
if (!isEmpty())
return arr[top];
else
exit(1);
}

// Utility function to return the size of the stack


template <class T>
int StackDemo<T>::size()
{
return top + 1;
}

// Utility function to check if the stack is empty or not


template <class T>
bool StackDemo<T>::isEmpty()
{
return top == -1; // or return size() == 0;
}

// Utility function to check if the stack is full or not


template <class T>
bool StackDemo<T>::isFull()
{
return top == capacity - 1; // or return size() == capacity;
}

// main function
int main()
{
StackDemo<string> st(2);

st.push("A");
st.push("B");
st.pop();
st.pop();

st.push("C");

// Prints the top of the stack


cout << "Top element is: " << st.peek() << endl;

// Returns the number of elements present in the stack


cout << "Stack size is " << st.size() << endl;

st.pop();

// check if stack is empty or not


if (st.isEmpty())
cout << "Stack Is Empty\n";
else
cout << "Stack Is Not Empty\n";

return 0;
}
Output:
Inserting A
Inserting B
Removing B
Removing A
Inserting C
Top element is: C
Stack size is 1
Removing C
Stack Is Empty

APPLICATIONS OF STACK
1. Reversing a String.
2. Parsing - Balancing of Parenthesis.
3. Infix to Postfix /Prefix conversion.
4. Postfix expression evaluation.
5. Redo-undo features at many places like editors, Photoshop.
6. Forward and backward feature in web browsers.
7. Used in many algorithms like Tower of Hanoi, tree traversals, stock span problem, histogram problem.
8. Other applications can be Backtracking, Knight tour problem, rat in a maze, N queen problem and Sudoku
solver.
9. In Graph Algorithms like Topological Sorting and Strongly Connected Components.

1. Expression Conversion (Infix to Postfix, Postfix to Prefix etc.,)


o While we use infix expressions in our day to day lives. Computers have trouble understanding this
format because they need to keep in mind rules of operator precedence and also brackets.
o Prefix and Postfix expressions are easier for a computer to understand and evaluate.
o Infix expression: The expression of the form a op b. When an operator is in-between every pair of
operands. This form of expressions are known as infix expressions.
o Postfix expression: The expression of the form a b op. When an operator is followed for every pair of
operands. This form of expressions are known as postfix expressions.
o Prefix expression: The expression of the form op a b. When an operator is before every pair of
operands. This form of expressions are known as prefix expressions.

Infix to postfix conversion:


Why postfix representation of the expression?
o The compiler scans the expression either from left to right or from right to left.
o Consider the below expression: a + b * c + d
o The compiler first scans the expression to evaluate the expression b * c, then again scan the
expression to add a to it. The result is then added to d after another scan.
o The repeated scanning makes it very in-efficient. It is better to convert the expression to postfix (or
prefix) form before evaluation.
o The corresponding expression in postfix form is: abc*+d+. The postfix expressions can be evaluated
easily using a stack.

Algorithm:
1. Scan the infix expression from left to right.
2. If the scanned character is an operand, output it.
3. Else,
a. If the precedence of the scanned operator is greater than the precedence of the operator in the
stack (or the stack is empty or the stack contains a ‘(‘ ), push it.
b. Else, Pop all the operators from the stack which are greater than or equal to in precedence than
the scanned operator. (If you encounter parenthesis while popping then stop there and push the
scanned operator in the stack.)
c. After doing that Push the scanned operator to the stack.
4. If the scanned character is an ‘(‘, push it to the stack.
5. If the scanned character is an ‘)’, pop the stack and and output it until a ‘(‘ is encountered, and discard
both the parenthesis.
6. Repeat steps 2-6 until infix expression is scanned.
7. Pop and output from the stack until it is not empty.

/* C++ implementation to convert infix expression to postfix*/


#include <iostream>
#include <string.h>
using namespace std;

// Class for stack


template <class T>
class StackDemo
{
T* arr;
int top;
int capacity;

public:
StackDemo(int); // constructor

void push(T);
T pop();
T peek();

int size();
bool isEmpty();
bool isFull();

// destructor
~ StackDemo(){
delete[] arr;
}
};

// Constructor to initialize stack


template <class T>
StackDemo<T>:: StackDemo(int size)
{
arr = new T[size];
capacity = size;
top = -1;
}

// function to add an element x in the stack


template <class T>
void StackDemo<T>::push(T t)
{
if (isFull())
{
cout << "OverFlow\nProgram Terminated\n";
exit(1);
}

cout << "Inserting " << t << endl;


arr[++top] = t;
}

// function to pop top element from the stack


template <class T>
T StackDemo<T>::pop()
{
// check for stack underflow
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(1);
}

cout << "Removing " << peek() << endl;

// decrease stack size by 1 and (optionally) return the popped element


return arr[top--];
}

// function to return top element in a stack


template <class T>
T StackDemo<T>::peek()
{
if (!isEmpty())
return arr[top];
else
exit(1);
}

// Utility function to return the size of the stack


template <class T>
int StackDemo<T>::size()
{
return top + 1;
}

// Utility function to check if the stack is empty or not


template <class T>
bool StackDemo<T>::isEmpty()
{
return top == -1; // or return size() == 0;
}

// Utility function to check if the stack is full or not


template <class T>
bool StackDemo<T>::isFull()
{
return top == capacity - 1; // or return size() == capacity;
}

//utility function to return operator precedence


int prec(char c)
{
if(c == '^')
return 3;
else if(c == '*' || c == '/')
return 2;
else if(c == '+' || c == '-')
return 1;
else
return -1;
}

// Utility function to convert infix expression to postfix expression


void infixToPostfix(char s[])
{
int len=strlen(s);
StackDemo<char> st(len);
st.push('N');
string ns;
for(int i = 0; i < len; i++)
{
// If the scanned character is an operand, add it to output string.
if((s[i] >= 'a' && s[i] <= 'z')||(s[i] >= 'A' && s[i] <= 'Z'))
ns+=s[i];
// If the scanned character is an '(', push it to the stack.
else if(s[i] == '(')

st.push('(');

// If the scanned character is an ')', pop and to output string from the stack
// until an '(' is encountered.
else if(s[i] == ')')
{
while(st.peek() != 'N' && st.peek() != '(')
{
char c = st.peek();
st.pop();
ns += c;
}
if(st.peek() == '(')
{
char c = st.peek();
st.pop();
}
}

//If an operator is scanned


else{
while(st.peek() != 'N' && prec(s[i]) <= prec(st.peek()))
{
char c = st.peek();
st.pop();
ns += c;
}
st.push(s[i]);
}

}
//Pop all the remaining elements from the stack
while(st.peek() != 'N')
{
char c = st.peek();
st.pop();
ns += c;
}

cout << ns << endl;

// main function
int main()
{
char exp[] = "a+b*(c^d-e)^(f+g*h)-i";
infixToPostfix(exp);
return 0;
}
Output:
Inserting N
Inserting +
Inserting *
Inserting (
Inserting ^
Removing ^
Inserting -
Removing -
Removing (
Inserting ^
Inserting (
Inserting +
Inserting *
Removing *
Removing +
Removing (
Removing ^
Removing *
Removing +
Inserting -
Removing -
abcd^e-fgh*+^*+i-

Infix to prefix conversion:


o Given two operands a and b and an operator +, the infix notation implies that operator + will be placed in
between a and b i.e a + b .
o When the operator + is placed after both operands i.e ab+, it is called postfix notation.
o And when the operator + is placed before the operands i.e + a b, the expression in prefix notation.

Examples:
Input : A * B + C / D
Output : + * A B/ C D
Input : (A - B/C) * (A/K-L)
Output : *-A/BC-/AKL
Algorithm:
Step-1: Reverse the infix expression i.e A+B*C will become C*B+A. Note while reversing each ‘(‘ will
become ‘)’ and each ‘)’ becomes ‘(‘.
Step-2: Obtain the postfix expression of the modified expression i.e CB*A+.
Step-3: Reverse the postfix expression. Hence in our example prefix is +A*BC.
// CPP program to convert infix to prefix
#include <iostream>
#include <string.h>
#include <bits/stdc++.h>
using namespace std;

bool isOperator(char c)
{
return (!isalpha(c) && !isdigit(c));
}
int getPriority(char C)
{
if (C == '-' || C == '+')
return 1;
else if (C == '*' || C == '/')
return 2;
else if (C == '^')
return 3;
return 0;
}

string infixToPostfix(string infix)


{
infix = '(' + infix + ')';
int l = infix.size();
stack<char> char_stack;
string output;

for (int i = 0; i < l; i++) {

// If the scanned character is an


// operand, add it to output.
if (isalpha(infix[i]) || isdigit(infix[i]))
output += infix[i];

// If the scanned character is an


// ‘(‘, push it to the stack.
else if (infix[i] == '(')
char_stack.push('(');

// If the scanned character is an


// ‘)’, pop and output from the stack
// until an ‘(‘ is encountered.
else if (infix[i] == ')') {

while (char_stack.top() != '(') {


output += char_stack.top();
char_stack.pop();
}

// Remove '(' from the stack


char_stack.pop();
}

// Operator found
else {

if (isOperator(char_stack.top())) {
while (getPriority(infix[i])
<= getPriority(char_stack.top())) {
output += char_stack.top();
char_stack.pop();
}

// Push current Operator on stack


char_stack.push(infix[i]);
}
}
}
return output;
}

string infixToPrefix(string infix)


{
/* Reverse String
* Replace ( with ) and vice versa
* Get Postfix
* Reverse Postfix * */
int l = infix.size();

// Reverse infix
reverse(infix.begin(), infix.end());

// Replace ( with ) and vice versa


for (int i = 0; i < l; i++) {

if (infix[i] == '(') {
infix[i] = ')';
i++;
}
else if (infix[i] == ')') {
infix[i] = '(';
i++;
}
}

string prefix = infixToPostfix(infix);

// Reverse postfix
reverse(prefix.begin(), prefix.end());

return prefix;
}

// Driver code
int main()
{
string s = ("(a-b/c)*(a/k-l)");
cout << infixToPrefix(s) << std::endl;
return 0;
}
Output:
*-a/bc-/akl
The complexity is linear in time i.e O(n).
Evaluation of Postfix Expression
 The Postfix notation is used to represent algebraic expressions.
 The expressions written in postfix form are evaluated faster compared to infix notation as parenthesis are
not required in postfix, and the need of remembering operator precedence can be avoided.
 Following is algorithm for evaluation postfix expressions.

Algorithm:
1. Create a stack to store operands (or values).
2. Scan the given expression and do following for every scanned element.
…..a) If the element is a number, push it into the stack
…..b) If the element is a operator, pop operands for the operator from stack. Evaluate the operator and
push the result back to the stack
3. When the expression is ended, the number in the stack is the final answer
Example: Let the given expression be “2 3 1 * + 9 -“. We scan all elements one by one.

1. Scan ‘2’, it’s a number, so push it to stack. Stack contains ‘2’.


2. Scan ‘3’, again a number, push it to stack, stack now contains ‘2 3’ (from bottom to top).
3. Scan ‘1’, again a number, push it to stack, stack now contains ‘2 3 1’.
4. Scan ‘*’, it’s an operator, pop two operands from stack, apply the * operator on operands, we get 3*1
which results in 3. We push the result ‘3’ to stack. Stack now becomes ‘2 3’.
5. Scan ‘+’, it’s an operator, pop two operands from stack, apply the + operator on operands, we get 3 + 2
which results in 5. We push the result ‘5’ to stack. Stack now becomes ‘5’.
6. Scan ‘9’, it’s a number, we push it to the stack. Stack now becomes ‘5 9’.
7. Scan ‘-‘, it’s an operator, pop two operands from stack, apply the – operator on operands, we get 5 – 9
which results in -4. We push the result ‘-4’ to stack. Stack now becomes ‘-4’.
8. There are no more elements to scan, we return the top element from stack (which is the only element left
in stack).

Program: Postfix Expression evaluation


#include <iostream>
#include <math.h>
#include <string.h>
using namespace std;

class StackDemo
{
private:
int* arr;
int top, res, capacity;
public:
StackDemo(int);
void push(int);
int pop();
int peek();
int size();
bool isEmpty();
bool isFull();

void postEval(char[]);

// destructor
~ StackDemo(){
delete[] arr;
}
};

// Constructor to initialize stack


StackDemo:: StackDemo(int size)
{
arr = new int[size];
capacity = size;
top = -1;
}

// function to add an element t in the stack


void StackDemo::push(int t)
{
if (isFull())
{
cout << "OverFlow\nProgram Terminated\n";
exit(1);
}

cout << "Inserting " << t << endl;


arr[++top] = t;
}

// function to pop top element from the stack


int StackDemo::pop()
{
// check for stack underflow
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(1);
}

cout << "Removing " << peek() << endl;

// decrease stack size by 1 and (optionally) return the popped element


return arr[top--];
}

// function to return top element in a stack


int StackDemo::peek()
{
if (!isEmpty())
return arr[top];
else
exit(1);
}

// Utility function to return the size of the stack


int StackDemo::size()
{
return top + 1;
}

// Utility function to check if the stack is empty or not


bool StackDemo::isEmpty()
{
return top == -1;
}

// Utility function to check if the stack is full or not


bool StackDemo::isFull()
{
return top == capacity - 1;
}

void StackDemo::postEval(char texp[])


{
int op1, op2, op3;
while (*texp)
{
if ( *texp == ' ' || *texp == '\t' )
{
texp++;
continue;
}
if(*texp<='9' && *texp>='0')
{
res = *texp - '0' ;
push(res);
}
else
{
op1 = pop();
op2 = pop();
switch (*texp)
{
case '+':
op3 = op2 + op1 ;
break;
case '-':
op3 = op2 - op1 ;
break;
case '/':
op3 = op2 / op1 ;
break;
case '*':
op3 = op2 * op1 ;
break ;
case '%':
op3 = op2 % op1 ;
break;
case '^' :
op3 = pow( op2 , op1 ) ;
break;
default :
cout << "Unknown Operator\n";
}
push(op3) ;
}
texp++ ;
}
res = pop();
cout << "Result is: " << res;
}

//Main function of the program


int main(void)
{
char exp[] = "647*+";
int len=strlen(exp);
StackDemo st(len);
st.postEval(exp);
return 0;
}
Output:
Inserting 6
Inserting 4
Inserting 7
Removing 7
Removing 4
Inserting 28
Removing 28
Removing 6
Inserting 34
Removing 34
Result is: 34
QUEUE ADT (Abstract Data Type):
 A Queue is a linear structure which follows a particular order in which the operations are performed. The
order is First In First Out (FIFO). The inserting operation (enQueue) can only be performed from one side
(called the rear) and the removing operation (deQueue) can only be performed from the other side (called
the front).
 A queue is an abstract data structure that contains a collection of elements.
 A good example of a queue is any queue of consumers for a resource where the consumer that came first is
served first.
 The difference between stacks and queues is in removing. In a stack we remove the item the most recently
added; in a queue, we remove the item the least recently added.
 The regular queue is also known as linear queue.

Queue EnQueue Operation:

Queue DeQueue Operation:


Applications of Queue:
 Queue is used when things don’t have to be processed immediately, but have to be processed in First In
First Out order like Breadth First Search.
 This property of Queue makes it also useful in following kind of scenarios.
1. When a resource is shared among multiple consumers. Examples include CPU scheduling, Disk
Scheduling.
2. When data is transferred asynchronously (data not necessarily received at same rate as sent)
between two processes. Examples include IO Buffers, pipes, file IO, etc.

Queue ADT
 A Queue contains elements of the same type arranged in sequential order. Operations take place at
both ends, insertion is done at the rear end and deletion is done at the front end.
 Following operations can be performed:
o enQueue() – Insert an element at the rear end of the queue, if the queue is not full.
o deQueue() – Remove and return the first element of the queue, if the queue is not empty.
o peekFront() – Return the front element of the queue without removing it, if the queue is not
empty.
o peekRear() – Return the rear element of the queue without removing it, if the queue is not
empty.
o size() – Return the number of elements in the queue.
o isEmpty() – Return true if the queue is empty, otherwise return false.
o isFull() – Return true if the queue is full, otherwise return false.

Array representation of Queue – using template


#include <iostream>
using namespace std;

template <class T>


class QueueDemo
{
T* queue;
int capacity;
int front;
int rear;
int count;

public:
QueueDemo(int);

void deQueue();
void enQueue(T);
T peekFront();
T peekRear();
int size();
bool isEmpty();
bool isFull();
};

template <class T>


QueueDemo<T>:: QueueDemo(int size)
{
queue = new T[size];
capacity = size;
front = 0;
rear = -1;
count = 0;
}

template <class T>


void QueueDemo<T>::enQueue(T item)
{
if (isFull())
{
cout << "OverFlow\nProgram Terminated\n";
return;
}

cout << "Inserting: " << item << '\n';

queue[++rear] = item;
count++;
}

template <class T>


void QueueDemo<T>::deQueue()
{
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
return;
}

cout << "\nRemoving: " << queue[front++] << '\n';


count--;
}

template <class T>


T QueueDemo<T>::peekFront()
{
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
return 0;
}
return queue[front];
}

template <class T>


T QueueDemo<T>::peekRear()
{
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
return 0;
}
return queue[rear];
}

template <class T>


int QueueDemo<T>::size()
{
return count;
}

template <class T>


bool QueueDemo<T>::isEmpty()
{
return (count == 0);
}

template <class T>


bool QueueDemo<T>::isFull()
{
return (rear == capacity-1);
}

int main()
{
QueueDemo<string> que(4);

que.enQueue("a");
que.enQueue("b");
que.enQueue("c");

cout << "Front element is: " << que.peekFront() << endl;
cout << "Rear element is: " << que.peekRear() << endl;
que.deQueue();

que.enQueue("d");

cout << "Queue size is " << que.size() << endl;

que.deQueue();
que.deQueue();
que.deQueue();

if (que.isEmpty())
cout << "Queue Is Empty\n";
else
cout << "Queue Is Not Empty\n";

que.enQueue("e");
que.deQueue();
return 0;
}
Output:
Inserting a
Inserting b
Inserting c
Front element is: a
Rear element is: c
Removing a
Inserting d
Queue size is 3
Removing b
Removing c
Removing d
Queue Is Empty
OverFlow
Program Terminated
UnderFlow
Program Terminated

CIRCULAR QUEUE:

 Circular Queue is a linear data structure in which the operations are performed based on FIFO (First In
First Out) principle and the last position is connected back to the first position to make a circle.
 It is also called ‘Ring Buffer’.

 In a normal Queue, we can insert elements until queue becomes full. But once queue becomes full, we
cannot insert the next element even if there is an empty space in front of the queue.
 The problem can be overcome with the help of a circular queue. In this the last position of the queue is
connected back to the first position to form the memory locations in a circular fashion.
 Here when the queue is full, and if there are empty locations before the front they can be reused to perform
more enQueue operations.
Applications of Circular Queue:
1. Traffic lights functioning is the best example for circular queues. The colors in a traffic light follow a
circular pattern.
2. In page replacement algorithm, a circular list of pages is maintained and when a page needs to be replaced,
the page in the front of the queue will be chosen.

Circular Queue ADT:


Operations on Circular Queue:
 enQueue(value) This function is used to insert an element into the circular queue. In a circular
queue, the new element is always inserted at Rear position.
 deQueue() This function is used to delete an element from the circular queue. In a circular
queue, the element is always deleted from front position.
 display() – Display all the elements form the circular queue.
 isFull() – Returns true if the circular queue is full, otherwise returns false.
 isEmpry() – Returns true if the circular queue is empty, otherwise returns false.
Array representation of Circular Queue using Template
#include<iostream>
#include<conio.h>
using namespace std;

// Creating a generic Queue class


template <class T>
class CQueueDemo
{
T* cqueue;
int front,rear,capacity;
public:
CQueueDemo(int);
void enQueue(T);
T deQueue();
void display();
bool isFull();
bool isEmpty();
};

template <class T>


CQueueDemo<T>:: CQueueDemo(int size)
{
cqueue=new T(size);
front=-1;
rear=0;
capacity=size;
}

// Enqueue function
template <class T>
void CQueueDemo<T>::enQueue(T item)
{
if (isFull())
{
cout << "Circular Queue is full\n";
exit(1);
}
if(front==-1)
{
front=0;
rear=0;
}
else
rear=(rear+1)%capacity;
cqueue[rear] = item; //inserting the item in the circular queue
}

//Dequeue function
template <class T>
T CQueueDemo<T>::deQueue()
{
T val;
if(isEmpty())
{
cout << "Circular Queue is empty\n";
exit(1);
}
val= cqueue[front]; //item to be deleted
if(front==rear)
front=rear=-1;
else
front=(front+1)%capacity;
return val;
}

template <class T>


void CQueueDemo<T>::display()
{
int temp;
if(isEmpty())
{
cout<<"\n Circular Queue is Empty";
exit(1);
}
cout<<"Elements in the Circular Queue:" <<endl;
temp=front;
while(temp!=rear)
{
cout<<"\n "<<cqueue[temp];
temp=(temp+1)%capacity;
}
cout<<"\n "<<cqueue[temp];
cout<<"\n";
}

template <class T>


bool CQueueDemo<T>::isFull()
{
return (front==(rear+1)%capacity);
}

template <class T>


bool CQueueDemo<T>::isEmpty()
{
return ((front==-1)||(front==rear-1));
}

//The main function


int main(void)
{
CQueueDemo<char> cq(5);
cq.enQueue('p');
cq.enQueue('q');
cq.enQueue('r');
cq.enQueue('s');
cq.enQueue('t');
cq.display();
cq.deQueue();
cq.deQueue();
cq.display();
cq.enQueue('u');
cq.enQueue('v');
cq.display();
cq.deQueue();
cq.display();
}
Output:
Elements in the Circular Queue:
p
q
r
s
t
Elements in the Circular Queue:
r
s
t
Elements in the Circular Queue:
r
s
t
u
v
Elements in the Circular Queue:
s
t
u
v

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy