0% found this document useful (0 votes)
26 views39 pages

DS Unit-I

Uploaded by

Aarush Pitla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views39 pages

DS Unit-I

Uploaded by

Aarush Pitla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

Data Structures

UNIT-I

Introduction: What is data structure, Types of data structures, Static and Dynamic representation
of data structure and comparison. Stacks- definition, operations, Applications of stacks –
Representation and evaluation of expressions using Infix, Prefix and Postfix, Algorithms for
conversions and evaluations of expressions from infix to prefix and postfix using stack, Towers of
Hanoi, Parenthesis checker.
**************************************************************************************************
Introduction to Data Structures:

A data structure can be defined as follows...

Data structure is a method of organizing a large amount of data more efficiently so


that any operation on that data becomes easy.

OR

Data Structure can be defined as the group of data elements which provides an
efficient way of storing and organizing data in the computer so that it can be
used efficiently.

There are ‘n’ number of algorithms were proposed to organize the data in memory. These
algorithms are referred to as Abstract data types. These Abstract data types are the set of
rules:

1
Data Structures
Data Structure Operations
The major or the common operations that can be performed on the datastructures are:
 Insertion: We can insert the new element in a data structure.
 Updating: We can also update the element, i.e., we can replace the element with
anotherelement.
 Deletion: We can perform the delete operation to remove the element from the data
structure.
 Searching: We can also search for any element in a data structure.
 Sorting: We can sort the elements of a data structure either in an ascending or
descendingorder

Advantages of Data structures:

Efficiency If the choice of a data structure for implementing a


particular ADT is proper, it makes the program very
efficient in terms of time and space

The data structure provides reusability means that


Reusability multiple client programs can use the data structure.

The data structure specified by an ADT also provides


Abstraction the level of abstraction. The client cannot see the
internal working of the data structure, so it does not
have to worry about the implementation part. The
client can only see the interface

Abstract data types:

The abstract data type is special kind of data type, whose behaviour is defined by a set of values
and 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

2
Data Structures
Types of Data Structures

There are two types of data structures:


i) Primitive data structure
ii) Non-primitive data structure

Primitive Data structure: The primitive data structures are primitive data types. The int,
char, float, double, and pointer are the primitive data structures that can hold a single value.

Non-Primitive Data structure: The non-primitive data structure is divided into two types:
o Linear data structure
o Non-linear data structure

Linear Data Structure: The arrangement of data in a sequential manner is known asa linear
data structure. The data structures used for this purpose are Arrays, Linked list, Stacks, and
Queues. In these data structures, one element is connected to onlyone another element in a
linear form.

Non-Linear Data Structure: When one element is connected to the 'n' number of elements
known as a non-linear data structure. The best example is trees and graphs. In this case, the
elements are arranged in a random manner.

3
Data Structures
Static Representation of Data structures:

Static data structure:


 In Static data structure the size of the structure is fixed. It is a type of data structure where
the size is allocated at the compile time.
 Therefore, the maximum size is fixed. The content of the data structure can be modified but
without changing the memory space allocated to it.
Example: Array.
Array : An array is a collection of elements identified by index or key values.
 The size of the array is specified at the time of creation and remains constant.
 For example, an array of integers can be declared as int arr[8];

Example Program:

// C program to store and calculate the sum of 5 numbers entered by the user using arrays.
#include<stdio.h>
int main( )
{
int num[5], sum=0;
printf(“Enter five numbers : “);
/* Storing five numbers entered by user in an array and finding the sum of numbers */
for (int i=0; i<5; ++i)
{
scanf(“%d”, &num[i]) :
sum+=num[i];
}
printf(“The sum of five integer numbers = %d”, sum);
return 0;
}
Output
Enter five numbers : 3 4 5 4 2
The sum of five integer numbers = 18

4
Data Structures
Advantages of Static Data Structures:
 Static data structures have a fixed size and structure, making them simpler to implement

and understand.
 Since the size is known in advance, the memory can be allocated efficiently.

 Accessing elements in static data structures is generally faster than in dynamic data

structures.
Disadvantages of Static Data Structures:
 The size and structure is fixed, which can lead to inefficient memory usage if the data

requirements change.
 Static data structures have a predefined size, limiting their ability to handle large and

varying amounts of data.


 If the data size is smaller than the allocated memory, the unused memory is wasted.

 Expanding the size of a static data structure requires complex procedures, such as creating

a new, larger structure and copying the data.

Dynamic Representation of Data structures:

Dynamic data structure:


 In Dynamic data structure the size of the structure in not fixed and can be modified
during the operations performed on it.
 It is a type of data structure where the size is allocated at the run time.
 Therefore, the maximum size is flexible.
Example: Linked List.
Linked List:
 Linked Lists are linear data structures where the elements are not stored in contiguous
locations and every element is a separate object with a data part and address part.
 The elements are linked using pointers and addresses. Each element is known as a node.
 Due to the dynamicity and ease of insertions and deletions, they are preferred over the
arrays.

5
Data Structures
Dynamic memory allocation using malloc

struct node
{
int data;
struct node *next;
};
struct node *new;
new = ( struct node * ) malloc ( sizeof ( struct node * ) );

Static Vs Dynamic Data Structures (Comparisons)

S. No Static Memory Allocation Dynamic Memory Allocation


