elements are carried out at one end and is called as

26
Stack: Definition and examples, Primitive operations, The stack as an ADT, Implementing push and pop operations. Expressions: Infix, postfix, and prefix expressions, Basic definitions and Examples, Converting an expression from infix to postfix, Program to convert an expression from infix to postfix, Program to evaluate a postfix expression. Recursion: Recursive definition and processes, Factorial function, Multiplication of natural numbers, Fibonacci sequence, Properties of recursive definition or algorithm, Towers of Hanoi problem. DEFINITION AND MEANING Stack is non-primitive linear data structure into which, new items may be inserted and from which items may be deleted. In this data structure, the insertion and deletion of the elements are carried out at one end and is called as „top‟ of the stack. In stack, the element last inserted will be the first to be deleted. Hence, stack is known as Last In First Out (LIFO) structure. For example, consider the task of keeping books on a table one above the other. When a person wants to take the book, he has to take the book which was kept last. Thus, the first book kept on the table will be the last book to be taken out. In the study of data structures, insertion of new item into the stack is called as push operation; whereas, deletion of an item at the top of the stack is pop operation. When the stack is full, we can‟t insert any more elements. This situation is called as stack overflow. Similarly, when stack is empty, we can‟t delete element from it. This condition is known as stack underflow. An integer variable top is normally used for denoting current status of the stack that is, the value of top gives the number of items of the stack. For programming purpose, an empty stack is denoted by setting the value of top as -1. Each time the push operation is encountered, the top will be incremented. When the pop operation is done, top will be decremented. Usually, we define the size of the stack at the beginning. For example, stack of 5 elements, stack of 10 elements etc. When the value of top becomes -1 during deletion, it is stack underflow. When the top reaches the predefined size, it is stack overflow. The figures show Demo of stack operations.

Upload: others

Post on 27-Dec-2021

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: elements are carried out at one end and is called as

Stack: Definition and examples, Primitive operations, The stack as an ADT,

Implementing push and pop operations. Expressions: Infix, postfix, and prefix

expressions, Basic definitions and Examples, Converting an expression from infix to

postfix, Program to convert an expression from infix to postfix, Program to evaluate a

postfix expression.

Recursion: Recursive definition and processes, Factorial function, Multiplication of

natural numbers, Fibonacci sequence, Properties of recursive definition or algorithm,

Towers of Hanoi problem.

DEFINITION AND MEANING

Stack is non-primitive linear data structure into which, new items may be inserted and

from which items may be deleted. In this data structure, the insertion and deletion of the

elements are carried out at one end and is called as „top‟ of the stack. In stack, the

element last inserted will be the first to be deleted. Hence, stack is known as Last In

First Out (LIFO) structure.

For example, consider the task of keeping books on a table one above the other. When a

person wants to take the book, he has to take the book which was kept last. Thus, the

first book kept on the table will be the last book to be taken out.

In the study of data structures, insertion of new item into the stack is called as push

operation; whereas, deletion of an item at the top of the stack is pop operation. When

the stack is full, we can‟t insert any more elements. This situation is called as stack

overflow. Similarly, when stack is empty, we can‟t delete element from it. This

condition is known as stack underflow.

An integer variable top is normally used for denoting current status of the stack – that

is, the value of top gives the number of items of the stack. For programming purpose, an

empty stack is denoted by setting the value of top as -1. Each time the push operation is

encountered, the top will be incremented. When the pop operation is done, top will be

decremented. Usually, we define the size of the stack at the beginning.

For example, stack of 5 elements, stack of 10 elements etc. When the value of top

becomes -1 during deletion, it is stack underflow. When the top reaches the predefined

size, it is stack overflow.

The figures show Demo of stack operations.

Page 2: elements are carried out at one end and is called as

Primitive Operations and Stack as ADT

Stack in one of the ADT data type. Here is a minimal set of operations that we would

need for an abstract.

1. Create stack- Create a stack of elements

2. PUSH()- Push an element on top of the stack. If the stack is full, then PUSH

operation is not possible.

3. POP()- Pop an element from the stack (Top element). If the stack is empty, then

POP operation is not possible

4. ISEMPTY()-Returns true if the stack is empty

5. DISPLAY()-Displaying all elements in the stack

6. COUNT()-Count the number of elements in the stack

Page 3: elements are carried out at one end and is called as

Algorithm: PUSH(S, TOP, MAXSTK, item)

