0% found this document useful (0 votes)
17 views

Module 2 DSA Notes MUSE (1)

Uploaded by

finalproject4812
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views

Module 2 DSA Notes MUSE (1)

Uploaded by

finalproject4812
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 36

Data Structures and Applications, MUSE

Data Structures and Applications


Module-2
Stacks

Definition of Stack
It is and abstract data type commonly used in most of the programming language. A stack is a linear
data structure in which insertion and deletion of the elements are allowed only at one end called “top”
of the stack.

Stacks are also known as Last-In-First-Out (LIFO) or First In Last Out (FILO) list, Since the last
element inserted into a stack is the first element removed.

Logical Representation of stacks

It is like a container which as one open end.

Stack operations
• push(): insert data onto the stack
• pop(): deletes the element present on the top of the stack.
• top() or peek(): returns the last inserted element without removing it.
• Size(): returns the size or number of elements in the stack.
• display(): display the contents of the stack.
• overflow or isFull(): check whether stack full or not.
• underflow or isEmpty(): check whether stack full or not.

Applications of Stack
• Reverse a string or word. Ex: radar radar
• Undo mechanism in Microsoft word. Ex: ctrl+z
• Function call: when you call function something or value would return.
• Recursion: chain function call i.e., function is calling itself again and again.
• To check the balance of the parenthesis. Ex: (), {}, [] for each opening there is proper closing.
• Infix, postfix, prefix etc.
• Topological sorting, DFS (Depth first search), Tower of Hanoi etc.
• Evaluation of postfix expression.

1
Data Structures and Applications, MUSE

Stack Implementation using arrays


A stack data structure can be implemented using 1-D arrays but can store only fixed number of
values.

Define 1-D array of specific size and insert/delete the values in the array by using LIFO principle with
the help of variable “top”.

So, initialize variable top= -1

#define N 5
int stack[N];
int top = -1;

push() or insert--- the two steps to push data onto the stack are,

• Check whether the following stack is full by comparing “top” with size “N” i.e., (top==N-1) if
it is full then display “overflow” condition and terminate.
• If it is not full, then increment the “top” and assign the value.

Function to perform push operation in stack


