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

Module 2

This document discusses stacks and queues. It begins with an introduction to stacks and queues, explaining that they are linear data structures that restrict insertions and deletions to one end. It then covers stack operations like push, pop and peek. Implementation of stacks using arrays and dynamic arrays is described. Applications of stacks like expression evaluation, recursion and system stack are explained. The document also covers queues, conversions between infix, postfix and prefix notation, and evaluation of postfix expressions.

Uploaded by

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

Module 2

This document discusses stacks and queues. It begins with an introduction to stacks and queues, explaining that they are linear data structures that restrict insertions and deletions to one end. It then covers stack operations like push, pop and peek. Implementation of stacks using arrays and dynamic arrays is described. Applications of stacks like expression evaluation, recursion and system stack are explained. The document also covers queues, conversions between infix, postfix and prefix notation, and evaluation of postfix expressions.

Uploaded by

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

R N S INSTITUTE OF TECHNOLOGY

Dr. VISHNUVARDHAN ROAD, CHANNASANDRA, RR NAGAR POST, BANGALORE -560 098

Department of Information Science & Engineering

Data structures and Applications [18CS32]


STACKS AND QUEUES

MODULE 2
CONTENTS
⚫ Stacks: Definition, Stack Operations, Array
Representation of Stacks, Stacks using
Dynamic Arrays, Stack Applications: Polish
notation, Infix to postfix conversion,
evaluation of postfix expression.
⚫ Recursion: Factorial, GCD, Fibonacci
Sequence, Tower of Hanoi, Ackerman's
function.
⚫ Queues: Definition, Array Representation,
Queue Operations, Circular Queues,
Circular queues using Dynamic arrays,
Dequeues, Priority Queues, A Mazing
Problem. Multiple Stacks and Queues.
INTRODUCTION
⚫ The linear lists and linear arrays allows one
to insert and delete elements at any place
in the list- at the beginning, at the end or in
the middle
⚫ There are certain frequent situations when
one wants to restricts insertions and
deletions so that they can take place only at
the beginning or the end of the list, not in
the middle
⚫ They are STACKS and QUEUES
STACKS
⚫ Stack is a linear list in which addition and
deletion of elements are restricted to one end
called the top.
⚫ A linear list is a list in which each element has
unique successor.
⚫ A linear list may be a restricted list or a
general list.
⚫ Stack is also called as
o LIFO Data structure
o Push down list
⚫ Stack belongs to non-primitive linear
data structure.
STACKS
Top an-1
an-2
…..
….
a1
a0
Figure 1a: Stack S

⚫ Consider a stack s=(a0,a1,….,an-1).here a0 is

the bottom element , an-1 is the top element


and generally, element ai is on the top of
element ai-1,0<i<n.
STACKS
⚫ If A, B, C, D, E are the elements added into stack in
that order then E is the first element to be deleted.
Figure shows insertion and deletion of elements
from the stack.

Figure 1b: Insertion and deletion of elements from


the stack
Examples for STACKS

Figure 2: Stack of cards and plates

Figure 3: Stack representation


SYSTEM STACK
⚫ A stack used by a program at run-time to
process function-calls is called
system-stack.
⚫ Initially, stack-frame/activation record for
invoked-function contains only pointer to
previous stack-frame & return-address.
⚫ The previous stack-frame pointer points
to the stack-frame of the
invoking-function, while return-address
contains the location of the statement to
be executed after the function terminates.
⚫ If one function invokes another function,
local variables and parameters of the
SYSTEM STACK
⚫ A new stack-frame is then created for the
invoked-function & placed on top of the
system-stack.
⚫ When this function terminates, its stack-frame is
removed (and processing of the invoking-function,
which is again on top of the stack, continues).
⚫ Frame-pointer(fp) is a pointer to the current
stack-frame.
STACK ADT
STACK ADT
Stack Operations
⚫ PUSH – Used to insert an element into
Stack.
⚫ POP – Used to delete an element from
Stack.
⚫ Stack top – used to copy the item at the top
of Stack but does not delete it.
⚫ peek() − get the top data element of the
stack, without removing it.
⚫ isFull() − check if stack is full or overflow.
⚫ isEmpty() − check if stack is empty or
underflow.
Stack Operations
PUSH Operation
⚫Step 1 − Check if stack is full.
⚫Step 2 − If stack is full, produce error and
exit.
⚫Step 3 − If stack is not full, increment top to
point next empty space.
⚫Step 4 − Add data element to the stack
location, where top is pointing.
⚫Step 5 − return success
Stack Operations
Push Operation
Stack Operations
POP Operation
•Step 2 − If stack is empty, produce error and exit.
•Step 1 − Check if stack is empty.
•Step 3 − If stack is not empty, access the data element at which top is
pointing.
•Step 4 − Decrease the value of top by 1.
•Step 5 − return success.

Figure 6: pop operation


IMPLEMENTATION OF STACK
OPERATIONS
IMPLEMENTATION OF STACK
OPERATIONS
⚫ The easiest way to implement stack ADT is
using one-dimensional array.
⚫ stack[ MAX_STACK_SIZE],where
MAX_STACK_SIZE =maximum number
of entries in the stack.
⚫ • The first element of the stack is stored in
stack [0],stack[1] is second element and
stack[i-1] is the ith element.
⚫ • ’top’ points to the top element in the stack
(top=-1 to denote an empty stack).
⚫ • The CreateS() function can be
implemented as follows and it creates stack
of size 100.
IMPLEMENTATION OF STACK
OPERATIONS

⚫ Function push/add() checks to see if the stack is