Push an element on top of the stack. If the stack is full, then PUSH operation is not

possible

Step 1 − Checks if the stack is full. If the stack is full, produces an error and

exit.

Step 2 − If the stack is not full, increments top to point next empty space.

Step 3 − Adds data element to the stack location, where top is pointing.

Step 4 − Returns success.

Algorithm: POP(S, TOP, item)

Pop an element from the stack (Top element). If the stack is empty, then POP operation is

not possible

Step 1 − Checks if the stack is empty. If the stack is empty, produces an error

and exit.

Step 2 − If the stack is not empty, accesses the data element at which top is

pointing.

Step 3 − Decreases the value of top by 1.

Step 4 − Returns success.

Page 4: elements are carried out at one end and is called as

Algorithm: DISPLAY

Displaying all elements in the stack

IS EMPTY( )

Returns true if the stack is empty

Page 5: elements are carried out at one end and is called as

STACK TOP()

Program to implement stack using an ARRAY

Page 6: elements are carried out at one end and is called as
Page 7: elements are carried out at one end and is called as

EXAMPLE 1

Consider the following stack of characters, where STACK is allocated N = 8 memory

cells

Initial State of a STACK : A,C,D,F,K

Describe the stack as the following operations takes place:

(a) POP(STACK, ITEM)

(b) POP(STACK, ITEM)

(c) POP(STACK, ITEM)

(d) PUSH(STACK, R)

(e) PUSH(STACK,L)

(f) PUSH(STACK, S)

(g) PUSH(STACK,P)

(h) POP(STACK, ITEM)

Ans:

(a) STACK: A,C,D,F,_,_,_,_

(b) STACK: A,C,D,_,_,_,_,_

(c) STACK: A,C,_,_,_,_,_,_

(d) STACK: A,C,R,_,_,_,_,_

(e) STACK:A,C,R,L,_,_,_,_

(f) STACK:A,C,R,L,S, _ ,_,_

(g) STACK: A,C,R,L,S,P,_,_

(h) STACK: A,C,R,L,S,_,_,_

Example 2

Initially stack with a value 55

S.push(7); // 55, 7

S.push(20); // 55, 7, 20

S.push(35); // 55, 7, 20, 35

S.pop(); // 55, 7, 20

S.push(14); // 55, 7, 20, 14

S.pop(); // 55, 7, 20

S.pop(); // 55, 7

Page 8: elements are carried out at one end and is called as

INFIX, PREFIX and POSTFIX EXPRESSIONS

INFIX

To add A, B, we write A+B

To multiply A, B, we write A*B

The operators ('+' and '*') go in between the operands ('A' and 'B'). This is "Infix"

notation.

PREFIX

Instead of saying "A plus B", we could say "add A,B " and write + A B

"Multiply A,B" would be written *A B

This is Prefix notation.

POSTFIX

Another alternative is to put the operators after the operands as in A B +

And A B *

This is Postfix notation.

Examples:

Page 9: elements are carried out at one end and is called as

Program to convert an infix to postfix expression: # include <string.h> char stack[20];

int top = -1;

void push(char x)

{

stack[++top] = x;

}

char pop()

{

if(top == -1)

return -1;

else

return stack[top--];

}

int priority(char x)

{

if(x == '(')

Page 10: elements are carried out at one end and is called as

return 0;

if(x == '+' || x == '-')

return 1;

if(x == '*' || x == '/')

return 2;

if(x == '$' || x == '^')

return 3;

}

main()

{

char exp[20];

char *e, x;

printf("Enter the expression :: ");

scanf("%s",exp);

e = exp;

while(*e != '\0')

{

if(isalnum(*e))

printf("%c",*e);

else if(*e == '(')

push(*e);

else if(*e == ')')

{

while((x = pop()) != '(')

printf("%c", x);

}

else

{

while(priority(stack[top]) >= priority(*e))

printf("%c",pop());

push(*e);

}

e++;

Page 11: elements are carried out at one end and is called as

}

while(top != -1)

{

printf("%c",pop());

}

}

Operator Priorities

Postfix conversion operation depends on operator priority are given below

Operators are taken out of the stack as long as the in-stack priority is greater

than or equal to the in-coming priority of the new operator

Example 1

A+ (B*C-(D/E^F)*G)*H, where ^ is an exponential operator

Page 12: elements are carried out at one end and is called as