void push()
{
int x;
printf(“enter data\n”);
scanf(“%d”, &x);
if (top = =N-1)
printf(“overflow condition\n”);
else
{
top++;
stack[top] = x;
}

pop() or delete-- the two steps to pop data from the stack are,

• Check whether the stack is empty by comparing “top” with size “-1” i.e., (top==-1) if it is empty
then display “underflow” condition and terminate.
• If it is not empty, then decrement the “top” and return the value.

Function to perform pop operation in stack


void pop()
{
int item;
if (top = = -1)
printf(“underflow condition\n”);
else
{
item = stack[top];
top++;
printf(“%d”, item);
}

2
Data Structures and Applications, MUSE

display() or traverse-- the two steps to display data in stack are,

• Check whether the stack is empty by comparing “top” with size “-1” i.e., (top==-1) if it is empty
then display stack is empty and terminate.
• If it is not empty, then run a for loop from the top till it reaches “0” by decrementing and print
contents.

Function to display the contents of the stack


void display()
{
int i;
for (i= top; i>=0; i++)
printf(“d”, stack[i]);
}
peek() or top
Function to print the top of the stack
void peek()
{
if (top = = -1)
printf(“stack is empty\n”);
else
printf(“d”, stack[top]);
}

Stack Implementation using dynamic arrays


Why we need to go to dynamic arrays? Till now what we were using was static arrays i.e., size was
fixed so, we allocate or create a stack dynamically during run time when we are not sure about the size
of the stack.

#define N 1
int stack[N];
int *stack;
int top = -1;
Function to perform push operation in stack
void push()
{
if (top = = -1)
{
printf(“stack full\n”);
printf(“increase stack by 1\n”);
N++;
realloc(*stack, N, int);
}
else
{
top++;
stack[top] = x;
}
}

3
Data Structures and Applications, MUSE

Function to perform pop operation in stack


void pop()
{
if (top = = -1)
printf(“stack is empty\n”);
else
{
printf(“item deleted =%d\n”, s[top--]);
printf(“stack size decremented by 1\n”)
N--;
realloc(*stack, N, int);
}
}

Stack Applications: Polish notation


Expression
It is sequence of operators and operands that reduces to a single value after evaluation is called an
expression.
<operands> <operator> <operands>
Example: 5+1, a*b, (a/b) -a*p

Operands may be variables like a, b, c etc. or a constant like 5, 4, 3etc. operators is symbol which
signifies a mathematical or logical operations between operands such as +, -, *, ^, %, /.

An expression can represented using following three different notations.

• Infix: it is a form of arithmetic expression in which we fix the operators in between two
operands.
Example: (A+B)*(C-D)
• Prefix or Polish Notation: it is a form of arithmetic expression in which we fix the operators
before its two operands.
Example: +*CD ^EF+OP
• Postfix or Reverse Polish Notation: it is a form of arithmetic expression in which we fix the
operators after two operands. The postfix notation is also called as “Suffix notation”.
Example: AB*XY/ZF+

Precedence of the operators


The first problem with understanding the meaning of expressions and statements is finding out the
order in which the operations are performed. The Bodmas theorem is applied for the operator
precedence.

Example 1, Example 2,

=1+2*5+30/5 = 2^2^3
=1+10+30/5 = 2^8
=1+10+6 = 256
= 11+6
= 17

4
Data Structures and Applications, MUSE

Convert infix expression to prefix expression without stack


1. = 5+1
= +51

2. = a*b+c
= *ab+c
= +*abc

3. = a+b-c
= +ab-c
= -+abc

4. = a*b-c/d
=*ab-c/d
=*ab-/cd
= -*ab/cd

Convert infix expression to postfix expression without stack


1. =a+b
=ab+

5
Data Structures and Applications, MUSE

2. =a+b-c
=ab+-c
=ab+c-

3. =a+b*c
=a+bc*
=abc*+

4. = a*b-c/d
= ab*-c/d
= ab*-cd/
= ab*cd/-

5. = ((A+(B-C)*D)^E+F)
= ((A+BC-*D)^E+F)
= ((A+BC-D*)^E+F)
= (ABC-D*+^E+F)
= (ABC-D*+E^+F)
= ABC-D*+E^F+

6. = X^Y^Z-M+N+P/Q
= X^YZ^-M+N+P/Q
= XYZ^^-M+N+P/Q
= XYZ^^-M+N+PQ/
= XYZ^^M-+N+PQ/
= XYZ^^M-N++PQ/
= XYZ^^M-N+PQ/+

Rules to convert infix expression to postfix expression with stack


• Print the operands as they arrive.
• If stack is empty or contains a left parenthesis on top, push the incoming operator onto the
stack.
• If incoming symbol is “(“ push it on to stack.
• If incoming symbol is “)” pop the stack and print the operator until left paraenthesis is found.
• If incoming symbol has higher precedence then the top of the stack, push it on to the stack.
• If incoming symbol has loer precedence than the top of the stack, pop and print the top. Then
test the incoming operator against new top of the stack.
• If incoming operator has equal precedence with the top of the stack, use associativity rule.
➢ Associativity is L to R, then pop and print the top of the stack and then push the
incoming operator.
➢ Associativity R to L, then push the incoming operator.
• At the end of the expression , pop and print all the operators of the stack.
Example 1: A+B/C
Steps Scanned Symbol Stack Output
0 A A
1 + + A
2 B + AB
3 / +/ AB

6
Data Structures and Applications, MUSE

4 C +/ ABC
5 ABC/+

Example 2: A-B/C*D+E

Steps Scanned Symbol Stack Output


0 A A
1 - - A
2 B - AB
3 / -/ AB
4 C -/ ABC
5 * -* ABC/
6 D -* ABC/D
7 + + ABC/D*-
8 E + ABC/D*-E
9 + ABC/D*-E+

Example 3: K+L-M*N+(O^P)*W/U/V*T+Q
Steps Scanned Symbol Stack Output
0 K K
1 + + K
2 L + KL
3 - - KL+
4 M - KL+M
5 * -* KL+M
6 N -* KL+MN
7 + + KL+MN-*
8 ( +( KL+MN-*
9 O +( KL+MN-*O
10 ^ +(^ KL+MN-*O
11 P +(^ KL+MN-*OP
12 ) + KL+MN-*OP^
13 * +* KL+MN-*OP^
14 W +* KL+MN-*OP^W
15 / +/ KL+MN-*OP^W*
16 U +/ KL+MN-*OP^W*U
17 / +/ KL+MN-*OP^W*U/
18 V +/ KL+MN-*OP^W*U/V
19 * +* KL+MN-*OP^W*U/V/
20 T +* KL+MN-*OP^W*U/V/T
21 + + KL+MN-*OP^W*U/V/T*+
22 Q + KL+MN-*OP^W*U/V/T*+Q
23 + KL+MN-*OP^W*U/V/T*+Q+

Example 4: K+L-M*N+(O^P)*W/U/V*T+Q^J^A

Steps Scanned Symbol Stack Output


0 K K
1 + + K
2 L + KL
3 - - KL+
4 M - KL+M

7
Data Structures and Applications, MUSE

5 * -* KL+M
6 N -* KL+MN
7 + + KL+MN-*
8 ( +( KL+MN-*
9 O +( KL+MN-*O
10 ^ +(^ KL+MN-*O
11 P +(^ KL+MN-*OP
12 ) + KL+MN-*OP^
13 * +* KL+MN-*OP^
14 W +* KL+MN-*OP^W
15 / +/ KL+MN-*OP^W*
16 U +/ KL+MN-*OP^W*U
17 / +/ KL+MN-*OP^W*U/
18 V +/ KL+MN-*OP^W*U/V
19 * +* KL+MN-*OP^W*U/V/
20 T +* KL+MN-*OP^W*U/V/T
21 + + KL+MN-*OP^W*U/V/T*+
22 Q + KL+MN-*OP^W*U/V/T*+Q
23 ^ +^ KL+MN-*OP^W*U/V/T*+Q
24 J +^ KL+MN-*OP^W*U/V/T*+QJ
25 ^ +^^ KL+MN-*OP^W*U/V/T*+QJ
26 A +^^ KL+MN-*OP^W*U/V/T*+QJA
27 +^^ KL+MN-*OP^W*U/V/T*+QJA^^+

Manually evaluation of postfix expression without stack


Example 1: 231*+9-
= 231*+9-
= 23+9- // operand 2 is 1 and operand 1is 3 so, 3*1=3
= 59- // operand 2 is 3 and operand 1is 2 so, 2+3=5
=-4 // operand 2 is 9 and operand 1is 5 so, 5-9= -4

Example 2: 53+62/*35*+
= 53+62/*35*+
= 862/*35*+
= 83*35*+
= 2435*+
= 2415+
= 39

Example 3: Assume a=2, b=3, c=4, d=16, e=2, f=3. Evaluate following postfix expression
abc*+def^/-
= abc*+def^/-
= 234*+1623^/-
= 212+1623^/-
= 141623^/-
= 14168/-
= 142-
= 12

8
Data Structures and Applications, MUSE

Evaluation of postfix expression with stack


A postfix expression can be evaluated using stack data structure. To evaluate the postfix expression
using stack data structure follow the below rules.

• Scan the given expression from left to right.


• For each character in the postfix expression, do if the operand encountered, push it onto stack.
• Else if, operator is encountered, pop 2 elements
➢ Top element of the stack is operand 2
➢ Next to top element is operand 1
➢ Result = operand 1*operand 2
➢ Push the result on to stack
• Return the element of the stack top.
Example 1: 234*+1623^/-

Steps Scanned Symbol Stack Output


0 2 2
1 3 23
2 4 234
3 * 212 12
4 + 14 14
5 16 14 16
6 2 14 16 2
7 3 14 16 2 3
8 ^ 14 16 8 8
9 / 14 2 2
10 - 12 12

Example 2: 632-5*+1^7+
Steps Scanned Symbol Stack Output
0 6 6
1 3 63
2 2 632
3 - 61 1
4 5 615
5 * 65 5
6 + 11 11
7 1 11 1
8 ^ 11 11
9 7 11 7
10 + 18 18

Example 3: Convert the given expression to postfix expression and then evaluate the postfix
expression using stack. (1+(2-3)*4)
First perform Conversion of postfix expression

Steps Scanned Symbol Stack Output


0 ( (
1 1 ( 1
2 + (+ 1
3 ( (+( 1

9
Data Structures and Applications, MUSE

4 2 (+( 12
5 - (+(- 12
6 3 (+(- 123
7 ) (+ 123-
8 * (+* 12 3-
9 4 (+* 1 2 3 -4
10 ) 1 2 3 -4 * +

Now postfix expression is: 123-4*+


So, perform evaluation of this expression

Steps Scanned Symbol Stack Output


0 1 1
1 2 12
2 3 123
3 - 1 -1 -1
4 4 1 -1 4
5 * 1 -4 -4
6 + -3 -3

10
Data Structures and Applications, MUSE

Recursion

Recursion is a method of solving the problem where the solution to a problem depends on solutions to
smaller instances of the same problem.

Recursive function is a function that calls itself during the execution.

The two types of recursions are,

• Direct Recursion
• Indirect Recursion

Direct recursion

• A recursive function that invokes itself is said to have direct recursion.


• For example, factorial function calls itself hence it is called direct recursion.

Indirect recursion

A function which contains call to another function which in turn contains calls another function, and so
on.

Any recursive function has two elements,

• Base case
• General case

Base case

• The statement that solves the problem is called base case.


• Every recursive function must have at least one base case.
• It is a special case whose solution can be obtained without using recursion.

A base case serves two purposes,

• It acts as a terminating condition.


• The recursive function obtains the solution from the base case it reaches.

General case:

The statement that reduces the size of the problem is called general case.
This is done by calling the same function with reduced size.
In general, recursive function of factorial problem can be written as,

11
Data Structures and Applications, MUSE

Limitations of Recursion
• Recursive solutions may involve extensive overhead because they use function calls.
• Each time you make a call, you use up some of your memory allocation. If recursion is
deep, then you may run out of memory.

Example Programs,
Write a C program to find a factorial of number using recursion.
#include<stdio.h>
int fact(int);
void main( )
{
int n, res;

printf(“enter the number to find its factorial\n”);


scanf(“%d”,&n);
res=fact(n);
printf(“factorial of %d=%d”,n,res);
}
int fact(int n)
{
if(n==0)
return 1;
else
return (n*fact(n-1));
}

Output
enter the number to find its factorial
5
factorial of 5 = 120

12
Data Structures and Applications, MUSE

Fibonacci series

A series of number in which each number is sum of the two-proceeding number.


Example: 0, 1, 1, 2, 3, 5, 8………
The first two numbers of Fibonacci series are ‘0’ and ‘1’.
The recursive function for Fibonacci series are 3 cases,
• If n=1 only one digit to printed i.e., ‘0’.
• If n=2 only two digit to be printed i.e., ‘0’ and ‘1’.
• If n>2 last two digit is to be added and printed i.e., fib(n-1) +fib(n-2).

Program to generate Fibonacci series using recursion.

#include<stdio.h>
int Fibonacci(int);
void main()
{
int n, i = 0, c;
printf(" enter the number of terms\n");
scanf("%d", &n);
printf("Fibonacci series\n");
for ( c = 1 ; c <= n ; c++ )
{
printf("%d\n", Fibonacci(i));
i++;
}
}
int Fibonacci(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return ( Fibonacci(n-1) + Fibonacci(n-2) );
}

Output
enter the number of terms
5
01123

GCD (Greatest Common Device)

The greatest common divisor (GCD) of two integers a and b is the greatest integer that divides both a
and b with no remainder.

gcd(a,b) = gcd (b, a mod b) i.e., if only a > b again and again call a mod b then stop when,
gcd(a,0) = a

Algorithm:
• Divide a by b and assign the value reminder to c.

13
Data Structures and Applications, MUSE

• Then assign the value b to a and value c to b.


• Repeat the step 1 and 2 until the value of b becomes 0.
• If b=0, then return the value of a as the gcd value of a and b.

Example: Assume, a=30, b=18 gcd(30,18)?

a b a/b
30 18 16
18 12 6
12 6 0
6 0

gcd(30,18) = 6

Write a program to find GCD and LCM of two numbers using concept of functions.
#include<stdio.h>
int hcf(int, int);
int main( )
{
int x, y, gcd, lcm;

printf(“Enter two numbers”);


scanf(“%d%d”, &x, &y);
gcd = hcf(x, y);
lcm = (x * y)/ gcd;

printf(“GCD = %d”, gcd);


printf(“LCM = %d”, lcm);
}
int hcf( int x, int y)
{
if(x == 0)
return y;
while(y!=0)
{
if(x > y)
x = x-y;
else
y = y-x;
}
return x;
}

OUTPUT

Enter two numbers


12 8
GCD = 4
LCM = 24

14
Data Structures and Applications, MUSE

Tower of Hanoi

It is a mathematical puzzle, where we have three roads (Beginning, Auxiliary, End) and ‘N’ disks. The
objective of the puzzle is to move the ‘N’ disks to destination road, obeying the following rules.
• Only one disk can be moved at a time.
• A disk can only be moved, if it is the uppermost disk.
• No disk may be placed on the top of the smaller disk.

Example 1: n = 1

Output:

1. Move top disk from peg A to peg C.

In other words,
n=l: A→C

15
Data Structures and Applications, MUSE

Example 1: n = 2

Output:
1. Move top disk from peg A to peg B.
2. Move top disk from peg A to peg C.
3. Move top disk from peg B to peg C.

In other words,
n=2: A→B, A→C, B→C,

Example 1: n = 3

16
Data Structures and Applications, MUSE

17
Data Structures and Applications, MUSE

Output:
1. Move top disk from peg A to peg C.
2. Move top disk from peg A to peg B.
3. Move top disk from peg C to peg B.
4. Move top disk from peg A to peg C.
5. Move top disk from peg B to peg A.
6. Move top disk from peg B to peg C.
7. Move top disk from peg A to peg C.

In other words,
n=3: A→C, A→B, C→B, A→C, B→A, B→C, A→C

The recursive procedure call for tower of Hanoi problem is, general notation is,

TOWER (N, BEG, AUX, END)

• Move the top n-1 disks from peg A to B.


• Move the top disk from peg A to peg C i.e., A C
• Move the top n-1 disks from peg B to peg C.

Follow these three steps to solve n = 4 disks.

• TOWER (N-1, BEG, END, AUX)


• TOWER (1, BEG, AUX, END)
• TOWER (N-1, AUX, BEG, END)

Example 1: n = 4

18
Data Structures and Applications, MUSE

Ackerman’s Function
It is a function with two arguments each of which can be assigned any non-negative integers i.e.,
0,1,2… is defined as follows.

Definition
• If m = 0 then A (m, n) = n+1
• If m = 0 but n = 0 then, A (m, n) = A (m-1, 1)
• If m = 0 but n = 0 then, A (m, n) = A (m-1, A (m, n-1))

Example: Evaluate A (1,1) using Ackerman’s function.

A (1, 1) = A(m, n)
= A (m-1, A (m, n-1))
= A (1-1, A (1, 1-1))
= A (0, A (1, 0))
= A (0, A (m-1, 1))
= A (0, A (1-1, 1))
= A (0, A (0, 1))
= A (0, n+1)
= A (0, 1+1)
= A (0, 2)
= n+1
=2+1
=3

19
Data Structures and Applications, MUSE

Queues

Definition

A queue is linear data structure or abstract data type of elements in the insertion can take place at
only one end called “rear” and deletion can take place at only on end called “front”.

The insertion and deletion of elements in queue will follow “first in first out (FIFO)” or “last in last or
(LILO)”.

The three basic operations of queue are,


• Enqueue (insert)-- inserts element onto the queue at “rear”.
• Dequeue (delete)-- delete element at “front”.
• Traverse (display)-- display the contents of queue.

Types of Queues

• Ordinary or Normal or Linear Queue


• Circular Queue
• Double ended Queue
• Priority Queue

Applications of queue
It is used when you want share serve the request on the single shared resource.
• Printers: shared with different computers.
• Customer care service: to put the people on hold until they representative attains the call.
• Processors: is placed in queue (ex: in operating systems and job scheduling process).

Queue implementation using arrays


#define N 5
int queue[5];
int front = -1;
int rear = -1;
void main()
{
enqueue(10);

20
Data Structures and Applications, MUSE

enqueue(20);
enqueue(30);
display();
peek();
dequeue();
peek();
display();
}

void enqueue(int x)
{
if (rear == N-1)
printf(“overflow condition\n”);
elseif(front == -1 && rear == -1)
{
front = rear = 0;
queue[rear] = x;
}
else
{
rear++;
queue[rear]=x;
}
}

void dequeue()
{
if (front == -1 && rear == -1)
printf(“underflow condition\n”);
elseif(front == rear)
front = rear = -1;
else
{
printf(“%d”, queue[front]);
front++;
}

void display()
{
if (front == -1 && rear == -1)
printf(“queue is empty\n”);
else
{
for(i=front; i<rear+1; i++)
printf(“%d”, queue[i]);
}
}
void peek()
{
if(front == -1&&rear == -1)
printf(“queue is empty\n”);
else
printf(“%d”, queue[front]);
}

21
Data Structures and Applications, MUSE

Output for enqueue

Output for display

10 20 30

Output for peek

10

Output for dequeue

10

Output for peek

20

Output for display

20 30

22
Data Structures and Applications, MUSE

Circular queue implementation using arrays


#define N 5
int queue[5];
int front = -1;
int rear = -1;
void main()
{
enqueue(10);
enqueue(20);
enqueue(30);
enqueue(40);
enqueue(50);
display();
dequeue();
dequeue();
enqueue(60);
enqueue(70);
enqueue(80);
}

void enqueue(int x)
{
if (front == -1 && rear == -1)
{
front = rear = 0;
queue[rear] = x;
}
elseif((rear+1)%N)==front))
printf(“queue is full\n”);
else
{
rear = (rear+1)%N;
queue[rear] = x;
}
}

void dequeue()
{
if (front == -1 && rear == -1)
printf(“queue is empty\n”);
elseif(front == rear)
front = rear = -1;
else
{
printf(“%d”, queue[front]);
front=(front+1)%N;
}
}

void display()
{
if (front == -1 && rear == -1)
printf(“queue is empty\n”);

23
Data Structures and Applications, MUSE

else
{
for(i=front; i<rear+1; i++)
printf(“%d”, queue[i]);
}
}
void peek()
{
if(front == -1&&rear == -1)
printf(“queue is empty\n”);
else
printf(“%d”, queue[front]);
}

Output for enqueue

Output for display

10 20 30 40 50

Output for dequeue

10

24
Data Structures and Applications, MUSE

20

Output for enqueue

Output for enqueue

Output for enqueue


queue id full

Circular queue implementation using dynamic arrays


#define N 5
int queue[5];
int front = -1;
int rear = -1;
int *q;

void enqueue(int x)
{
if((rear+1)%N)==front))
{
printf(“queue is full and increase the by 1\n”);
N++;
q = (int*) realloc (q, N* sizeof(int));
for(i=N-2; i>front; i--)
{
q[i+1]=q[i];
}
front++;
else
{

25
Data Structures and Applications, MUSE

rear = (rear+1)%N;
queue[rear] = x;
}
}

void dequeue()
{
if (front == -1 && rear == -1)
printf(“queue is empty\n”);
else
{
printf(“deleted element is %d”, queue[front]);
N--;
q = (int*) realloc (q, N* sizeof(int));
for(i=front-1; i<N; i++)
q[i]=q[i+1];
front--;
}
}

Dequeues (Doble-ended queue or deck or Deque)

A deque is linear list in which elements can be added or removed at either end. Insertion is possible at
both front and rear end. Similarly, deletion can be done at front and rear end.

Types of deque

• Input restricted
• Output restricted

Input restricted

output restricted

26
Data Structures and Applications, MUSE

Deque memory representation

It can be implemented using circular arrays and linked list.

Deque operations

The operations performed are:


insertfront();
insertrear(); enqueue

deletefront();
deleterear(); dequeue

getfront(); == isfull()
getrear(); ==isempty()

Applications of deque

• Palindrome check. Ex: radar radar


• Redo and Undo mechanism in Microsoft word. Ex: ctrl+z
• Multi processors scheduling.

Implementation of deque(double ended queue) using circular arrays

#define N 5
int deque[5];
int f = -1;
int r = -1;
void main()
{
enqueuefront(1);
enqueuefront(2);
enqueuerear(-1);
enqueuerear(0);
enqueuefront(5);
enqueuerear(4);
display();
getfront();
getrear();
dequeuefront();
dequeuerear();
dequeuefront();
}

void enqueuefront(int x)
{
if(f==0&&N-1|| front==rear+1)
printf(“deque is full\n”);
elseif(f==-1 &&r==-1)
{
f=r=0;
deque[f] = x;
}
elseif(f==0)

27
Data Structures and Applications, MUSE

{
f=N-1;
deque[f]=x;
}
else
{
f--;
deque[f]=x;
}
}

void enqueuerear(int x)
{
if(f==0&&N-1|| front==rear+1)
printf(“deque is full\n”);
elseif(f==-1 &&r==-1)
{
f=r=0;
deque[f] = x;
}
elseif(r==N-1)
{
r=0;
deque[f]=x;
}
else
{
r++;
deque[r]=x;
}
}

void display()
{
int i=f;
while(i!=rear)
{
printf(“%d”, deque [i])
i=(i+1)%N;
}
printf(“%d”, deque[rear]);
}

void getfront()
{
printf(“%d”, deque[front]);
}

void getrear()
{
printf(“%d”, deque[rear]);
}

void dequeuefront()
{

28
Data Structures and Applications, MUSE

if(f==-1&& r==-1)
printf(“deque is full\n”);
elseif(f==r)
f=r=-1;
elseif(f==N-1)
{
printf(“%d”, deque[f]);
f=0;
}
else
{
printf(“%d”, deque[f]);
f++;
}
}

void dequeuerear()
{
if(f==-1&& r==-1)
printf(“deque is full\n”);
elseif(f==r)
f=r=-1;
elseif(r==0)
{
printf(“%d”, deque[r]);
r=N-1;
}
else
{
printf(“%d”, deque[r]);
r--;
}
}

Output enqueuefront

29
Data Structures and Applications, MUSE

Output enqueuerear

Output enqueuefront

queue is full

Output display

5 2 1 -1 0

Output getfront

Output getfront

Output dequeuefront

Output dequeuerear

30
Data Structures and Applications, MUSE

Output dequeuefront

Priority Queue

It is special type of queue in which each element is associated with a “priority value”. Elements are
served on the basis of their priority. i.e., higher priority elements are served first.

If the elements with the same priority occur, they are served according to their order (FIFO).

Types of priority queue

• Ascending order priority queue


Insertion is arbitrary deletion is from smallest element.
Lower priority = to higher priority
• Descending order priority queue
Insertion is arbitrary deletion is from largest element.
Higher priority number = to higher priority

Implementation of priority queue is three ways,

• Arrays
• Linked list
• Heap

Function for priority queue (ascending priority queue)

void insert()
{
int i;
if (r== N-1)
printf(“queue is full\n”);
i=r;
while(i>=0&& x<q[i])
{
q[i+1] = q[i];
i--;
}
q[i+1]=x;
r=r+1;
}

31
Data Structures and Applications, MUSE

Function for priority queue (descending priority queue)

void insert()
{
int i;
if (r== N-1)
printf(“queue is full\n”);
i=r;
while(i>=0&& x>q[i])
{
q[i+1] = q[i];
i--;
}
q[i+1]=x;
r=r+1;
}

Priority queue using arrays (Ascending priority queue)

Priority queue using Linked List (Ascending priority queue)

32
Data Structures and Applications, MUSE

A Mazing Problem
A maze is confusing network of paths through which it is very difficult to find one’s way. A maze is
represented as 2D array in which,

• Zero’s represent open path.


• One’s represent barriers.

Example: Entrance for rat

• We assume that rat starts at the top left and is to exit at bottom right.
• The maze can be represented as 2D array, the location of the rat in the maze can be
determined by row and column position.
• Let (i,j) is the current position of the rat in maze where ‘I’ is the row index and j is the column
index.
• Rat can move in the 8 possible directions N, NE, E, SE, S, SW, W and NW respectively.

• The rat can move in all 8 directions but this not true all time. If the position of rat is on any
border, then it cannot move in all directions. So to avoid checking the border conditions, we
can surround the maze by adding one’s to above figure indicate the barriers for the entrance
of rat.

33
Data Structures and Applications, MUSE

Either we add -1, 1 or 0 to (i , j) to get the new position. These values that we add to find the new
position is called offset values.

Name Direction Vertical Horizontal


N 0 (i-1, j) -1 0
NE 1 (i-1, j+1) -1 1
E 2 (i, j+1) 0 1
SE 3 (i+1, j+1) 1 1
S 4 (i+1, j) 1 0
SW 5 (i+1, j-1) 1 -1
W 6 (i, j-1) 0 -1
NW 7 (i-1, j-1) -1 -1

Multiple stacks

In many applications and algorithm several stacks are needed. For these we can create more than one
stack in same array. This technique is called multiple stack.

• For ‘n’ number of stacks, one has to divide the available array into ‘n’ equal segments having
equal memory.
• If size of stack is known, then the division of available memory is done according to the size
of the stack.

Size, m = 16 (array size)


No. of stack n = 4
m/n = 16/4 = 4

34
Data Structures and Applications, MUSE

To find the initial value of top of each of stack i.e., top[0], top[1], top[2], top[3] use the expression,
top[i] = m/n * i-1
where, i=0 to n.

i.e., i=0; top[0] = 16/4*0-1 =-1


i=1; top[1] = 16/4*1-1 = 3
i=2; top[2] = 16/4*2-1 = 7
i=3; top[3] = 20/4*0-1 =11
So,
for(i=0; i<=n; i++)
{
top[i] = m/n*i-1;
}

To find the boundary of each of the stack, cop initial value of top[0] to boundary[0] and so on,

for(i=0; i<=n; i++)


{
boundary[i] = top[i];
}

Function for push element in multiple stack


void push()
{
if top[i]==boundary [i+1])
printf(“stack is full\n”,i);
stack[++top[i]] = x;
}

Function for pop element in multiple stack


void pop()
{
if top[i]==boundary [i])
printf(“stack is empty\n”,i);
printf(“deleted element = %d”, stack[top[i]--);
}

35
Data Structures and Applications, MUSE

Function for display element in multiple stack


void display()
{
if top[i]==boundary [i])
printf(“stack is empty\n”,i);
for(i=boundary[i]+1; i<=top[i]; i++)
printf(“%d\n”stack[i]);
}

36

You might also like