full. If it is, it calls stack_full(), which prints an
error message and terminaexecutionWhen the
stack is not full, we increment top and assign item
to stack[top].
IMPLEMENTATION OF STACK
OPERATIONS
Function pop/delete()
void stack_full()
{ printf(stderr,”stack is full, can’t add
element”);
exit(EXIT_FAILURE);
}
void stack_empty ()
{ printf(stderr,”stack is empty, can’t delete
element”);
exit(EXIT_FAILURE);
}
STACK USING DYNAMIC
ARRAYS
⚫ Shortcoming of static stack
implementation: is the need to know at
compile-time, a good bound
(MAX_STACK_SIZE) on how large the
stack will become.
⚫ This shortcoming can be overcome by
using a dynamically allocated array for the
elements & then increasing the size of the
array as needed Initially, capacity=1 where
capacity=maximum no. of stack-elements
that may be stored in array.
STACK USING DYNAMIC
ARRAYS
The CreateS() function can be implemented as
follows

The CreateS() function can be implemented as follows


STACK USING DYNAMIC
ARRAYS

void stack_full()
{ printf(stderr,”stack is full, can’t add element”);
exit(EXIT_FAILURE);
}

void stack_empty ()
{ printf(stderr,”stack is empty, can’t delete element”);
exit(EXIT_FAILURE);
}
APPLICATIONS OF STACKS
⚫ Stack is used by compilers to check for
balancing of parentheses, brackets and
braces.
⚫ Stack is used to evaluate a postfix
expression.
⚫ Stack is used to convert an infix expression
into postfix/prefix form.
⚫ In recursion, all intermediate arguments
and return values are stored on the
processor’s stack.
⚫ During a function call the return address
and arguments are pushed onto a stack and
on return they are popped off.
EXPRESSIONS
⚫ An algebraic expression is a legal
combination of operators and operands.
“The sequence of operators and operands
that reduces to a single value after
evaluation is called Expression”.
⚫ Operand is the quantity on which a
mathematical operation is performed.
Operand may be a variable like x, y, z or a
constant like 5, 4, 6 etc.
⚫ Operator is a symbol which signifies a
mathematical or logical operation between
the operands. Examples of familiar
operators include +, -, *, /, ^ etc.
postfix and prefix notations:
⚫ Infix: It is the form of an arithmetic
expression in which we fix (place) the
arithmetic operator in between the two
operands. Example: (A + B) * (C - D)
⚫ Prefix: It is the form of an arithmetic
notation in which we fix (place) the
arithmetic operator before (pre) its two
operands. The prefix notation is called as
polish notation (due to the polish
mathematician Jan Lukasiewicz in the year
1920). Example: * + A B – C D
⚫ Postfix: It is the form of an arithmetic
expression in which we fix (place) the
CONVERSION FROM INFIX TO
POSTFIX
⚫ Scan the infix expression from left to right.
⚫ If the scanned symbol is left parenthesis,
push it onto the stack.
⚫ If the scanned symbol is an operand, then
place directly in the postfix expression
(output).
⚫ If the symbol scanned is a right
parenthesis, then go on popping all the
items from the stack and place them in the
postfix expression till we get the matching
left parenthesis.
⚫ the scanned operator onto the stack
otherwise, push the scanned operator onto
CONVERSION FROM INFIX TO
POSTFIX
⚫ If the scanned symbol is an operator, then
go on removing all the operators from the
stack and place them in the postfix
expression, if and only if the precedence of
the operator which is on the top of the
stack is greater than (or greater than or equal)
to the precedence
Operators of the precedence
scanned operator
and push ^% 4
* / 3
+ - 2
# ( 1
Example To convert infix to
postfix
⚫ Convert the following infix expression A + B * C – D / E * H into
its equivalent postfix expression
EVALUATION OF POSTFIX
EXPRESSION
Steps for evaluating postfix expression
⚫ Scan the symbol from left to right.
⚫ If the scanned-symbol is an operand, push
it on to the stack.
⚫ If the scanned-symbol is an operator, pop
two operands from the stack. The first
popped operand acts as operand2 and the
second popped operand act as operand
1.Now perform the indicated operation and
Push the result on to the stack.
⚫ Repeat the above procedure till the end of
input is encountered
EXAMPLE
Evaluate the postfix expression: 6 5 2 3 + 8 * + 3 + *
Underflow and Overflow
⚫ Underflow is a condition occurs if we try to
POP item from the empty STACK
⚫ Overflow is a condition occurs if we try to
PUSH an ITEM to the STACK which is
already full
STACK
E D C B A FULL
STACK
OVERFLOW

<--TO
P
POP

D <--TOP

STACK
EMPT
Y STACK UNDERFLOW
Array representation of Stack
⚫ Array can be used as home to the stack
⚫ Data structure
#define MAX STK 25
typedef struct {
int top;
char item[MAXSTK];
}STACK;
STACK s;
s.top= -1;

A B C D

top
Stack after – PUSH( ‘A’), PUSH( ‘B’), PUSH( ‘C’),
PUSH( ‘D’)
Evaluation of expression
⚫ Three levels of precedence for the 5 binary
operations
⚫ Highest : Exponentiation ( ) or ($) or (^) or (**)
⚫ Next Highest : Multiplication (*) and
Division(/)
⚫ Lowest: Addition (+) and Subtraction (-)
Evaluation of expression
⚫ 2 3 + 5 * 2 2 - 12 / 6
⚫ To evaluate expression is traversed three
times, each time corresponding to the level
of precedence of the operations
⚫ After first traversal expression reduces to 8
+ 5 * 4 -12 / 6
⚫ After Second traversal expression reduces
to 8 + 20 – 2
⚫ After Third traversal expression reduces to
26
Arithmetic Expression
Representation
⚫ INFIX
⚫ PREFIX – POLISH
⚫ POSTFIX – REVERSE POLISH or SUFFIX
INFIX POLISH REVERSE
POLISH
A+B*C +A*BC ABC*+