Example 2

Example 3

Page 13: elements are carried out at one end and is called as

Example 4

Page 14: elements are carried out at one end and is called as

Example 5

Example 6

Page 15: elements are carried out at one end and is called as

Evaluating POSTFIX expression Algorithm

Page 16: elements are carried out at one end and is called as
Page 17: elements are carried out at one end and is called as

3. Input:

Page 18: elements are carried out at one end and is called as

Postfix expression: 53+62/*35*+

Output:

The result is: 39

RECURSION

Definition and meaning

Recursion is a technique of defining something in terms of itself. If a function calls itself

then it is known as recursive function. If the function calls itself directly, then it is known

as direct recursion.

Example:

void myfun()

{ -----

-----

myfun();

-----

-----

}

1. FACTORIAL OF A NUMBER

Factorial of a non-negative integer n is defined as the product of all integers from 1 to n.

That is: n! = n(n-1)(n-2)…3.2.1 , for all n>=1 and 0! = 1.

By definition we have, n!= n(n-1)!

Thus, factorial is a recursive function.

Consider one example of finding

5! – 5! = 5*(5-1)!

= 5*4!

= 5*4*3!

= 5*4*3*2!

= 5*4*3*2*1!

= 5*4*3*2*1*0!

= 5*4*3*2*1*1

= 120

Page 19: elements are carried out at one end and is called as

This procedure can be implemented through program given below:

//FACTORIAL OF A NUMBER

#include<stdio.h>

int fact(int n)

{

if (n==0)

return 1;

return n* fact(n-1);

}

void main()

{

int n;

printf(“Enter the value of n”);

scanf(“%d”, &n);

if(n<0)

printf(“Invalid input”);

else

printf(“\nFactorial of %d is %d “, n, fact(n)) ;

}

The output would be:

Enter the value of n: 6

The factorial of 6 is 720

2. MULTIPLICATION OF TWO NATURAL NUMBERS

The product of two natural numbers say, m and n is nothing but the sum obtained by

adding m for n number of times. That is,

m*n = m+m+… +m (for n times).

This can be given recursively as

– m*n= m*(n-1) + m for n>1

= m for n=1

Consider one example of multiplying 4 and 3.

Let m=4 and n=3.

Then 4*3 = 4*(3-1) +4

= 4*2 + 4

= 4 * (2-1) + 4 +4

Page 20: elements are carried out at one end and is called as

= 4 * 1 + 4 + 4

= 12

Program:

// Multiplication of two Natural Numbers

#include<stdio.h>

int mul(int a, int b)

{

if(b==1)

return a;

return a + mul(a, b-1);

}

void main()

{

int m, n;

printf(“Enter the values of m and n”);

scanf(“%d%d”, &m, &n);

if(m<=0 || n<=0)

{

printf(“Invalid input”);

return;

}

printf(“Product of %d and %d is %d”, m, n, mul(m,n));

}

3. FIBONACCI SEQUENCE

A sequence of integers is called Fibonacci sequence if an element of a sequence is the

sum of its immediate two predecessors.

That is:

f(x)=0 for x=1

f(x)=1 for x=2

f(x)=f(x-2)+f(x-1) for x>2

Thus the Fibonacci sequence is 0, 1, 1, 2, 3, 5, 8, 13, 21, ….

Consider an example of finding 6th Fibonacci number.

f(6) = f(4) + f(5)

= f(2) + f(3) + f(3) + f(4)

= 1 + f(1) + f(2) + f(1) + f(2) + f(2)+ f(3)

= 1 + 0 + 1 + 0 + 1 + 1 + f(1) +(2)

Page 21: elements are carried out at one end and is called as

= 4 + 0 + 1

= 5

The above procedure can be illustrated through the program given below:

//Finding nth Fibonacci number

#include<stdio.h>

int fibo(int n)

{

if (n==1)

return 0;

else if (n==2)

return 1;

return fibo(n-1) + fibo (n-2);

}

void main()

{

int n;

printf(“Enter value of n”);

scanf(“%d”, &n);

if(n<=0)

printf(“invalid input”);

else

printf(“%d th fibonacci number is %d “, n, fibo(n));

}

The output would be:

Enter the value of n : 10

10th fibonacci number is 34

4. TOWER OF HANOI PROBLEM

In the problem of Tower of Hanoi, there will be three poles, viz. A, B and C. Pole A

(source pole) contains „n‟ discs of different diameters and are placed one above the other

such that larger disc is placed below the smaller disc. Now, all the discs from source (A)

must be transferred to destination (C) using the pole B as temporary storage.

Conditions are:

Only one disc must be moved at a time

Page 22: elements are carried out at one end and is called as

smaller disc is on the top of larger disc at every step

Algorithm to move n discs from source to destination is as follows –

(i) move n-1 discs from source to temporary

(ii) move nth disc from source to destination

(iii) move n-1 disc from temporary to destination

For example, consider the number of discs = 3. Then, various steps involved in

transferring 3 discs from source to destination are shown below –

Page 23: elements are carried out at one end and is called as

Program:

#include<stdio.h>

int count=0;

void tower(int n, char s, char d, char t)

{

if(n==1)

{

printf(“Move disc 1 from %c to %c “, s, d);

count ++; return;

}

tower(n-1, s, d, t);

printf(“Move disc %d from %c to %c”, n, s,d);

count ++;

tower(n-1, t, s, d);

}

void main()

{

int n;

printf(“Enter the number of discs”);

scanf(“%d”, &n);

tower(n, „A‟,‟C‟,‟B‟);

printf(“Total number of moves =%d”, count);

}

Output:

Enter the number of discs: 3

Move disc 1 from A to C

Move disc 2 from A to B

Move disc 1 from C to B

Move disc 3 from A to C

Move disc 1 from B to A

Move disc 2 from B to C

Move disc 1 from A to C

Total number of disc moves = 7

Properties of Recursive definition or algorithm

Page 24: elements are carried out at one end and is called as

When a function calls itself, a new set of local variables and parameters are being

allocated memory in the stack. Then the function code is executed from the top with these

new variables. A recursive call does not make a new copy of the function, only the values

being operated upon are new. When each recursive call returns, the old local variables

and parameter are removed from the stack and the execution resumes at the point of the

function call inside the function.

Some facts about recursive functions are:

Recursive functions do not usually reduce the code size.

They do not improve memory utilization compared to iterative functions.

Many of the recursive functions may execute a bit slower compared to iterative

functions because of the overhead of repeated function calls.

They may cause a stack overrun, as each new call to the recursive function creates

a new copy of variables and parameters and puts them into the stack.

The advantage of using recursive functions is to create clearer and simpler

programs. Moreover, some of the algorithms do require recursive functions as the

iterative versions of them are quite difficult to write and implement.

While writing a recursive function, a conditional statement has to be included

which will terminate the recursive function without using a recursive function call.

Otherwise, the recursive function will enter into an infinite loop and will not

terminate at all.

Thus, any recursive function should satisfy the following conditions:

In each and every call, the function must be nearer to the solution. (In other words,

at every step, the problem size must reduce)

There should be at least one non-recursive exit condition.

Page 25: elements are carried out at one end and is called as

Example: Sum of Natural Numbers Using Recursion #include <stdio.h> int sum(int n); int main() { int number, result; printf("Enter a positive integer: "); scanf("%d", &number); result = sum(number); printf("sum = %d", result); return 0; } int sum(int n) { if (n != 0) // sum() function calls itself return n + sum(n-1); else return n; }

Recursion Quiz for placement training purpose Predict output of following program Question 1 #include <stdio.h> int fun(int n) { if (n == 4) return n; else return 2*fun(n+1); }

int main()

Page 26: elements are carried out at one end and is called as

{ printf("%d ", fun(2)); return 0; }

Question 1 Explanation: Fun(2) = 2 * Fun(3) and Fun(3) = 2 * Fun(4) ....(i)

Fun(4) = 4 ......(ii)

From equation (i) and (ii),

Fun(2) = 2 * 2 * Fun(4)

Fun(2) = 2 * 2 * 4

Fun(2) = 16.

So, C is the correct answer

Question 2

Consider the following recursive function fun(x, y). What is the value of fun(4, 3) int fun(int x, int y) { if (x == 0) return y; return fun(x - 1, x + y); }

Question 2 Explanation: The function fun() calculates and returns ((1 + 2 … + x-1 + x) +y) which is x(x+1)/2 + y.

13

Q3: What does the following function print for n = 25? void fun(int n) { if (n == 0) return;

printf("%d", n%2); fun(n/2); }

Question 3 Explanation: The function mainly prints binary representation in reverse order. 10011