When the allocation of memory performs When the memory allocation is done at the
1 at the compile time, then it is known as execution or run time, it is called dynamic
static memory. memory allocation.
The memory is allocated at the compile The memory is allocated at the runtime.
2 time.
In static memory allocation, the memory In dynamic memory allocation, while
3 cannot be changed while executing a executing a program, the memory can be
program. changed.
Static memory allocation is preferred in an Dynamic memory allocation is preferred in
4 array. the linked list.
5 It saves running time as it is fast. It is slower than static memory allocation.
Static memory allocation allots memory Dynamic memory allocation allots memory
6 from the stack. from the heap.
Once the memory is allotted, it will remain Here, the memory can be alloted at any time
7 from the beginning to end of the program. in the program.

Static memory allocation is less efficient as Dynamic memory allocation is more efficient
8 compared to Dynamic memory allocation. as compared to the Static memory allocation.

9 This memory allocation is simple. This memory allocation is complicated.

6
Data Structures
STACKS
Stack Definition:
“A stack is a linear data structure. In which, insertions and deletions are takes place at
one end, called the top. Stack maintains a variable called top, which keeps track of the top
most elements in the stack”.
“Stack is a recursive data structure having pointer to its top element. Stacks are
sometimes called as Last-In-First-Out (LIFO) lists i.e. the element which is inserted first in
the stack, will be deleted last from the stack”

Standard Stack Operations:

 push( ): When we insert an element in a stack then the operation is known as a push. If the

stack is full then the overflow condition occurs.


 pop( ): When we delete an element from the stack, the operation is known as a pop. If the
stack is empty means that no element exists in the stack, this state is known as an
underflow state.
 isEmpty( ): It determines whether the stack is empty or not.
 isFull( ): It determines whether the stack is full or not.'

 peek( ): It returns the element at the given position.

 display( ): It prints all the elements available in the stack

PUSH operation

7
Data Structures
POP operation:

Top and its value:

Top position Status of stack


-1 Empty
0 Only one element in the stack
N-1 Stack is full
N Overflow

Stack implementation using Arrays:

Push operation: Adding an element into the top of the stack is referred to as push operation.
Push operation involves following two steps.
1. Increment the variable Top so that it can now refere to the next memory location.
2. Add element at the position of incremented top. This is referred to as adding new
element atthe top of the stack.

Stack is overflown when we try to insert an element into a completely filled stacktherefore, our
main function must always avoid stack overflow condition.
Algorithm:
1. begin
2. if top = n then stack full
3. top = top + 1
4. stack (top) : = item;
5. end
Time Complexity: o(1)

Pop operation: Deletion of an element from the top of the stack is called pop operation. The
value of the variable top will be incremented by 1 whenever an item is deleted from the stack.
The top most element of the stack is stored in an another variable and then the top is
decremented by 1. Theunderflow condition occurs when we try to delete an element from an
already empty stack.

8
Data Structures
Algorithm:
1. begin
2. if top = 0 then stack empty;
3. item := stack(top);
4. top = top - 1;
5. end;
Time Complexity: o(1)

Peek operation: Peek operation involves returning the element which is present at the top of
the stack without deleting it. Underflow condition can occur if we try to return the top
element in an alreadyempty stack.

Algorithm:
PEEK (STACK, TOP)
1. Begin
2. if top = -1 then stack empty
3. item = stack[top]
4. return item
5. End
Time complexity: o(n)

Traversing: Displaying all the nodes of a stack needs traversing all the nodes of the linked list
organized in the form of stack. For this purpose, we need to follow the following steps.
1. Copy the head pointer into a temporary pointer.
2. Move the temporary pointer through all the nodes of the list and print the value field
attached to every node.
Time Complexity : o(n)
// C program to implement Stack using Array
#include <stdio.h>
int stack[100],i,j,choice=0,n,top=-1;
void push();
void pop();
void show();
void main ()
{
printf("Enter the number of elements in the stack ");
scanf("%d",&n);
printf("*********Stack operations using array*********");
printf("\n -------------------------------------------- \n");
while(choice != 4)
{
printf("Chose one from the below options. \n");
printf("\n1.Push\n2.Pop\n3.Show\n4.Exit");
printf("\n Enter your choice \n");
scanf("%d",&choice);
switch(choice)
{

9
Data Structures
case 1:
{
push();
break;
}
case 2:
{
pop();
break;
}
case 3:
{
show();
break;
}
case 4:
{
printf("Exiting. .. ");
break;
}
default:
{
printf("Please Enter valid choice ");
}
}; } }
void push ()
{
int val;
if (top == n )
printf("\n Overflow");
else
{
printf("Enter the value?");
scanf("%d",&val);
top = top +1;
stack[top] = val;
} }
void pop ()
{
if(top == -1)
printf("Underflow");
else
top = top -1;
}
void show()
{
for (i=top;i>=0;i--)
{
printf("%d\n",stack[i]);
}
if(top == -1)
{
printf("Stack is empty");
}}

10
Data Structures
Applications of stacks:

1. Expression Evaluations & Conversions: A stack is a very effective data structure for
evaluating arithmetic expressions in programming languages. An arithmetic expression
consists of operands and operators.
2. Backtracking(Recursion): Backtracking is another application of Stack. It is a recursive
algorithm that is used for solving the optimization problem.
3. Parsing (Delimiter Checking) : The common application of Stack is delimiter checking, i.e.,
parsing that involves analyzing a source program syntactically. It is also called parenthesis
checking.
4. Function calls: Stacks are used to keep track of the return addresses of function calls,
allowing the program to return to the correct location after a function has finished
executing.
5. Editors: Undo and Redo functions in any text editor.
6. Tree Traversals: Stacks are useful for Depth First Search Traversal method.
7. Browsers: Stacks are useful for function calls, storing the activation records. The history of a
web browser is stored in the form of a stack.