(A+B)*C *+ABC AB+C*


⚫ Note
⚫ The order of operators and operands in an INFIX expression does
not uniquely determine the order in which operations to be
performed
⚫ In POLISH and REVERSE POLISH notation the order in which
the operations to be preformed is completely determined by the
position of the operators and the operands in the expression
⚫ No parenthesis required to determine the order
⚫ Computer evaluates arithmetic expressions in INFIX notation in
two steps
⚫ 1) Convert INFIX expression to POSTIX
⚫ 2) Evaluate the POSTFIX expression
Converting infix to postfix and Prefix
-Examples
INFIX
1. A+B*C : A+[BC*]ABC*+ is POSTFIX
A+[*BC] +A*BC is PREFIX
2 (A+B)*C : [AB+]*C AB+C* is POSTFIX
[+AB]*C *+ABC is PREFIX
3 A$B*C-D+E/F/G+H: [AB$]*C-D+E/F/G+H
(Converting to postfix )
[AB$C*]-D+[EF/G/]+H
AB$C*D-EF/G/+H+ is
POSTFIX
(Converting to prefix) [$AB]*C-D+E/F/G+H
[*$ABC]-D+[//EFG]+H
++-*$ABCD//EFGH is PREFIX
Converting infix to postfix and Prefix
-Examples
INFIX to POSTFIX Conversion
Given Infix Expression: ((A+B)*C-(D-E))$(F+G)
([AB+]*C-[DE-])$[FG+]
([AB+C*]-[DE-])$[FG+]
[AB+C*DE--]$[FG+]
AB+C*DE--FG+$ is Post expression
INFIX to PREFIX Conversion
Given Infix Expression: ((A+B)*C-(D-E))$(F+G)
([+AB]*C-[-DE])$[+FG]
([*+ABC]-[DE-])$[+FG]
[-*+ABC-DE]$[+FG]
$-*+ABC-DE+FG is Prefix expression
Evaluation of postfix expression
To evaluate postfix expression, create an
empty stack
⚫ Scan from left to right to get a token
⚫ If token is operand place on the stack
⚫ If token is an operator remove two
operands from the stack
⚫ Perform the operation on that operands
corresponding to the operator
⚫ Result is placed back on the stack
⚫ Continue the procedure until we reach end
of the expression
⚫ Remove the answer from the stack.
expression
⚫ EVALUATE (P)
This algorithm finds the VALUE of an arithmetic expression P
written in postfix notation
1. Append a right parenthesis “)” at the end of P.[this acts as a
sentinel]
2. Scan P from left to right and repeat Steps 3 and 4 for each
element of P until the sentinel “)” is encountered
3. If an operand is encountered, place it on to STACK
4. If an operator is encountered, then,
(a) Remove the two top elements of STACK, where A is the top
element and B is the next-to-top element
(b) Evaluate B operator A
(c) Place the result of (b) back on stack
[End of If structure]
[End of Step 2 loop]
5. Set VALUE equal to the top element on STACK
6. Exit
Evaluating Given Postfix Expression :
Example: 6 2/ 3– 42*+
Token Stack top
[0] [1] [2]
Initially -1
6 6 0
2 6 2 1
/ 3 0
3 3 3 1
- 0 0
4 0 4 1
2 0 4 2 2
* 0 8 1
+ 8 0
eos -1 Answer=8
Postfix Evaluation
Postfix expression
62/3–42*+
stack

Postfix Expression
2/3–42*+

Token
Operand,
6 PUSH onto
stack
stack

Postfix Expression
2/3–42*+

6
stack

Postfix Expression
/3–42*+

Token
Operand,
2 PUSH onto
stack

6
stack

Postfix Expression
/3–42*+

2
6
stack

Postfix Expression
3–42*+

Token
Operator, POP
/ 2 top elements
from the stack
2
and store it in
6 opnd2 and
opnd1
stack

Postfix Expression
3–42*+

opnd1 opnd2
6 2
stack

Postfix Expression
3–42*+
Evaluate
opnd1 opnd2
opnd1
6 2 operator
opnd2
stack

Postfix Expression
3–42*+

opnd1 opnd2 Res


6 / 2 3

PUSH Res onto stack


stack

Postfix Expression
3–42*+

3
stack

Postfix Expression
–42*+

Token
Operand,
3 PUSH onto
stack

3
stack

Postfix Expression
–42*+

3
3
stack

Postfix Expression
42*+

Token
Operator, POP
- 2 top elements
from the stack
3
and store it in
3 opnd2 and
opnd1
stack

Postfix Expression
42*+
Evaluate
opnd1 opnd2
opnd1
3 3 operator
opnd2
stack

Postfix Expression
42*+

opnd1 opnd2 Res


3 - 3 0

PUSH Res onto stack


stack

Postfix Expression
42*+

0
stack

Postfix Expression
2*+

Token
Operand,
4 PUSH onto
stack

0
stack

Postfix Expression
2*+

4
0
stack

Postfix Expression
*+

Token
Operand,
2 PUSH onto
stack
4
0
stack

Postfix Expression
*+

2
4
0
stack

Postfix Expression
+

Token
Operator, POP
2 * 2 top elements
from the stack
4
and store it in
0 opnd2 and
opnd1
stack

Postfix Expression
+
Evaluate
opnd1 opnd2
opnd1
4 2 operator
opnd2

0
stack

Postfix Expression
+

opnd1 opnd2 Res


4 * 2 8

PUSH Res onto stack


stack

Postfix Expression
+

8
0
stack

Postfix Expression

Token
Operator, POP
+ 2 top elements
from the stack
8
and store it in
0 opnd2 and
opnd1
stack

Postfix Expression

Evaluate
opnd1 opnd2
opnd1
0 8 operator
opnd2
stack

Postfix Expression

opnd1 opnd2 Res


0 + 8 8

PUSH Res onto stack


stack

Postfix Expression

8
process
⚫ Since the order of operands in the infix and postfix
expression is same ,Scan the input infix expression from
left to right
⚫ During the scan ,operands are passed directly to the
postfix expression as they are encountered.
⚫ When the operators are encountered it is placed in the
postfix expression depending on its precedence
⚫ To get the higher precedence first in the postfix
expression, we save the operators until we know their
correct placement. To do this we follow the following
procedure
⚫ Check the precedence of the incoming operator with the
stack top.
if precedence of incoming operator is not higher than the
operator at the stack top repeatedly pop the stack and place
the popped item to the postfix expression.
⚫ place incoming operator on the stack.
⚫ Once you reach end of infix expression repeatedly pop
the stack and place the popped item to the postfix
⚫ In a parenthesized infix expression the
expression inside the parenthesis
should be converted first.
⚫ Hence we stack the operators until we
reach the right parenthesis
⚫ As we encounter left parenthesis during
scanning, we must place it on the stack
what ever may be the stack top. Once
left parenthesis becomes the stack top,
what ever may be the operators other
than the right parenthesis ,the operator
should be placed on the stack
⚫ Hence left parenthesis need to behave
like high precedence when it is out
Infix to postfix conversion
algorithm
⚫ Reverse polish(Q, P) // Q is an arithmetic expression in
INFIX notation
Algorithm converts INFIX expression Q into POSTFIX
expression P
1 push “(“ onto STACK, and append “)” to the end of Q
2 scan Q left to right and repeat Steps 3 to 6 for each
element of Q until the STACK is empty
3 If an operand is encountered place it in the POSTFIX
expression P
4 If an left parenthesis is encountered, push it on to the
STACK
Complexity – Ø(n), where n be the number of tokens in the
expression
Infix to postfix conversion
algorithm
5 If an operator is encountered, call it as incoming
operator, then:
a) Repeatedly pop from the STACK and place it in the P
which has the same precedence or higher precedence
than the incoming operator
b) b) Place the incoming operator to the STACK
[End of IF]
6 If a right parentheses is encountered
a) Repeatedly pop from the STACK and place it in the
P until left parenthesis is encountered
b) Remove the left parenthesis
[ End of If ]
[ End of Step 2 loop ]
Infix to postfix conversion
infixVect
(a+b-c)*d–(e+f)

postfixVect
Infix to postfix conversion
stackVect

infixVect
a+b-c)*d–(e+f)

postfixVect

(
Infix to postfix conversion
stackVect

infixVect
+b-c)*d–(e+f)

postfixVect
a

(
Infix to postfix conversion
stackVect

infixVect
b-c)*d–(e+f)

postfixVect
a

+
(
Infix to postfix conversion
stackVect

infixVect
-c)*d–(e+f)

postfixVect
ab

+
(
Infix to postfix conversion
stackVect

infixVect
c)*d–(e+f)

postfixVect
ab+

-
(
Infix to postfix conversion
stackVect

infixVect
)*d–(e+f)

postfixVect
ab+c

-
(
Infix to postfix conversion
stackVect

infixVect
*d–(e+f)

postfixVect
ab+c-
Infix to postfix conversion
stackVect

infixVect
d–(e+f)

postfixVect
ab+c-

*
Infix to postfix conversion
stackVect

infixVect
–(e+f)

postfixVect
ab+c-d

*
Infix to postfix conversion
stackVect

infixVect
(e+f)

postfixVect
ab+c–d*

-
Infix to postfix conversion
stackVect

infixVect
e+f)

postfixVect
ab+c–d*

(
-
Infix to postfix conversion
stackVect

infixVect
+f)

postfixVect
ab+c–d*e

(
-
Infix to postfix conversion
stackVect

infixVect
f)

postfixVect

+ ab+c–d*e

(
-
Infix to postfix conversion
stackVect

infixVect
)

postfixVect

+ ab+c–d*ef

(
-
Infix to postfix conversion
stackVect

infixVect

postfixVect
ab+c–d*ef+

-
Infix to postfix conversion
stackVect

infixVect

postfixVect
ab+c–d*ef+-
Infix to Postfix Conversion using Stack:
Example

Infix Expression : A *(B + C) / D


Token Stack top Postfix
[0] [1] [2]
A -1 A
* * 0 A
( * ( 1 A
B * ( 1 AB
+ * ( + 2 AB
C * ( + 2 A BC
) * 0 ABC+
/ / 0 ABC+*
D / 0 ABC+*D
eos -1 ABC+*D/
Implementation
⚫ Since left parenthesis need to behave like high
precedence when it is out from the stack and
low precedence operator when it is on the
stack, this may be implemented by defining 2
precedence levels.
⚫ 1) In Stack Precedence ISP
⚫ 2) In Coming Precedence ICP as given below
Typedef Enum { lparen, rparen, plus, minus, times, divide,
mod, eos,operand} precedence;
⚫ int ISP [ ] = { 0,19, 12, 12, 13, 13, 13, 0};
⚫ int ICP [ ] = { 20,19, 12, 12, 13, 13, 13, 0};
⚫ Note: Here stack is used to store mnemonic
for token.
Reversing Data

⚫ Reversing a list
⚫ Reversing Data: We can use stacks to reverse
data.
(example: files, strings)
Very useful for finding palindromes.

Pseudocode:
1) read (data)
2) loop (data not EOF and stack not full)
1) push (data)
2) read (data)
3) Loop (while stack notEmpty)
1) pop (data)
2) print (data)
⚫ Converting Decimal to Binary: Consider the
following pseudo code
1) Read (number)
2) Loop (number > 0)
1) digit = number modulo 2
2) print (digit)
3) number = number / 2
// from Data Structures by Gilbert and Forouzan