Expression Types:
Based on the operator position, expressions are divided into THREE types. They are as follows...

1. Infix Expression
2. Postfix Expression
3. Prefix Expression

Infix Expression:
 In infix expression, operator is used in between the operands.
 The general structure of an Infix expression is as follows...

Operand1 Operator Operand2


Example:

Postfix Expression:
 In postfix expression, operator is used after operands. We can say that "Operator follows
the Operands".
 The general structure of Postfix expression is as follows...
Operand1 Operand2 Operator
Example:

11
Data Structures
Prefix Expression:
 In prefix expression, operator is used before operands. We can say that "Operands
follows the Operator".
 The general structure of Prefix expression is as follows...
Operator Operand1 Operand2
Example:

 Every expression can be represented using all the above three different types of expressions.
And we can convert an expression from one form to another form like Infix to Postfix, Infix to
Prefix, Prefix to Postfix and vice versa.

Order of Operations (Precedence) from left to right.

^ Exponentiation right to left

Evaluation of Infix Expressions:


Example:

i) 4 + 6 * 2 = > 4 + (6 * 2)
= (4 + 12)
= 16
ii) 2 + 3 * 4 – 5 => 2 + (3 * 4) - 5
= (2 + 12) – 5
= (14 – 5)
=9
iii) 2 * 6 /2 – 3 + 7 => (2 * 6) / 2 – 3 + 7
= (12 / 2) – 3 + 7
= (6 – 3) + 7
= (3 + 7)
= 10

12
Data Structures
iv) 2 * 3 + 5 * 4 – 9 => (2 * 3) + 5 * 4 – 9
= (6) + (5*4) – 9
= (6) + (20) – 9
= (6 + 20) – 9
= (26) – 9
= (26 – 9)
= 17
Representation of infix to Prefix Expression (Polish notation) using stack
Example
A + B * C – D => A + ( * B C ) – D
 (+A*BC)–D
 (-+A*BCD)
 -+A*BCD