The problem with this code is that it will print the binary
number backwards. (ex: 19 becomes 11001000 instead of
00010011. )
To remedy this problem, instead of printing the digit right
away, we can
push it onto the stack. Then after the number is done being
converted, we
pop the digit out of the stack and print it.
Parsing Data

⚫ Parsing is any logic that breaks data into


independent pieces for further processing.
One common problem is unmatched
parenthesis in an algebraic expression.
This error can checked by using stack
Backtracking Steps.

⚫ Goal seeking
⚫ Decision Analysis
Recursion
⚫ Recursion is a process in which a
procedure calls itself. In C the function that
calls itself is called as recursive function.
⚫ Two types
1. Direct recursion – if the function A calls
function A itself
2. Indirect recursion – if function A calls
function B, function B calls function A (
recursive chain)
⚫ A recursive procedure must have the
following 2 properties
1. There must be base criteria ( terminating
Recursion
Function.
void recursion()
{
recursion(); /* function calls itself */
}
void main()
{
recursion();
}
The C programming language supports
recursion, i.e., a function to call itself.
RECURSION PROPERTIES
⚫ Base criteria − There must be at least one
base criteria or condition, such that, when
this condition is met the function stops
calling itself recursively.

⚫ Recursive criteria − the recursive calls


should progress in such a way that each
time a recursive call is made it comes
closer to the base criteria.
Recursion - Examples
⚫ Recursion is implemented by means of Stacks.
⚫ Factorial function – f(n) = n*f(n-1) for n != 0
f(n) = 1 for n = 0
Algorithm:
FACTOIAL (FACT, N)
This procedure calculates N! and returns the value
in the variable FACT
1) If N = 0, then Set FACT := 1 and Return
2) Call FACTORIAL (FACT, N-1)
3) Set FACT := N * FACT
4) Return
Fibonacci number
⚫ Fibonacci sequence- fib(n) = fib(n-1) + fib (n-2)
for n > 1
fib(n) = n for
n=0 or n=1
Algorithm:
FIBONACCI (FIB, N)
This procedure calculates FN and returns the
value in the first parameter FIB
1) In N = 0 or N=1 then: Set FIB := N, and Return.
2) Call FIBONACCI (FIBA, N-2)
3) Call FIBONACCI (FIBB, N-1)
4) Set FIB := FIBA + FIBB
5) Return
Fibonacci number
The following example calculates the factorial of a given number using a
recursive function
#include <stdio.h>
int factorial(unsigned int n)
{
if(n <= 1)
{
return 1;
}
return n * factorial(n - 1);
}
void main()
{
int n,res;
printf(“\n enter the value for n”);
scanf(“%d”,&n);
res=factorial(n);
printf("Factorial of %d is %d\n", n, res); }
GCD
⚫ GCD – gcd(m, n) = gcd( n, m mod n) for n != 0
gcd (m,n) = m for n = 0
Algorithm:
GCD(m, n)
This procedure calculates the GCD of two
numbers m, n and Returns
the value
1. If n=0 then, Set gcd := m; Return gcd
2. Call GCD ( n, m mod n)
3. End
GCD OF TWO NUMBERS

⚫ GCD is calculated by using