Algorithm:
1. First, reverse the infix expression given in the problem. While reversing each ‘( ‘will
become ‘)’ and each ‘)’ becomes ‘(‘.
2. Scan the expression from left to right. Whenever the operands arrive, print them.
3. If the operator arrives and the stack is found to be empty, then simply push the operator
into the stack.
4. If the operator is '(', then push it into the stack. If the operator is ')', then pop all the
operators from the stack till it finds ( opening bracket in the stack.
5. If the incoming operator has higher precedence and same precedence with the TOP of
the stack, push the incoming operator into the stack.
6. If the incoming operator has lower precedence than the TOP of the stack, pop, and print
the top of the stack. Test the incoming operator against the top of the stack .
7. When we reach the end of the expression, pop, and print all the operators from the top of
the stack.
8. If the top of the stack is '(', push the operator on the stack.
9. At the end, reverse the output.

Example:01- A + B * C – D
 If we are converting the expression from infix to prefix, we need first to reverse the
expression.
 The Reverse expression would be: D-C*B+A

Input expression Stack Prefix expression


D D
- - D
C - DC
* -* DC
B -* DCB
+ -+ DCB*
A -+ DCB*A
DCB*A+-

13
Data Structures

The above expression, i.e., DCB*A+-, is not a final expression. We need to reverse this expressionto
obtain the prefix expression.
Now infix expression is -+A*BCD

Example:02- A + ( B * C )

 If we are converting the expression from infix to prefix, we need first to reverse the
expression.
 The Reverse expression would be: ( C * B ) + A

Input expression Stack Prefix expression


( (
C ( C
* (* C
B (* CB
) CB*
+ + CB*
A + CB*
CB*A+

The above expression, i.e., CB*A+, is not a final expression. We need to reverse this expression to
obtain the prefix expression.
Now infix expression is +A*BC

14
Data Structures

Example: 04- (A+B)+C-(D-E)^F

 If we are converting the expression from infix to prefix, we need first to reverse the
expression.
 The Reverse expression would be: F^(E-D)-C+(B+A)

Input Token Stack Expression Action

F F Add F into expression string

^ ^ F Push ‘^’ into stack


( ^( FE Push ‘)’ into stack

E ^( FE Add E into expression string

– ^(- FE Push ‘-‘ into stack

D ^(- FED Add D into expression string

) ^ FED- ‘(‘ Pair matched, so pop operator ‘-‘

‘-‘ operator has less precedence than


– – FED-^ ‘^’, so pop ^ and add to expression
string

C – FED-^C Add C into expression string

+ -+ FED-^C Push ‘-’ into stack, same precedence

( -+( FED-^C Push ‘(’ into stack

B -+( FED-^CB Add B into expression string

+ -+(+ FED-^CB Push ‘+’ into stack

A -+(+ FED-^CBA Add A into expression string

) -+ FED-^CBA+ ‘(‘ Pair matched, so pop operator ‘+’

Pop all operators one by one as we


FED-^CBA++-
have reached end of the expression

Now infix expression is -++ABC^-DEF

15
Data Structures
Evaluation of Prefix Expression (Polish notation) Using Stack

Algorithm:

Step-1: Create an empty STACK and start scanning the Prefix expression from Right to Left.
Step-2: if the element is an Operand, PUSH it into the STACK.
Step-3: if the element is an Operator, POP twice and get top most two elements Aand B;
Calculate A Operator B and PUSH the result back into the STACK.
Step-4: When the expression is ended, the value in the STACK is the final answer.

Example:

i) 4 + 6 * 2 = > 4 + (*6 2)
= (+ 4 * 6 2)
=+4*62

Pop( )->A=6 Pop( ) ->A=4


Empty Push(2) Push(6) Pop( )->B=2 Push(12) Push(4) Pop( ) ->B=12 Push(16)
A*B = 6*2=12 A+B = 4+12=16

6 4
2 2 12 12 16
Stack
Therefore, the final answer of prefix notation + 4 * 6 2 is 16

ii) 2 + 3 * 4 – 5 => 2 + (* 3 4) - 5

= (+ 2 * 3 4) – 5
= (- + 2 * 3 4 5)
=-+2*345
Pop( )->A=3 Pop( ) ->A=2
Empty Push(5) Push(4) Push(3) Pop( )->B=4 Push(12) Push(2) Pop( ) ->B=12 Push(14)
A*B = 3*4=12 A+B = 2+12=14
3 2
4 4 12 12 14
5 5 5 5 5 5 5 5
Stack
Pop( )->A=14
Pop( )->B=5 Push(9)
A-B = 14-5=9

Therefore, the final answer of prefix notation - + 2 * 3 4 5 is 9

iii) 2 * 6 /2 – 3 + 7 => (* 2 6) / 2 – 3 + 7
= (/ *2 6 2) – 3 + 7
= (- / * 2 6 2 3) + 7
= (+ - / * 2 6 2 3 7)
=+-/*26237

16
Data Structures
Pop( ) ->A=2
Empty Push(7) Push(3) Push(2) Push(6) Push(2) Pop( ) ->B=6 Push(12)
A*B = 2*6=12
2
6 6 12
2 2 2 2 2
3 3 3 3 3 3
7 7 7 7 7 7 7
Stack

Pop( )->A=12 Pop( )->A=6 Pop( )->A=3


Pop( )->B=2 Push(6) Pop( )->B=3 Push(3) Pop( )->B=7 Push(10)
A/B = 12/2=6 A-B = 6-3=3 A+B = 3+7=10

6
3 3 3
7 7 7 7 10

Therefore, the final answer of prefix notation + - / * 2 6 2 3 7 is 10

iv) 2 * 3 + 5 * 4 - 9 => (* 2 3) + 5 * 4 - 9
= (*2 3) + (*5 4) - 9
= (+ * 2 3 * 5 4) - 9
= (- + * 2 3 * 5 4 9)
=-+*23*549
Pop( ) ->A=5
Empty Push(9) Push(4) Push(5) Pop( )->B=4 Push(20) Push(3) Push(2)
A*B = 5*4=20
2
5 3 3
4 4 20 20 20
9 9 9 9 9 9 9
Stack

Pop( )->A=2 Pop( )->A=6 Pop( )->A=26


Pop( )->B=3 Push(6) Pop( )->B=20 Push(26) Pop( )->B=9 Push(17)
A*B = 2*3=6 A+B = 6+20=26 A-B = 26-9=17

6
20 20 26
9 9 9 9 17

Therefore, the final answer of prefix notation - + * 2 3 * 5 4 9 is 17

17
Data Structures
Representation of infix to Postfix Expression (Reverse Polish notation) using stack:

Example
A + B * C – D => A + ( B C * ) – D
 (ABC*+)–D
 (ABC*+D-)
 ABC*+D–
Algorithm:

1. Read all the symbols one by one from left to right in the given Infix Expression.
2. If the reading symbol is operand, then directly print it to the result (Output).
3. If the reading symbol is left parenthesis '(', then Push it on to the Stack.
4. If the reading symbol is right parenthesis ‘)’, pop the stack and print the operators until left
parenthesis is found.
5. if the reading symbol is the operator and the Stack is empty or contains the '(', ')' symbol,
push the operator into the Stack.
6. If incoming symbol has higher precedence than the top of the stack, push it on the stack
7. If incoming symbol has lower precedence than the top of the stack, pop and print the top.
Then test the incoming operator against the new top of the stack.
8. If incoming operator has equal precedence with the top of the stack, use associatively rule
 If associatively L to R then pop and prints the top of the stack and then push the
incoming operator.
 If associatively R to L then push the incoming operator
9. At the end of the expression, pop and print all operators of stack.

NOTE:
 +,- operators has same precedence
 *,/ operators has same precedence

Example: 01- A + B * C – D

Input expression Stack Postfix expression


A A
+ + A
B + AB
* +* AB
C +* ABC
- - ABC*+
D - ABC*+D
ABC*+D-

Now Postfix expression is ABC*+D-

18
Data Structures
Example: 02- ( A + B ) * ( C - D )

Input expression Stack Postfix expression


( (
A ( A
+ (+ A
B (+ AB
) AB+
* * AB+
( *( AB+
C *( AB+C
- *(- AB+C
D *(- AB+CD
) * AB+CD-
AB+CD-*

Evaluation of Postfix Expression using Stack:

Algorithm:
Step-1: Create an empty STACK and start scanning the Postfix expression from Left to Right.
Step-2: if the element is an Operand, PUSH it into the STACK.
Step-3: if the element is an Operator, POP twice and get top most two elements A and
B; Calculate B Operator A and PUSH the result back into the STACK.
Step-4: When the expression is ended, the value in the STACK is the final answer.

Example:01

i) 4 + 6 * 2 = > 4 + (6 2 *)
= ( 4 6 2 * +)
=462*+

Pop( )->A=2 Pop( ) ->A=12


Empty Push(4) Push(6) Push(2) Pop( )->B=6 Push(12) Pop( ) ->B=4 Push(16)
B*A = 6*2=12 B+A = 4+12=16
2
6 6 12
4 4 4 4 4 16
Stack

Therefore, the final answer of postfix notation 4 6 2 * + is 16

ii) 2 + 3 * 4 – 5 => 2 + (3 4 *) - 5
= (2 3 4 * +) – 5
= (2 3 4 5 * + -)
=234*+5–

19
Data Structures

Pop( )->A=4 Pop( )->A=12


Empty Push(2) Push(3) Push(4) Pop( )->B=3 Push(12) Pop( )->B=2 Push(14) Push(5)
B*A = 4*3=12 B+A = 2+12=14
4
3 3 12 5
2 2 2 2 2 14 14
Stack

Pop( )->A=5
Pop( )->B=14 Push(9)
B-A = 14-5=9

Therefore, the final answer of postfix notation 2 3 4 5 * + - is 9

iii) 2 * 6 /2 – 3 + 7 => (2 6 *) / 2 – 3 + 7
=(26*2/)–3+7
= (2 6 * 2 / 3 -) + 7
= (2 6 * 2 / 3 - 7 +)
=26*2/3–7+

Pop( )->A=6 Pop( )->A=2


Empty Push(2) Push(6) Pop( )->B=2 Push(12) Push(2) Pop( )->B=12 Push(6)
B*A = 2*6=12 B/A = 12/2=6
6 2
2 2 12 12 6
Stack
Pop( )->A=3 Pop( )->A=7
Push(3) Pop( )->B=6 Push(3) Push(7) Pop( )->B=3 Push(10)
B-A = 6-3=3 B+A = 3+7=10
3 7
6 3 3 10

Therefore, the final answer of postfix notation 2 6 * 2 / 3 – 7 + is 10

Example-02- (5+3)*(8-2)

20
Data Structures

Example: 3
Now let us consider the following infix expression 2 * (4+3) - 5.
Its equivalent postfix expression is
2 4 3 + * 5 is 9

21
Data Structures
Program to Convert Infix to Postfix notation
PROGRAM:01

// C Program to Convert Infix to Postfix notation

#include<stdio.h>
#include<stdlib.h>
char stack[100];
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 == '(')
return 0;
if(x == '+' || x == '-')
return 1;
if(x == '*' || x == '/')
return 2;
return 0;
}

void main()
{
char exp[100];
char *e, x;
clrscr();
printf("Enter the Infix expression : ");
scanf("%s",exp);
printf("\n");
printf("Postfix express is : ");
e = exp;
while(*e != '\0')
{
if(isalnum(*e))
printf("%c ",*e);
else if(*e == '(')
push(*e);

22
Data Structures
else if(*e == ')')
{
while((x = pop()) != '(')
printf("%c ", x);
}
else
{
while(priority(stack[top]) >= priority(*e))
printf("%c ",pop());
push(*e);
}
e++;
}
while(top != -1)
{
printf("%c ",pop());
}
getch();
}

OUTPUT:

PROGRAM:02

// C program to Convert Infix to Postfix notaion


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 100
char stack[SIZE];
int top = -1;
void push(char item)
{
if(top >= SIZE-1)
{
printf("\nStack Overflow.");
}
else
{
top = top+1;
stack[top] = item;
}

23
Data Structures
}
char pop()
{
char item ;
if(top<0)
{
printf("stack under flow: invalid infix expression");
exit(1);
}
else
{
item = stack[top];
top = top-1;
return(item);
}
return(1);
}
int is_operator(char symbol)
{
if(symbol == '^' || symbol == '*' || symbol == '/' || symbol == '+' || symbol =='-')
{
return 1;
}
else
{
return 0;
}
}
int precedence(char symbol)
{
if(symbol == '^')
{
return(3);
}
else if(symbol == '*' || symbol == '/')
{
return(2);
}
else if(symbol == '+' || symbol == '-')
{
return(1); }

else
{
return(0);
}
}

24
Data Structures
void InfixToPostfix(char infix_exp[], char postfix_exp[])
{
int i, j;
char item;
char x;
push('(');
strcat(infix_exp,")");
i=0;
j=0;
item=infix_exp[i];
while(item != '\0')
{
if(item == '(')
{
push(item);
}
else if( isdigit(item) || isalpha(item))
{
postfix_exp[j] = item;
j++;
}
else if(is_operator(item) == 1)
{
x=pop();
while(is_operator(x) == 1 && precedence(x)>= precedence(item))
{
postfix_exp[j] = x;
j++;
x = pop();
}
push(x);
push(item);
}
else if(item == ')')
{
x = pop();
while(x != '(')
{
postfix_exp[j] = x;
j++;
x = pop();
}
}
else
{
printf("\nInvalid infix Expression.\n");
exit(1);
}

25
Data Structures
i++;
item = infix_exp[i];
}
if(top>0)
{
printf("\nInvalid infix Expression.\n");
exit(1);
}
postfix_exp[j] = '\0';
}
void main()
{
char infix[SIZE], postfix[SIZE];
clrscr();
printf("\nEnter Infix expression : ");
gets(infix);
InfixToPostfix(infix,postfix);
printf("Postfix Expression: ");
puts(postfix);
getch();
}

OUTPUT:

26
Data Structures
Program to evaluate Postfix notation

PROGRAM:01

// c program to evaluate postfix notation #include<stdio.h>


#include<conio.h> #include<ctype.h> #include<stdlib.h>
int stack[20]; int top=-1;
void push(int x)
{
stack[++top]=x;
}
int pop()
{
return stack[top--];
}
void main()
{
char exp[20]; char *e;
int n1,n2,n3,num; clrscr();
printf("\nEnter the expression :"); scanf("%s",exp);
e=exp;
while(*e != '\0')
{
if(isdigit(*e))
{
num = *e-48; push(num);
}
else
{
n1=pop();
n2=pop();
switch(*e)
{
case '+':
{
n3=n1+n2; break;
}
case '-':
{
n3=n2-n1; break;
}
case '*':
{
n3=n1*n2; break;
}
case '/':
{
n3=n2/n1; break;
}}
push(n3);
}
e++;
}
printf("\nThe result of expression %s = %d \n ",exp, pop()); getch( ); }

27
Data Structures
OUTPUT:

Towers of Hanoi
 Tower of Hanoi, is a mathematical puzzle which consists of three towers (pegs) and more
than one rings is as depicted.
 These rings are of different sizes and stacked upon in an ascending order, i.e. the smaller
one sits over the larger one.
 There are other variations of the puzzle where the number of disks increase, but the tower
count remains the same.
Rules:
The mission is to move all the disks to some another tower without violating the sequence of
arrangement. A few rules to be followed for Tower of Hanoi are
 Only one disk can be moved at a time.
 Each move consists of taking the upper disk from one of the stacks and placing it on top of
another stack i.e. a disk can only be moved if it is the uppermost disk on a stack.
 No disk may be placed on top of a smaller disk.

Tower of Hanoi using Recursion:


The idea is to use the helper node to reach the destination using recursion. Below is the pattern
for this problem:
Step 1 − Move N-1 disks from A to B, using C.
Step 2 − Move Last (Nth) disk from A to C.
Step 3 − Move N-1 disks from B to C, using A

28
Data Structures
A recursive algorithm
START
Procedure Hanoi(disk, source, dest, aux)
IF disk == 1, THEN
move disk from source to dest
ELSE
Hanoi(disk - 1, source, aux, dest) // Step 1
move disk from source to dest // Step 2
Hanoi(disk - 1, aux, dest, source) // Step 3
END IF
END Procedure
STOP
Tower of Hanoi puzzle with n disks can be solved in minimum 2 n−1 steps. This presentation
shows that a puzzle with 3 disks has taken 23 - 1 = 7 steps.

Following are the implementations of this approach

#include <stdio.h>
void hanoi(int n, char from, char to, char via) {
if(n == 1){
printf("Move disk 1 from %c to %c\n", from, to);
}
else{
hanoi(n-1, from, via, to);
printf("Move disk %d from %c to %c\n", n, from, to);
hanoi(n-1, via, to, from);
}
}
int main() {
int n = 3;
char from = 'A';
char to = 'B';
char via = 'C';
//calling hanoi() method
hanoi(n, from, via, to);
}
Output:
Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C

29
Data Structures
Parenthesis checker
 The parentheses are used to represent the mathematical representation.
 The balanced parenthesis means that when the opening parenthesis is equal to the closing
parenthesis, then it is a balanced parenthesis.
The parenthesis is represented by the brackets shown below:
( ) , { }, [ ]
Where, ( → Opening bracket and
) → Closing bracket
Example 1: 2 * ( ( 4/2 ) + 5 )
The above expression has two opening and two closing brackets which means that the above
expression is a balanced parenthesis.
Example 2: 2 * ( ( 4/2 ) + 5
The above expression has two opening brackets and one closing bracket, which means that both
opening and closing brackets are not equal; therefore, the above expression is unbalanced.

Algorithm to check balanced parenthesis:

Now, we will check the balanced parenthesis by using a variable. The variable is used to determine
the balance factor. Let's consider the variable 'x'. The algorithm to check the balanced parenthesis
is given below:
Step 1: Set x equal to 0.
Step 2: Scan the expression from left to right.
For each opening bracket "(", increment x by 1.
For each closing bracket ")", decrement x by 1.
This step will continue scanning until x<0.
Step 3: If x is equal to 0, then
"Expression is balanced."
Else
"Expression is unbalanced."

Let's understand the above algorithm through an example.

Suppose expression is 2 * ( 6 + 5 )

30
Data Structures
Solution:
 First, the x variable is initialized by 0.
 The scanning starts from the variable '2', when it encounters '(' then the 'x' variable gets
incremented by 1 and when the x reaches to the last symbol of the expression, i.e., ')' then
the 'x' variable gets decremented by 1 and it's final value becomes 0.
 We have learnt in the above algorithm that if x is equal to 0 means the expression is
balanced; therefore, the above expression is a balanced expression.
************************************************************************************
OPTIONAL (Additional Information)

Arrays:
The array is a basic abstract data type that holds an ordered collection of items
accessible by an integer index. These items can be anything from primitive types
such as integers to more complex types like instances of classes. C provides a data
structure, the array, which stores a fixed-size sequential collection of elements of the
same type.
Instead of declaring individual variables, such as number0, number1, ..., and
number99, you declare one array variable such as numbers and use numbers[0],
numbers[1], and ..., numbers[99] to represent individual variables. A specific element
in an array is accessed by an index.
All arrays consist of contiguous memory locations. The lowest address
corresponds to the first element and the highest address to the last element.
Declaring Arrays: To declare an array in C, the programmer specifies the type of
the elements and the number of elements required by an array as follows:
dataType arrayName [ arraySize ];
This is called a single-dimension array. The arraySize must be an integer constant
greater than zero and type can be any valid C data type. For example, to declare a 5-
element array called marks of type integer, use this statement:
int marks [5];

Initializing Arrays: To initialize an array during declaration. You can initialize


array elements either one by one or using a single statement as follows:

int mark[5] = {79, 60, 80, 75, 90};

Here, we declared an array, mark, of integer type and size 5. Meaning, it can hold 5
integer values. The number of values between braces { } cannot be larger than the
number of elements that we declare for the array between square brackets [ ].

mark[0] mark[1] mark[2] mark[3] mark[4]

79 60 80 75 90

31
Data Structures
Here,
mark[0] is equal to 79
mark[1] is equal to 60
mark[2] is equal to 80
mark[3] is equal to 75
mark[4] is equal to 90
Accessing Array Elements: we can access elements of an array by using indices.
Suppose you declared an array mark as above. The first element is mark[0], second
element is mark[1] and so on.

mark[0] mark[1] mark[2] mark[3] mark[4]

79 60 80 75 90

Here,
 Arrays have 0 as the first index not 1. In this example, mark[0] is the first element
and it holds the value 79.
 If the size of an array is n, to access the last element, (n-1) index is used. In this
example, mark[4] is the last element and it holds the value 90.
 Suppose the starting address of mark[0] is 2120d. Then, the next address, a[1], will
be 2124d, address of a[2] will be 2128d and so on. It's because the size of a float is
4 bytes.
How to insert and print array elements:
int mark[5] = {79, 60, 80, 75, 90}
 insert different value to third element mark[2] = 50;
 take input from the user and insert in third element scanf (“%d”, &mark[2]);
 take input from the user and insert in (i+1) th elemen scanf (“%d”,&mark[i]);
 print first element of an array printf(“%d”, mark[0]);
 print ith element of an array printf(“%d”, mark[i-1]);

Following is an example, which will use all the above-mentioned three concepts viz.
declaration, assignment and accessing arrays:
// C program to store and calculate the sum of 5 numbers entered by the user using arrays.
#include<stdio.h>
#include<conio.h>
int main( )
{
int num[5], sum=0;

32
Data Structures
printf(“Enter five numbers : “);
/* Storing five numbers entered by user in an array and finding the
sum of numbers */
for (int i=0; i<5; ++i)
{
scanf(“%d”, &num[i])
sum+=num[i];
}
printf(“The sum of five integer numbers = %d”, sum);
return 0;
}

Output
Enter five numbers : 3 4 5 4 2
The sum of five integer numbers = 18
Representation of Arrays: In C, Arrays can be represented as a Single-dimensional
(or) Multi-dimensional. You can create an array of an array known as Multi-
dimensional array.
For example:
int A [3] [4];

Here, A is a two dimensional array. It can hold a maximum of 12 elements. You can think this array as
table with 3 rows and each row has 4 columns as shown below

int A [2] [4] [3];

FOR EXAMPLE
int A [2] [4] [3];
This array A can hold a maximum of 24 elements. That is each of the 2 elements can hold 4 elements,
which makes 8 elements and each of those 8 elements can hold 3 elements. Hence, total number of
elements this array can hold is 24

Initialization of two dimensional array


int test[2][3] = {2, 4, 5, 9, 3, 7};
Better way to initialize this array with same array elements as above.
int test[2][3] = { {2, 4, 5}, {9, 3, 7}};
Initialization of three dimensional array
int test[2][3][4] = {3, 4, 2, 3, 0, 7, 9, 11, 23, 12, 23, 2, 13, 4, 56,
3, 5, 9, 3, 5, 5, 1, 4, 9 };
Better way to initialize this array with same elements as above.

33
Data Structures
int test[2][3][4] = { { {3, 4, 2, 3}, {0, 7, 9, 11}, {23, 12, 23, 2} },
{ {13, 4, 56, 3}, {5, 9, 3, 5}, {3, 1, 4, 9} } };

//C Program to store marks of six subjects for students and display it.
#include <stdio.h>
const int STUDENT = 2;
const int SUBJECT = 6;
int main( )
{
int marks[STUDENT][SUBJECT];
printf("Enter marks of 6 subjects of first student and then second student. \n");
// Inserting the values into the marks array
for (int i = 0; i < STUDENT; ++i)
{
for(int j = 0; j < SUBJECT; ++j)
{
printf( "Student %d ", i + 1 “ Subject %d ", j + 1 “ Marks : ");
scanf(“%d”, &marks[i][j];
}
}
printf( "\n\nDisplaying Values:\n");
//Accessing the values from the marks array
for (int i = 0; i < STUDENT; ++i)
{
for(int j = 0; j < SUBJECT; ++j)
{
printf( "Student %d ",i+1 “ Subject %d", j+1 " Marks = %d", marks[i][j]);
printf(“/n”);
}
}
return 0;
}
Output
Enter marks of six subjects of first student and then second student.
Student 1, Subject 1 Marks : 62
Student 1, Subject 2 Marks : 75
Student 1, Subject 3 Marks : 80
Student 1, Subject 4 Marks : 45
Student 1, Subject 5 Marks : 50
Student 1, Subject 6 Marks : 70
Student 2, Subject 1 Marks : 80
Student 2, Subject 2 Marks : 55
Student 2, Subject 3 Marks : 60

34
Data Structures
Student 2, Subject 4 Marks : 68
Student 2, Subject 5 Marks : 75
Student 2, Subject 6 Marks : 40

Displaying Values:
Student 1, Subject 1 Marks = 62
Student 1, Subject 2 Marks = 75
Student 1, Subject 3 Marks = 80
Student 1, Subject 4 Marks = 45
Student 1, Subject 5 Marks = 50
Student 1, Subject 6 Marks = 70
Student 2, Subject 1 Marks = 80
Student 2, Subject 2 Marks = 55
Student 2, Subject 3 Marks = 60
Student 2, Subject 4 Marks = 68
Student 2, Subject 5 Marks = 75
Student 2, Subject 6 Marks = 40

Linked list implementation of stack

Instead of using array, we can also use linked list to implement stack. Linked list allocates the
memory dynamically. However, time complexity in both the scenario is same for all the operations
i.e. push, pop and peek.

In linked list implementation of stack, the nodes are maintained non-contiguously in the memory.
Each node contains a pointer to its immediate successor node in the stack. Stack is said to be
overflow if the space left in the memory heap is not enough to create a node.

The top most Node in the stack always contains null in its address field.

35
Data Structures
Adding a node to the stack (Push operation): Adding a node to the stack is referred
to as push operation. Pushing an element to a stack in linked list implementation is
different from that of an array implementation. In order to push an element onto the
stack, the following steps are involved.

Algorithm:

1. Create a node first and allocate memory to it.


2. If the list is empty then the item is to be pushed as the start node of the list. This includes
assigning value to the data part of the node and assign null to the address part of the node.
3. If there are some nodes in the list already, then we have to add the new element in the
beginning of the list (to not violate the property of the stack). For this purpose, assign the
address of the starting element to the address field of the new node and make the new node, the
starting node of the list.

Time Complexity: o(1)

Deleting a node from the stack (POP operation): Deleting a node from the top of
stack is referred to as pop operation. Deleting a node from the linked list
implementation of stack is different from that in the array implementation. In order to
pop an element from the stack, we need to follow the following steps:
1. Check for the underflow condition: The underflow condition occurs when we try to pop from
an already empty stack. The stack will be empty if the head pointer of the list points to null.
2. Adjust the head pointer accordingly: In stack, the elements are popped only from one end,
therefore, the value stored in the head pointer must be deleted and the node must be freed. The
next node of the head node now becomes the head node.

Time Complexity : o(n)

Display the nodes (Traversing): Displaying all the nodes of a stack needs traversing
all the nodes of the linked list organized in the form of stack. For this purpose, we
need to follow the following steps.

36
Data Structures
3. Copy the head pointer into a temporary pointer.
4. Move the temporary pointer through all the nodes of the list and print the value
field attached to every node.

Time Complexity : o(n)


//C program to implement Stack using Linked List(Pointers)
#include <stdio.h>
#include <stdlib.h>
void push( );
void pop( );
void display( );
struct node
{
int val;
struct node *next;
};
struct node *head;
void main ()
{
int choice=0;
printf("\n*******Stack operations using linked list********\n");
printf("\n \n");
while(choice != 4)
{
printf("\n\nChose one from the below options...\n");
printf("\n1.Push\n2.Pop\n3.Show\n4.Exit");
printf("\n Enter your choice \n");
scanf("%d",&choice);
switch(choice)
{
case 1: push( );
break;
case 2: pop( );
break;
case 3: display( );
break;
case 4: printf("Exiting... ");
break;
default: printf("Please Enter valid choice ");
}
}

37
Data Structures
}
void push ( )
{
int val;
struct node *ptr = (struct node*)malloc(sizeof(struct node));
if(ptr == NULL)
{
printf("not able to push the element");
}
else
{
printf("Enter the value");
scanf("%d",&val);
if(head==NULL)
{
ptr->val = val;
ptr -> next = NULL;
head=ptr;
}
else
{
ptr->val = val;
ptr->next = head;
head=ptr;
}
printf("Item pushed");
}
}
void pop( )
{
int item;
struct node *ptr;

if (head == NULL)
{
printf("Underflow");
}
else
{
item = head->val;

38
Data Structures
ptr = head;
head = head->next;
free(ptr);
printf("Item popped");
}
}
void display( )
{
int i;
struct node *ptr;
ptr=head;
if(ptr == NULL)
{
printf("Stack is empty\n");
}
else
{
printf("Printing Stack elements \n");
while(ptr!=NULL)
{
printf("%d\n",ptr->val);
ptr = ptr->next;
}
}
}

***********************************************************************************

39

You might also like