GCD(a,b)=GCD(b,a mod b).
⚫ Euclid’s algorithm
⚫ Take a and b, and calculate the remainder
by performing a%b.
⚫ Assign the value of b to a and value of
remainder to b.
⚫ Repeat the steps 1 & 2 until value of b
becomes 0.
⚫ If b=0, then return value of ‘a’ as the GCD
value of a & b.
#include <stdio.h>
int gcd(int m, int n);
void main()
{
int a, b,res;
printf("Enter two positive integers: ");
scanf("%d %d", &a, &b);
res=gcd(a,b);
printf("G.C.D of %d and %d is %d.", n1, n2, res);
}
int gcd(int a, int b)
{
int rem;
if (b==0) Output
return a; Enter two positive integers:
else 366 60
{ G.C.D of 366 and 60 is 6
rem=a%b;
a=b;
b=rem;
return gcd(a,b);
}
FIBONACCI SERIES
#include <stdio.h>
int fib(int i)
{
if(i == 0)
{
return 0;
}
if(i == 1)
{
return 1;
}
return (fib(i-1) + fib(i-2));
}
FIBONACCI SERIES

void main()
{
int i;
for (i = 0; i < 10; i++)
{
printf("%d\t", fib(i));
}
}
OUTPUT
0 1 1 2 3 5 8 13 21 34
Tower of Hanoi
Tower of Hanoi, is a mathematical puzzle which
consists of three tower (pegs) and more than one
rings; as depicted in below Figure.

Figure : Tower of Hanoi


Tower of Hanoi
Rules
⚫Only one disk can be moved among the towers
at any given time.
⚫Only the "top" disk can be removed.
⚫No large disk can sit over a small disk.
Algorithm
⚫If we have 2 disks −
⚫First we move the smaller one (top) disk to aux
peg
⚫Then we move the larger one (bottom) disk to
destination peg
⚫And finally, we move the smaller one from aux to
destination peg.
Tower of Hanoi
in recursive way for all given set of disks.
So steps to follow are −
⚫Step 1 − Move n-1 disks from source to aux
⚫Step 2 − Move nth disk from source to dest
⚫Step 3 − Move n-1 disks from aux to dest
⚫A recursive algorithm for Tower of Hanoi can be driven as follows −
START
Procedure tower(disk, source, dest, aux)
if n == 1, THEN
move disk from source to dest
else
tower(n - 1, source, aux, dest) // Step 1
move disk from source to dest // Step 2
tower(n - 1, aux, dest, source) // Step 3
END IF
END Procedure
STOP
Program Tower of Hanoi
#include<stdio.h>
#include<conio.h>
#include <stdio.h>
void towers(int, char, char, char);
int main()
{
int num;
printf("Enter the number of disks : ");
scanf("%d", &num);
printf("The sequence of moves involved in the Tower of
Hanoi are :\n");
towers(num, 'A', 'C', 'B');
getch();
return 0;
}
Program Tower of Hanoi
void towers(int num, char source, char dest, char aux)
{
if (num == 1)
{
printf("\n Move disk 1 from peg %c to peg %c",
source,dest);
return;
}
towers(num - 1, source, aux,dest);
printf("\n Move disk %d from peg %c to peg %c", num,
source, dest);
towers(num - 1, aux, dest, source);
}
Program Tower of Hanoi
⚫ The below figure shows the disks movements in tower of Hanoi for 3
disks

⚫ The below figure shows the recursive function calls in tower of Hanoi
for 3 disks
Recursive solution - Traces for
n=3
Tower(3,A,B,C)
Tower(2,A,C,B)
Tower(1,A,B,C)
Move disk 1 from A to C
Move disk 2 from A to B
Tower(1,C,A,B)
Move disk 1 from C to B
Move disk 3 from A to C
Tower(2,B,A,C)
Tower(1,B,C,A)
Move disk 1 from B to A
Move disk 2 from B to C
Tower(1,A,B,C)
Move disk 1 from A to C
Ackermann function
⚫ It is a function with 2 arguments which can be assigned non
negative integer ( 0, 1,2…..).
⚫ Ackermann function is defined as follows.
A(m, n)= n+1 if m = 0
A(m, n) = A(m-1, 1) if m != 0 and n = 0
A(m, n) = A(m-1, A(m, n-1)) if m != 0 and n != 0

⚫ Ackermann–Péter function, is defined as follows for


nonnegative integers m and n:
Ackermann function
To solve A(2,1) using Ackerman’s function: (m=2, n=1)
A(2,1) = A(1,A(2,0))
= A(1,A(1,1))
=A(1,A(0,A(1,0)))
=A(1,A(0,A(0,1)))
=A(1,A(0,2))
=A(1,3)
=A(0,A(1,2))
=A(0,A(0,A(1,1)))
=A(0,A(0,A(0,A(1,0))))
=A(0,A(0,A(0,A(0,1))))
=A(0,A(0,A(0,2)))
=A(0,A(0,3))
=A(0,4)
A(2,1) = 5
Program:-
#include<stdio.h>
int ackerman(int m, int n)
{
if(m==0)
return (n+1);
if(n==0 && m>0)
return ackerman(m-1,1);
if(m>0 && n>0)
return ackerman(m-1,ackerman(m,n-1));
}
void main()
{
int m,n;
printf(“Enter the value of m and n\n”);
scanf(“%d %d”,&m,&n);
printf(“%d”,ackerman(m,n));
}
QUEUES
⚫ Queue is a linear list of elements in which
insertion and deletion take place at different ends.
The end at which new element is inserted is
called as rear and the end from which element is
deleted is called as front
⚫ Queue has the property - FIFO
⚫ To implement queue front and rear variables are
used

A B C D

front rea
r
ADT QUEUE
APPLICATIONS OF QUEUE
⚫ Serving requests on a single shared
resource, like a printer, CPU task
scheduling etc.
⚫ In real life, Call Center phone systems will
use Queues, to hold people calling them in
an order, until a service representative is
free.
⚫ Handling of interrupts in real-time
systems. The interrupts are handled in the
same order as they arrive, First come first
served
QUEUE BASIC OPERATIONS
⚫ enqueue() − add (store) an item to the
queue.
⚫ dequeue() − remove (access) an item from
the queue.
⚫ peek() − get the element at front of the
queue without removing it.
⚫ isfull() − checks if queue is full.
⚫ isempty() − checks if queue is empty.
int peek()
{
return queue[front];
}
QUEUE BASIC OPERATIONS
isfull()
bool isfull()
{
if(rear == MAXSIZE - 1)
return true;
else
return false;
}
isempty()
bool isempty()
{
if(front < 0 || front > rear)
return true;
else
return false;
}
Enqueue (Insert) Operation
⚫ Step 1 − Check if queue is full.
⚫ Step 2 − If queue is full, produce overflow
error and exit.
⚫ Step 3 − If queue is not full, increment rear
pointer to point next empty space.
⚫ Step 4 − Add data element to the queue
location, where rear is pointing.
⚫ Step 5 − return success
Enqueue (Insert) Operation
void enqueue(int data)
{
if(isfull())
return 0;
rear = rear + 1;
queue[rear] = data;
}
Dequeue (Delete) Operation
⚫Step 1 − Check if queue is empty.
⚫Step 2 − If queue is empty, produce underflow error
and exit.
⚫Step 3 − If queue is not empty, access data where
front is pointing.
⚫Step 4 − Increment front pointer to point next
available data element.
Dequeue (Delete) Operation
Implementation of dequeue() in C programming
language −
int dequeue()
{
if(isempty())
return 0;
int data = queue[front];
front = front + 1;
return data;
}
IMPLEMENTATION OF QUEUE
⚫ The implementation of queue is given below
JOB SCHEDULING
⚫ Queues are used for the creation of a job-queue
by an operating-system. If operating-system does
not use, then the jobs are processed in the order
they enter the system
Circular Queues
When an array is used to have a circular queue : Front is one
position counterclockwise from the first element and rear is current end

[3] [4]

C D
[2] [5]
B E

A F
[6]
[1] G

[0] [7]

Front=0, Rear=7
Circular Queue

[3] [4]
C D
[2] [5]
B E

A F
[6]
[1] G

[0] [7]
Front=0, Rear=7

A B c A A A A A
Circular Queues
⚫ The addition and deletion operations on circular
queue are given below
DYNAMICALLY ALLOCATED
ARRAYS
DYNAMICALLY ALLOCATED
ARRAYS
Program A: Addition operation on CQ
void addq(element item)
{
rear= (rear+1) % capacity;
if(front == rear)
queueFull();
queue[rear]=item;
}
void queueFull( )
{
element *newqueue;
MALLOC(newqueue, 2 * capacity * sizeof(queue));
/*copy from queue to newqueue*/
int start=(front+1)%capacity;
if (start < 2)
/* no wrap around */
copy(queue+start, queue+start+capacity-1, newqueue);
else
{
/* queue wraps around*/
copy(queue+start, queue+start+capacity, newqueue);
copy(queue, queue+rear+1, newqueue+capacity-start);
}
/* switch to newqueue */
front = 2*capacity-1;
rear = capacity-2;
capacity*=2;
free(queue);
queue = newqueue;
}
Dequeues
⚫ Double ended queue is one in which
elements can be inserted or deleted at
either end but not in the middle.
⚫ Deques are implemented as circular queue
⚫ 2 types of dequeue are
1.Output restricted – allows deletion at
only one end (front) but insertion at both
ends
2.Input restricted - allows insertion at
only one end (rear) but deletion at both
ends
Operations on a Dequeue
Operations on a Dequeue
●initialize(): Make the queue empty
●empty(): Determine if queue is empty
●full(): Determine if queue is full
●enqueueF(): Insert an element at the front end of the queue
●enqueueR(): Insert an element at the rear end of the queue
●dequeueR(): Delete the rear element
●dequeueF(): Delete the front element
●print(): Print elements of the queue
PRIORITY QUEUE
⚫ Priority Queue is more specialized data structure
than Queue.
⚫ In Priority queue items are ordered by key value so
that item with the lowest value of key is at front
and item with the highest value of key is at rear or
vice versa.
⚫ priority to item is based on its key value. Lower
the value, higher the priority
Representations of priority queue
queue
⚫ insert / enqueue − add an item to the rear of the
queue.
⚫ remove / dequeue − remove an item from the fro
the queue
⚫ Peek − get the element at front of the queue.
⚫ isFull − check if queue is full.
⚫ isEmpty − check if queue is empty.
Insert / Enqueue Operation
Remove / Dequeue Operation
⚫ Whenever an element is to be removed from queue, queue get the element using item
count. Once the element is removed, Item count is reduced by one.
One-Way List Representation of a Priority Queue

[1] Each node in the list will contain three items of information: an information Field INFO, a
priority number PRN, and a link number LINK

[2] A node X precedes a node Y in the list

(a) when X has higher priority than Y or

(b) when both have same priority but X was added to the list before Y
PRIORITY QUEUE
⚫ Algorithm deletes and processes the first element in a priority queue which

appears in memory as a one way list

1. Set ITEM=INFO [START]

2. Delete first node from the list

3. Process ITEM

4. exit

Algorithm that adds an item with priority number N to a priority queue which is
maintained in memory as a one-way list.

1. Traverse the one-way list until finding a node X, whose priority number

exceeds N. Insert ITEM in front of node X.

2. If no such node is found , insert ITEM as the last element of the list.
MAZE PROBLEM
∙ Mazes have been an intriguing subject for many years. Experimental
psychologists train rats to search mazes for food.

∙ In computer science, maze presents a nice application of stacks. Here, a


program is developed that runs a maze. The program maze can take many false
paths before it finds a correct one, once found it can correctly rerun the maze
without taking false paths.

∙ The representation of maze is done using 2D array in which 0’s represent the
open paths and 1’s the barriers.

∙ The rat starts at the top left and is to exit at the bottom right. With the maze
represented as 2D array, the location of the rat in the maze can at any time be
described by the row and column position,
MAZE PROBLEM
⚫ If X is the spot of our current position, maze[row][col]. Following figure
represents the possible moves from this position. It points to specify the 8
directions of movements:- N, NE, E, SE, S, SW, W, NW as shown.
⚫ The border conditions of the maze can be represented by a border of ones.
Thus, an mxp maze will require an (m+2)x(p+2) array. The entrance is at
position[1][1] and exit at [m][p].
MAZE PROBLEM
⚫ The possible directions of movement can be predefined in the move array as
shown in following table. The 8 possible directions of movement are given by 0
to 7.
Name Dir move[dir].vert move[dir].horiz
N 0 -1 0
NE 1 -1 1
E 2 0 1
SE 3 1 1
S 4 1 0
SW 5 1 -1
W 6 0 -1
NW needed to create
The C declaration 7 this table are:--1 -1

typedef struct
{
short int vert;
short int horiz;
}offsets;
offsets moves[8];
MAZE PROBLEM
∙ If the rat is at position maze[row][col] and the next move position can be
obtained as follows:-

maze[nextRow][nextCol], where nextRow = row+move[dir].vert;

nextCol = col+move[dir].horoz;

∙ Here, the best possible direction is not predictable. So, the current position of
the rat is saved and arbitrarily pick a possible move.

∙ By saving the current position, it is possible to return to it back and try another
path if it is a hopeless path.

∙ Thus, all possible moved starting from the north and moving clockwise are
examined.

∙ A 2D array, mark is used to record the maze positions already checked.

∙ Initially, all the array enteries are 0.

∙ When a position maze[row][col] is visited, then mark[row][col] is changed to


1.
MAZE PROBLEM
∙ Initial maze traversal is shown in the above Figure. EXIT_ROW & EXIT_COL gives the
coordinates of maze exit.

∙ Stack is used to solve the problem.

⚫ Element is defined as:


typedef struct
{
short int row;
short int col;
short int dir;
}Element;
∙ Each position in the maze is visited no more than once, the stack need to have only as
many positions as there are 0’s in the maze.

∙ The maze has only 1 entrance and 1 exit path.

∙ When searching the maze from entrance to exit, all positions with 0 will be on the stack
when the exit is reached.

∙ Since, an mxp maze can have at most mp zeros, it is sufficient for the stack to have this
capacity.
Initial maze algorithm:-
while(stack is not empty)
{ /* move at position at top of stack*/
while(there are moves from current position)
{
<nextRow, nextCol>=coordinates of next move;
dir=direction of move;
if(nextRow == EXIT_ROW) && (nextCol == EXIT_COL))
success;
if(maze[nextRow][nextCol] == 0 && mark[nextRow][nextCol] == 0)
{ /* legal move and haven’t been there */
mark[nextRow][nextCol] = 1;
/* save current position & direction */
add <row, col, dir> to the top of the stack;
row = nextRow;
col = nextCol;
dir = North;
}
}
}
printf(“No path found\n”);
Maze Search function:-
void path()
{ /* output a path through the maze if such a path exists*/
int i, row, col, nextRow, nextCol, dir, found = FALSE;
Element position;
mark[1][1]=1;
top=0;
stack[0].row=1;
stack[0].col=stack[0].dir=1;
while (top>-1 && !found)
{
position = pop();
row=position.row;
col=position.col;
dir=position.dir;
while(dir<8 && !found)
{
/*move in direction dir */
nextRow = row+move[dir].vert;
nextCol = col+move[dir].horiz;
if(nextRow == EXIT_ROW && nextCol == EXIT_COL)
found – TRUE;
elseif(!maze[nextRow][nextCol] && !mark[nextRow][nextCol])
{
mark[nextRow][nextCol] = 1;
position.row = row;
position.col = col;
position.dir = ++dir;
push(position);
row=nextRow;
col=nextCol;
dir=0;
}
else ++dir;
}
}
if(found)
{
printf(“the path is:\n”);
printf(“ row col\n”);
for(i=0;i<=top;i++)
printf(“%2d %5d\n”, stack[i].row, stack[i].col);
printf(“%2d %5d\n”, row, col);
printf(“%2d %5d\n”, EXIT_ROW, EXIT_COL);
}
else
printf(“The maze doesnot have a path”);
}
Multiple stacks and
queues
Two stacks

m[0], m[1], …, m[n-2], m[n-1]

bottommost bottommost
stack 1 stack 2

More than two stacks (n)


memory is divided into n equal segments
boundary[stack_no]
0 ≤ stack_no < MAX_STACKS
top[stack_no]
0 ≤ stack_no < MAX_STACKS
Initially,
boundary[i]=top[i].
0 1 [ m/n ] 2[ m/n ] m-1

boundary[ 0] boundary[1] boundary[ 2]


boundary[n]
top[ 0] top[ 1] top[ 2]

All stacks are empty and divided into roughly equal


segments.

154
initial configuration for n stacks in memory
The relevant declaration are:
#define MEMORY_SIZE 100 /* size of memory */
#define MAX_STACKS 10 /* max number of stacks plus 1 */
element memory[MEMORY_SIZE];
int top[MAX_STACKS];
int n; /* number of stacks entered by the user */
To divide the array into equal segment, we use the following code:
top[0]=boundary[0]=-1;
for(j=1;j<n;j++)
top[j]=boundary[j]=(MEMORY_SIZE/n)*j;
boundary[n]=MEMORY_SIZE-1;
155
void push(int i,element item)
{
if(top[i]==boundary[i+1])
stackfull(i);
memory[++top[i]]=item;
}

Element pop(int i)
{
if(top[i]==boundary[i])
return stackempty(i);
return memory[top[i]--];
}
Find j, stack_no < j < n such that top[j] <
boundary[j+1]
or, 0 ≤ j < stack_no

b[0] t[0] b[1] t[1] b[i] t[i] t[i+1] t[j]


b[j+1] b[n]
b[i+1]
mee b[i+2]
t
b=boundary, t=top

157

You might also like