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

Data Structure Using C

Uploaded by

Abhay Goswami
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
311 views

Data Structure Using C

Uploaded by

Abhay Goswami
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 98

Data structure using C

BASIC TERMINOLOGIES
DATA : Data are simply values or set of values.
INFORMATION : Meaningful or processed data is called information.
DATA ITEM : Data Item refers to a single unit of values.
GROUP ITEMS : Data items that are divided into subitems are called
group items. eg,.name may be divided into three subitems, first,
middle and last name.
ENTITY: An entity is something that has certain properties or attributes
which may be assigned values. eg, employee is an entity. The
attributes and values of an entity are:
Attributes: Name Age Address
Values : RAM 28 XYZ street
ENTITY SET : Entities with similar attributes form an entity set.
DEFINITION OF DATA STRUCTURES
Data may be organized in many different ways.
The logical or mathematical model of a particular organization
of data is called data structure.

The study of data structures includes the following three steps:


1. Logical or mathematical description of the structure.
2. Implementation of the structure on a computer.
3. Quantitative analysis of the structure, which includes determining the
amount of memory needed to store the structure and the time
required to process the structure.

The choice of a particular data model depends on two


considerations:
1. The structure must be rich enough to mirror the actual
relationships of the data in real world.
2. The structure should be simple enough that one can effectively
process the data when necessary.
TYPES OF DATA STRUCTURES
DATA STRUCTURES

PRIMITIVE NON PRIMITIVE

INT CHAR FLOAT LINEAR NON LINEAR

ARRAYS STACKS QUEUES LISTS

TREES GRAPHS
LINEAR DATA STRUCTURES: -A data structure whose elements
form a sequence, and every element in the structure has a unique
predecessor and unique successor. Eg. Arrays,linked lists, stacks
and queues.
NON-LINEAR DATA STRUCTURES: A data structure whose
elements do not form a sequence, and there is no unique
predecessor or unique successor. Eg. Trees and graphs.

We will discuss about these data structures:


1. Arrays: An array is a list of finite number of elements of same
data type , ie integers, real or characters .The individual elements
of an array are accessed using an index to the array. Arrays can
be one- dimensional or linear arrays, two dimensional arrays or
multidimensional arrays.
2. Linked Lists: A linked list is a linear collection of data elements
called nodes. The linear order is maintained by pointers . A
linked list can be linear ( one way ) linked list or doubly (two-way)
linked list.
3.Stacks: A stack, also called Last In First Out (LIFO) system , is a
linear list in which insertions and deletions can take place only at
one end, called the top.
4.Queues: A queue, also called First In First Out (FIFO) system , is a
linear list in which insertions can take place at one end of the list ,
called the rear of the list , and deletions can take place only at the
other end , called the front of the list.
5.Trees: A tree is a data structure that represents a hierarchical
relationship between various elements.
6.Graphs: A graph G is a ordered set (V,E) where V represents the
set of elements , called nodes or vertices and E represents the
edges between these elements. They are used to represent
relationships between pair of elements , which are not necessarily
hierarchical in nature.
OPERATIONS ON DATA STRUCTURES

1. Traversal : Accessing each element exactly once in


order to process it. This operation is called visiting the
element.
2. Searching : Finding the location of a given element.
3. Insertion : Adding a new element to the structure.
4. Deletion : Removing a existing element from the
structure.
5. Sorting : Arranging the elements in some logical order.
6. Merging : Combining the elements of two similar sorted
structures into a single structure.
INTRODUCTION TO ALGORITHMS
An algorithm is a finite set of steps defining the solution
of a particular problem. Every algorithm must satisfy the
following criteria:
• Input : There are zero or more values which are
externally supplied.
• Output : At least one value is produced.
• Definiteness : Each step must be clear and
unambiguous.
• Finiteness : If we trace the steps of algorithm, then for all
cases, the algorithm must terminate after a finite number
of steps.
• Effectiveness : Each step must be basic and feasible.
CONVENTIONS USED IN ALGORITHMS
1. Steps : The steps of algorithm are executed one after
the other.
2. Control : Control may be transferred to step n of the
algorithm by the statement “Go to step n” or control
structures are used to to transfer the control.
3. Variable names: variable names will use capital
letters. Set is used to declare and initialize the
variables. eg. Set K:=1.
4. Exit: The algorithm is completed when the statement
“Exit” is encountered.
5. Comments: Each step may contain a comment in
brackets ( [ ).
6. Assignment Statement :Assignment statement will
use dots-equal notation (:=). Eg. MAX:=DATA[1].
7. Input and Output: Data may be input and assigned to variables by
means of a Read statement with the following form:
Read : Variable names
Similarly, messages placed in quotation marks, and data in
variables may be output by means of Write or Print statement with
the following form:
Write : Messages and/or variable names.
8. Selection Logic :It employs number of conditions which lead to a
selection of one out of several alternative modules. Structure of
this logic is:
If condition, then:
[ Module A ]
Else if condition, then
[ Module B ]
Else: [ Module C ]
[End of If structure]
9.Iteration Logic : Each type begins with a Repeat statement and is
followed by a module , called the body of loop. The structure of
repeat – for loop is:
Repeat for K = R to S by T :
[ Module ]
[ End of loop ]
The structure of repeat – while loop is:
Repeat while condition :
[ Module ]
[ End of loop ]
COMPLEXITY OF ALGORITHMS
The complexity of an algorithm M is the function
f(n) which gives the running time and/or storage space
requirement of the algorithm in terms of the size n of
the input data.
The time and space used by an algorithm are the
two main measures for the efficiency of algorithm.
The time is measured by counting the number of
key operations ie. The number of comparisons.
The space is measured by counting the
maximum of memory needed by the algorithm.
There are 3 cases for investigating the complexity
of an algorithm. They are:
1. Worst Case: maximum value of f(n) for any input.
2. Average Case: expected value of f(n) .
3. Best Case: minimum value of f(n) for any input.
RATE OF GROWTH OF ALGORITHM
The complexity f(n) of an algorithm M increases as the size
of the input data n increases. To examine the rate of increase of
f(n) , we will compare it with some standard functions. The following
table gives the approximate values of standard functions for certain
values of n.The table shows that the logarithmic function grows
most slowly,the exponential function grows most rapidly and
the polynomial function grows according to the exponent.

G(n) Log N N N2 N3 2n
n n log n
5 3 5 15 25 125 32
10 4 10 40 100 103 103
100 7 100 700 104 106 1030
1000 10 103 104 106 109 10300
ARRAYS
• An array is a way to reference a series of memory locations
using the same name.
• Each memory location is represented by an array element.
• An array element is similar to one variable except it is identified by
an index value instead of a name. An index value is a number used
to identify an array element.
An array is declared as: type name[size]
The ‘type’ indicates the name of the array.
The ‘name’ indicates the name of the array.
The ‘size’ indicates the number of elements of ’type’ that ‘name’
contains.
• E.g int V[100];
• Which defines an array named V to hold 100 values of the primitives
type int.
• The variable v decays to the reference integral type in most
expression contexts; the value obtained from that decay points to
the memory address of the first element.
PV+1
PV+2

V:

V[0] V[1] V[2] ……… V[99]


Address of the memory in an array

Let us use the notation:


loc(LA[k])= address of the element LA[k] of the
array LA
the element of LA are stored in succesive memory
cells.Accordingly. The computer doesn’t need to keep
track of the address of every element of LA, but needs to
keep track only of the address of the first element of
LA, denoted by Base(LA)
and called the base address of LA.Using this address
base(LA), the computer calculate the address of any
element of LA by the formula

loc(LA[K])= base(LA) + w(K-Lowerbound)


where w = number of words per memory cell for the
array LA.
Ques:Consider the array which records the number of automobiles
sold each year from 1932 through 1984. Suppose AUTO apears in
memory i.e Base(AUTO)=200 and w=4 words per memory cell for
AUTO.then
200
201 AUTO[1932]
Loc(AUTO[1932])=200 202
203
Loc(AUTO[1933])=204
204
AUTO[1933]
Loc(AUTO[1934])=208

What will be the address of the array element AUTO[1934]


For the year K=1965.
• Loc(AUTO[1965])=base(auto)+w(1965-lower bound)
=200 + 4(1965-1932)
=332

Ques:Consider the linear array AAA(5:50), BBB(-5:10) & CCC(18)


a) Find the number of element in each array.
b) Suppose base(AAA)=300 and w=4 words per memory cell for
AAA(15),AAA(35) & AAA(55).
• Sol
length= UB-LB+1
length(AAA)=50-5+1=46
length(BBB)=10-(-5)+1=16
length(CCC)=18-1+1=18(since LB=1)
=18-0+1=19(since LB=0)

• Loc(AAA[k]=base(AAA)+w(k-LB)
Loc(AAA[15])=300+4(15-5)=340
Loc(AAA[35])=300+4(35-5)=420
AAA[55] is not an element of AAA, since 5 exceed UB=50
Traversing Linear Array
• Here LA is a linear array with lower bound LB and upper
bound UB.This algorithm applies an operation process to
each element of LA
Algo1
step 1: [Initialize counter] set k:=LB
step 2: Repeat step 3 and 4 while k<=UB
step 3: [Visit element] Apply process to LA[k]
step 4: [Increase counter] Set k=k+1
[End of step 2 loop]
step 5: Exit
• Algo 2:
step 1: Repeat for k=LB to UB
Apply PROCESS to LA[k]
[End of loop]
step 2: Exit
Insertion into a linear array
• Insert(LA,N,K,ITEM)
Here LA is a linear array with N element and k is a positive
integer such that k<=N. This algorithm inserts an element ITEM
into Kth position in LA
step1: [Initialize counter] set J:=N
step2: Repeat step 3 and 4 while J>=k
step3:[Move Jth element downward] set LA[J+1]:=LA[J]
step4:[Decrease counter] set J=J-1
[End of step 2 loop]
step5:[Insert element] set LA[K]=ITEM
step6:[Reset N] set N=N+1
step7: Exit
Deletion from a Linear Array

• Delete(LA,N,K,ITEM)
Here LA is a Linear array with N element and K is a positive
integer such that K<=N.This algorithm deletes the Kth element
from LA
step1: set ITEM:=LA[K]
step2: Repeat for J=K to N-1
step3:[Move (J+1)th element upward] set LA[J]:=LA[J+1]
[End of loop]
step4:[Reset the number N of element in LA] set N:=N-1
step5: Exit
Searching:-Linear Search
• Linear(Data,N,Item,Loc)

HereData is a linear array with N elements and Item is a


given item of information. This algorithm finds the location loc
of Item in Data or sets Loc=0 if the search is unsuccessful.
step1: [Initialize] Set K :=1 and LOC:=0
step2: Repeat Steps 3 and 4 while LOC=0 and K<=N
step3: If ITEM=DATA[K],then: Set LOC:=K
step4: Set K:=K+1
[End of Step 2 loop]
step5:[Successful?]
If LOC=0,then:
Write: ITEM is not in the array data
Else:
Write :LOC is the location of ITEM
[End of If structure]
step6: Exit
Complexity of the Linear Search
Algorithm:-
• Clearly, the worst case occurs when one must search through the
entire array Data i.e when Item doesn’t appear in data. In this case,
the algorithm requires
f(n)=n+1 comparisons

Average case
f(n)= 1.p1 +2.p2+……….+n.pn+(n+1).q
In particular, suppose q is very small and Item appears with equal
probability in each element os Data. Then q=0 and each pi
=1/n.Accordingly,
f(n)=1.1/n+2.1/n+……..+n.1/n+(n+1).0
=(1+2+…….+n).1/n
=n(n+1).1/n= (n+1)/2
Binary Search
• Binary(Data,LB,UB,Item,Loc)
Here Data is a sorted array with lower bound LB and upper
bound UB and Item is a given item of information.The variable
MID denotes, middle location of a segment of element of
Data.This algorithm finds the location Loc of item in Data or set
Loc=Null
step1:[Initialize segment variable] set MID=INT((LB+UB)/2)
step2: Repeat step3 and step 4 while LB<=UB && Data[Mid]!=Item
step3: If Item<Data[MID], then:
set UB:=MID-1
else:
set LB:=MID+1
step4: set MID:= INT((LB+UB)/2)
[End of step 2 loop]
step5: If Data[MID]=Item,,then:
set Loc:=MID
else:
set Loc:=NULL
[End of If structure]
step6: Exit
• Example
Let Data be the following sorted 13 element array.
DATA: 11,22,30,33,40,44,55,60,66,77,80,88,99.Suppose Item=40,
find out the location by using Binary Search.

• Complexity of the Binary Search Algorithm


The complexity is measured by the number F(n) of comparisons tp
locate ITEM in DATA where DATA contains N elements.
Observe that each comparison reduces the sample size in half.
Hance we require at most F(n) comparisons to locate ITEM where
2f(n)>n or equivalently f(n)= log2n+1
Sorting, Searching & Merging Algorithm
• Sorting
• Internal sorting:- deal with sorting the data held in memory of the
computer.
• Example:
• Bubble sort, selection sort, Insertion sort, Bucket sort, Merging sort,
Quick sort, Heap sort, Shell sort.
• External sorting:- deals with sorting the data storing in data files.
This method is used when the volume of the data is very large and
cannot be held in computer’s main memory.
• Bubble Sort
• Consider the sorting of the following array in ascending order:
• 12 40 3 2 15
12 12 12 12 12
40 40 3 3 3
3 3 40 2 2
40
2 2 2 15
15 15 15 15 40

3 2 2
3 3 3
3 3
12 2 2 2
2 12 12 12 12
12
15 15 15
15 15 15
40 40 40 40 40 40
• Bubble(DATA,N))
Here DATA is an array with N elements.This algorithm sorts the
elements in DATA.

step 1: Repeat steps 2 and 3 for K=1 to N-1


step 2: Set PTR:=1
step 3: Repeat while PTR<= N-K:
(a) If DATA[PTR] > DATA[PTR+1],then:
Interchange DATA[PTR] and DATA[PTR+1]
[End of If Structure]
(b) Set PTR:=PTR+1
[End of Inner Loop]
[End of step 1 outer loop]
step 4: Exit.
Complexity Of Bubble Sort Algorithm

The time for sorting algorithms is measured in terms of


no. of comparisons.In Bubble Sort, there are n-1
comparisons during the first pass,which places the
largest element in the last position ;n-2 comparisons in
second step; ans so on. Thus
f(n)= (n-1)+(n-2)+………+2+1=n(n-1)/2=n2/2+O(n)=O(n2)
So, the time required to execute the bubble sort
algorithm is proportional to n2, where n is the no. of
input items.
Loc=0 Small=0
Selection 20 35 40 100 3 10 15

Sort
Pass 1 20 35 40 100 3 10 15
Loc=4 Small=4

Pass 2 3 35 40 100 20 10 15 Loc=5 Small=5

3 10 40 100 20 35 15 Loc=6 Small 6


Pass 3

3 10 15 100 20 35 40 Loc=4 Small=4


Pass 4

Pass 5
3 10 15 20 100 35 40 Loc=5 Small=5

Pass 6 3 10 15 20 35 100 40 Loc=6 Small=6

3 10 15 20 35 40 100
• MIN(A,K,N,LOC)
This algorithm finds the location of the smallest element among
A[K],A[k+1]…………….A[N]
1. Set MIN:=A[K] and LOC:=K
2. Repeat for J=K+1 to N:
If MIN > A[J],then: Set MIN:=A[J] and LOC:=J
[End of loop]
3. Return

Selection sort Algorithm


Selection(A,N) This algorithm sorts the array with N elements
1. Repeat steps 2 and 3 for K=1 to N-1
2. Call MIN(A,K,N,LOC)
3.Interchange A[K] and A[LOC]
[End of step 1 loop]
4.Exit.
Complexity of Selection Sort is same as that of Bubble Sort.
• Insertion 35 20 40 100 3 10 15

a[1]<a[0]
Pass 1 35 20 40 100 3 10 15

a[2]>a[1]
Pass 2 20 35 40 10 3 10 15

20 35 40 100 3 10 15 a[3]>a[2]
Pass 3

20 35 40 100 3 10 15 a[4]<a[3]<a[2]<
Pass 4
a[1]<a[0]
Pass 5
3 20 35 40 100 10 15 a[5]<a[4]<a[3]<
a[2]<a[1]
Pass 6 3 10 15 20 35 40 100 a[6]<a[5]<a[4]<
a[3]<a[2]
3 10 15 20 35 40 100
Insertion(A,N)
This algorithm sorts the array A with N elements.
1. Repeat steps 2 to 4 for K=2 to N
2. Set TEMP:=A[K] and PTR:=K-1
3. Repeat while TEMP < A[PTR]:
(a) Set A[PTR+1]:=A[PTR]
(b) Set PTR:=PTR-1
[End of loop]
4. Set A[PTR+1]:=TEMP
[End of step 1 loop]
5. Exit.

Complexity of Insertion Sort is same as that of Bubble Sort.


• Implementing One Dimensional Arrays
The one dimensional array can be implemented easily.The C declaration.
int b[100];
• Arrays as parameters:-
float avg(float a[],int size)
{ int I;
float sum=0;
for(i=0;i<size;i++)
sum+=a[i];
return(sum/size);
}
• Example
#include<stdio.h>
#include<conio.h>
void main()
{
int a[5];
fun(a,5);
getch();
}

fun(int a[],int n)
{ int i;
printf("enter the values");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
printf("%d",a[i]);
}
• Multidimensional Array:-
• A multidimensional array consists of two or more arrays defined by
set of array elements.
• Each set of array elements is an array.
• The first set of array elements is considered the primary array, and
the second and subsequent sets of array elements are considered
sub-arrays.
0 0

0 1 Sub array
Primary set
1 0

1 1

Array elements
• There are two arrays in the multidimensional array in the fig.

• Why to use Multidimensional Array?


• A multidimensional array can be useful to organize subgroups of
data within an array.
• Let us say that a students has three grades, a mid-term grade, a
final exam grade, and a final grade.
• You can store all three grades for an endless number of students in
a two-dimensioal array.
• Declares a multidimensional arrays of integers.
Int grades[3][4]
0 0 1001 Student ID
Student 1001 0 1 90 Mid-term grade
0 2 80 Final exam grade
95 Final grade
0 3
1 0 1002
1 1 70
Student 1002
1 2 85
1 3 75
2 0 1003
2 1 80
Student 1003
2 2 80
2 3 95
All three grades can be stored in a multidimensioal array(row
• Multidimensional Array in Memory
• Data stored in a multidimensional array is stored sequentially by
sets of elements.
• The first set of four elemnts is placed in memory, followed by the
second set of four array elements and so on.

1001 90 80 95 1002 70 80 75 1003 80 80 95

• The name of a multidimention array references the memory address


of the first element of first set of four elements.
• Declaring a multidimensional Array:-
• The general declaration of a 2D array is given as,
type name[row][column];
type specifies data type of the array
name specifies name of the array
row specifies number of rows in the array
column specifies number of column in the array
• Although you can create an array with any size multi-dimension, many
programmers limit an array to two dimensions.
• Example:-
int grades[3][4];
In C:
int grades[3][4]={ {1001,90,80,95} , {1002,70,80,75} , {1003,80,80,95} } ;
• Calculation:-

• Length = Upper bound – Lower bound +1


Integer_Number[2:5,-3:1]
Length of first dimension = 5-2+1=4
Length of second dimension = 1+3+1=5
The total no. of elements will be 4*5 =20 elements
• Address:- Matrix A[M,N]
(Column-major order)
loc(A[J,K])= Base(A) +w[M(K-1)+(J-1)]
or
(Row-major order)
loc(A[J,K])= Base(A) +w[N(J-1)+(K-1)]
• QUES:- Consider the 25 x 4 matrix array score. Suppose
Base(score)=200 and there are w=4 words per memory cell.
Futhermore, suppose the programming language stores two
dimensional array using row-major order. Then find out the address
of score[12,3],the test of the twelvth student.(Ans-384)
Applications Of Linear Arrays

Linear arrays are used to represent all sorts of lists.They are used
to implement other data structures such as stacks,queues,heaps
etc.

Limitations of Linear Arrays

1. The prior knowledge of number of elements in the linear array is


necessary.
2. These are static structures.ie the memory used by them cannot
be reduced or extended.
3. Since the elements are stored in consecutive locations, the
insertions and deletions in these arrays are time consuming.
Sparse Matrices
• Sparse matrix is a matrix that has relatively few non-zero entries.It may be
represented in much less than n x m space.
• Computer’s memory is costly, so there is no point in wasting memory in
storing elements that do not deserve a place in it. Sparce matrix is the case
in point.
• If lot of elements from matrix have a value 0 then the matrix is known as
sparse matrix. There must be a way to represent sparse matrix, because
majority of elements of matrix are 0.
• So storing only non-zero elements and keep intact the functionality of matrix
can save a lot of memory space.

0 0 1 2

0 0 0 5

1 0 2 0

2 0 3 0
• A common way of representing non-zero elements of a sparse matrix is the
3-type form.
• In this form each non-zero element is stored in a row, with first and second
element of this row containing the row and column in which the element is
present in the original matrix.

• (A) Triangular Sparse Matrix:-


In such type of sparse matrix, the non-zero entries are present only on
diagonal or in upper triangle or in lower triangle.
The lower triangular sparse matrix contains non-zero entries only on or
below main diagonal(A(I,j)=0 for i<j)

-3 7

8 9 2
• When the non-zero elements are present only on or above main
diagonal, the matrix is called upper triangular sparse matrix.
( A (i,j)=0 for i>j)
2 -4 0
6 2

• (B) Diagonal Matrix


When the non zero elements are present only on the diagonal position.
(A(i,j)=0 for i!=j)
• (C)Tridiagonal Sparse Matrix:-(A(i,j)=0 for | i – j|>1)
In this type of sparse matrix, the non-zero entries can occur only on
main diagonal or on immediate above or below the diagonal.
1 2 3 4 5
1 5 -4
2 7 -6 2

-5 7 -3
3

4 4 -8 5

5 2 9
Sequential Representation of sparse matrix:-

Array Row Column Data


1 1 1 4
4 0 0 0 0
2 2 1 2
2 5 0 0 0
3 2 2 5
0 7 6 0 0 4 3 2 7
8 9 4 7 0 5 3 3 6

3 0 0 2 8 6 4 1 8

7 4 2 9

8 4 3 4
9 4 4 7
11 5 1 3
12 5 4 2
13 5 5 8
pointers

Variable Value Address


code 2125 1500

ptr 1500 2000

Pointer as a
• Declaring and Initializing Pointers:-
variable
The syntax for declaring pointer variable is
data-type * ptrName;
int *int_ptr;
This statement declares a pointer variable int_ptr that can point to an integer type
variable.
• Initialization:-
{ int *ptr , x=10 , y ; y = * ptr
ptr = &x; y = * &x
y = *ptr; } y = *(&x)

* ptr
5002 10

ptr (5000) 5002


concept

• int a,*p = &a; \\ valid


• float a , b;
int x , *p; \\ invalid
p = &a;
• int *p; \\ invalid
p = 5368;
• int *p = &x , x ; \\ invalid
• y = *p1 + *p2; \\ valid
• sum = sum + *p1; \\ valid
• z = 5 - *p1/ *p2; \\ valid
• *p2 = *p2 + 10; \\ valid
• p1++; ++p1; --p1; p1--;
• p1 + 4; p2 – 2; \\ valid
• p1 – p2 ;

• p1/p2; p1+p1; p1xp2; p1/3 \\ invalid


String
• Just as group of number can be stored in an array, a group of
characters can also be stored in an array. Such an array of characters
is often called a string.
• A string variable is the name of array declared to hold a string of
specified size.
• The declared size of array should be one more than the maximum size
of the string, as every string must be terminated by null ‘\0’ character.
• A string constant is sequence of characters enclosed in double
quotes.
“ Hello! You are welcome”
• In C, a string variable can also be initialized during declaration using
following approaches.
char mess[ ]={‘y’,’o’,’u’,’ ‘,’ ‘a’ ,’r’,’e’,’ ‘,’w’,’e’,’l’,’c’,’o’,’m’,’e’,’\0’}
• In former approach, string variable mess is initialized as sequence
of character constants.In this approach it is programmer’s job to
specify the null character(‘\0’) as the last character.
• char mess [ ] = “you are welcome”;

• Representing String in Memory:-

H e l l o \0

Array representation of string


“Hello”
• Length of string:-

int strlength( char *charPtr) {


int Len=0;
while( *charPtr++)
len++;
return len;
}

strlen ( ):
Syntax : len = strlen ( ptr );

Int len ;
Char str[ ] = “ hello “;
len = strlen( str );
• Copying a string:-
void strCopy( char *dest, char *source) {
char *ptr1, *ptr2;
ptr1 = source;
Syntax : strcpy ( ptr2, ptr1 );
ptr2 = dest;
while(*ptr1) {
*ptr2 = *ptr1;
ptr1++;
ptr2++; }
*ptr2 = ‘ \ 0 ’ }
• Appending a string to another string:-
char *strConcatenate( char *dest, char *source) {
char *ptr1 , *ptr2;
ptr1 = source;
ptr2 = dest;
while(*ptr2++) ;
ptr2--; Syntax : strcat ( ptr2 , ptr1 ) ;
while(*ptr1) {
*ptr2 = *ptr1;
ptr1++;
ptr2++; }
*ptr2 = ‘ \0 ‘;
return dest;
}
• Comparing two Strings:-

int strCompare ( char *str1, char *str2) {


char *ptr1, *ptr2;
ptr1 = str1;
ptr2 = str2;
while ( ( *ptr1 == *ptr2) &&( *ptr1 && *ptr2) )
{ ptr1++;
ptr2++; }
if ( *ptr1 == ‘\0’ && *ptr2 == ‘\0’)
return 0;
else if ( *ptr1 == ‘\0’)
return -1; Syntax : strcmp ( ptr1,ptr2 );
else if( *ptr2 == ‘\0’)
return 1;
else return ( *ptr1 - *ptr2); } }
• Reversing string:-
void strReverse( char *str1)
char *ptr1, *ptr2, temp;
ptr1 = str1;
ptr2 = str1;
while ( *ptr2 != ‘\0’ )
ptr2++;
ptr2--;
while ( ptr1 < ptr2 ) {
temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
ptr1++;
ptr2--;
}
• Converting Alphabets of String to Uppercase:-
void toUppercase ( char *str1) {
char *ptr1;
ptr1 = str1;
while ( *ptr1 )
{ if ( ( *ptr1 >= ‘a’ ) && ( *ptr1 <= ‘z’ ) )
*ptr1 - = 32;
ptr1++;
} }
• Converting alphabets of string to lowercase:-

void toLowerCase( char *str1 ) {


char *ptr1;
ptr1 = str1;
while ( *ptr1 )
{ if ( ( *ptr1 >= ‘A’ ) && ( *ptr1 <= ‘Z’ ) )
*ptr1 + =32;
ptr1++;
} }
Stacks

• A stack is a homogeneous collection of items of any one type,


arranged linearly with access at one end only, called the top. This
means that data can be added or removed from only the top.
Formally this type of stack is called a Last In, First Out (LIFO) stack.
• Data is added to the stack using the Push operation, and removed
using the Pop operation.
• A stack is simply a list of elements with insertion and deletion
permitted at one end called the stack top. That means that it is
possible to remove elements from a stack in reverse order from the
insertion of elements into the stack.
Array Representation and Implementation of Stack

• One of the way to implement a stack is by using a one dimensional


array ( also know as a vector ). When implemented this way, the
data is simply stored in array.
• Top is an integer value, which contains the array index for the top of
the stack.
• Each time data is added or removed, top is incremented or
decremented accordingly, to keep track of the current top of the
stack.
10 top
20
30
40
Array
• Stack implemented as array are useful if a fixed amount of data is to
be used.
• However, if the amount of data is not a fixed size, then an array is a
poor choice for implementing a stack.
• An array would be a poor choice, as you would have to declare it to
be large enough that there is no danger of it running out of storage
space when the procedure “ called “ many times. This can waste a
significant amount of memory if the procedure normally only “called”
a few times.
• The limitation of an array implementation is that the stack can’t grow
and shrink dynamically as per the requirement
• Procedure:-
Push(stack, top, maxstk,item)
step 1: [stack already filled]
If top = maxstk , then print: overflow, return
step 2: set top = top + 1 [ Increase top by 1 ]
step 3: set stack[top] = item [ Inserts item in new top
position]
• Procedure:-
POP(stack, top, item)
step 1: [stack has an item to be removed]
if top = 0 then underflow, and return
step 2: set item = stack[top]. [assign top element to item]
step 3: set top = top – 1 [ decrease top by 1 ]
#include< stdio.h>
#define max 100
Struct stack
{
int top, s[max];
} st;
void push();
void pop();
void main()
{ int x;
st.top = 0;
while(1)
{
printf(“enter choice \n”);
printf(“1. push \n”);
printf(“2. pop \n”);
printf(“3. exit \n”);
scanf(“%d”, &x);
switch( x )
{
case 1 : push( ); break;
case 2 : pop(); break;
case 3 : exit;
}
}
}
• void push( )
• { int x;
• If (st.top > max – 1)
• { printf(“overflow\n”);
• return; }
• printf(“enter item \n”);
• scanf(“%d” , &x);
• st.s[st.top++] = x; }

• Void pop( )
• { int x;
• If (st.top == 0)
• { printf(“ underflow \n”);
• return; }
• x = st.s[st.top];
• st.top = st.top -1;
• printf(“%d” x);
• }
Applications of stack

• Stack are used to pass parameters between functions. On call to a


function, the parameters and local variables are stored on a stack.
• High level programming languages, that provides support for
recursion use stack for bookkeeping. Remember, in each recursive
call, there is need to save the current values of parameters, local
variable and return address.
• Stacks are used for expression conversion
(a) Infix to postfix
(b) Infix to prefix
© Postfix to infix
(d) Prefix to infix
• Stacks are used for evaluation of expression.
• Stacks are used to convert decimal no. to binary form.
Arithmetic Expressions:-
• The most common arithmetic operations, the operator symbol is
placed b/w its two operands. For example
a/b, x*y, c-d
This is called Infix notation.
• A notation, in which the operator symbol is placed before its two
operands is called “ Polish Notation” or “Prefix notation”
Example /ab, *xy, -cd

• Similarly, a notation is which the operator symbol is placed after its


two operands is called “ Reverse Polish Notation”
ab/, xy*, cd-
This notation is also called postfix notation,
• Conversion of infix to postfix expression:-
Consider the following arithmetic infix expression Q.
Q: A +( B* C –( D/F^F )* G)* H
Symbol Stack Expression P
A ( A
+ (+ A
( (+( A
B (+( AB
* (+(* AB
C (+(* ABC
- (+(- ABC*
( (+(-( ABC*
D (+(-( ABC*D
/ (+(-(/ ABC*D
E (+(-(/ ABC*DE
^ (+(-(/^ ABC*DE
F (+(-(/^ ABC*DEF
) (+(- ABC*DEF^/
* (+(-* ABC*DEF^/
G (+(-* ABC*DEF^/G
) (+ ABC*DEF^/G*-
* (+* ABC*DEF^/G*-
H (+* ABC*DEF^/G*-H
) ABC*DEF^/G*-H*+
Consider the following algebric expression
and convert it into postfix notation:-

1. P*Q^R+S
2. A && B || C || ! (E>F)
3. [A + (B – C)] * [(D – E) / (F – G + H)]
4. A+B*C–D/F
5. (A + B) / D ^ ( ( E – F) + G)
6. A + (B * C – (D / E – F * G) * H)
7. 5 * (6 + 2) – 12 / 4
• Transforming Infix Expressions into Postfix Expressions:-
Polish( Q, P) Suppose Q is an arithmeric expression written in infix
notation. This algorithm finds the equivalent postfix expression P.
1. Push “( “ onto stack, and add “ )“ to the end of Q.
2. Scan Q from left to right step3 to step6 for each element of Q unit

the stack is empty.


3. If an operend is encountered, add it to P.
4. If a left parenthesis
X is encountered, push it onto stack.
5. If an operator is encountered , then
a) Repeatedly pop from stack and add to P each operator which
has the
x same precedence as or higher precedence than
b) Add to stack.
6. If a right parenthesis is encountered, then x
a) Repeatedly pop from stack and add to P each operator until a
left paraenthesis is encountered.
b) Remove the left parenthesis. [Do not add the left parenthesis to
p]
[ End of if structure]
[ End of step2 loop]
7. Exit.

Evaluate the following postfix expressions:

• ABCDE+*+-
• AB+CD*+E*
Evaluation of a post expression
• Algorithm:- This algoithm finds the value of an arithmetic
expression P written in postfix notation.
1. Add a right parenthesis “ )” at the end of P.
2. Scan P from left to right and repeat step 3 and 4 for each
element of P until “ )” is encountered.
3. If an operand is encountered, put it on stack.
4. If an operator X is encountered, then
a) Remove the top two elements of stack, where A is top
element of stack and B is the next to top element.
b) Evaluate B X A
c) Place the result of back on stack.
[End of if structure]
[End of step2 loop]
5. Set value equal to the top element on stack
6. Exit.
Recursion

• Recursion is a fundamental concept in


mathematics.When a function is defined in terms of itself
then it is called a recursive function.

• There must be certain criteria,called base criteria, for


which the function does not call itself.

• Each time the function does call itself(directly or


indirectly), it must be closer to the base criteria, i.e, it
uses an argument(s) closer than the one it was given.
1. The factorial can be defined recursively as
1 if n=0
n! =
n.(n-1)! if n>0
• Let us compute 4! using recursive definition. This computation
requires following steps
• 4!= 4.3!
• 3!= 3.2!
• 2!= 2.1!
• 1!=1.0!
• 0!= 1
• 1!=1.1=1
• 2!=2.1=2
Backtracking
• 3!=3.2=6
• 4!=4.6=24
• Factorial function without using recursion
int factorial( int n )
{ if(n==0)
return 1;
else{
int i, fact =1;
for( i=2; i<=n; i++ )
fact * =I;
return fact; }
}
• Factorial function with using recursion
int factorial( int n )
{ if(n==0)
return 1;
else
return ( n * factorial ( n-1 ) );
}
2. Positive Exponential Power Function
• Its iterative version is
1 if n=0
xn = πn x if n>0
i=1
• where as its recursive version is
1 if n=0
x =
n x.x n-1 if n>0
float power ( float x, int n )
{ if ( n == 0 )
return 1;
else {
int i, prod = x;
for ( i =2; i<=n; i++)
prod * = x;
retrun prod; }
}
• float power( float x, int n )
{ if(n==0)
return 1;
else
return ( x * power ( x, n-1 ) );
}

3. Fibonacci Numbers
A very important sequence, Fibonacci sequence, usually denoted
by F0,F1,,,,,,,Fn, is as follows:
0,1,1,2,3,5,8,13,…..
A formal definition for Fibonacci number Fn is

n if n<=1
fib(n) =
fib(n-1) + fib(n-2) if n>1
Fib(5)

Fib(4) Fib(3)

Fib(3) Fib(2) Fib(2) Fib(1)


Fib(2) Fib(1) Fib(1) Fib(0) Fib(1) Fib(0)

Fib(1) Fib(0)

• int fib( int n )


• { if(n<=1)
• return n;
• else
• return ( fib(n-1) + fib(n-2) );
• }
4.Function for finding sum of elements in an array
int sum (int a[ ],int n)
{
if(n==1)
return (a[0]);
else
return (a[n-1] + sum(a,n-1));
}
5. Function for finding length of string
int length(char s[ ])
{
if(s[0]==‘\0’)
return (0);
return (1+ length(s+1));
}
6.Function for reversing a string

void reverse(char *s,int i,int j)


{
char temp;
if(i<j) /* I is the index of first char and j is the index of last char*/
{ temp=s[i];
s[i]=s[j];
s[j]=temp;

reverse(s,i+1,j-1);
}
}
Write a recursive function for the following
recursive definition:

1. Ackermann’s Function A(m,n)


(n+1) if m=0
A(m,n)= A(m-1,1) if n=0
A(m-1,A(m,n-1) otherwise

2.Binomial Cofficient nCm where


nC =nC =1 and
0 n
nC =n-1C + n-1C
m m m-1
• Direct Recursion:

A function is directly recursive if it contains an explicit call to itself. For


example, the function
int fun(int x)

  if (x <= 0)
return x;   
return fun(x - 1);
}
includes a call to itself, so it's directly recursive. The recursive call
will occur for positive values of x.
• Indirect Recursion:

A function fun is indirectly recursive if it contains a call to another


function which ultimately calls fun. The following pair of functions is
indirectly recursive. Since they call each other, they are also known
as mutually recursive functions.
int fun(int x)

  if (x <= 0) return x;
   return bar(x);
}
int bar(int y)
{
   return fun(y - 1);
}
Advantages and disadvantages of recursion

• The great advantage of recursion is that it makes functions very


simple and allows them to behave just like the thing they are
attempting to model.
• Unfortunately there are few situations in which recursion can be
employed in a practical way.
• The major disadvantage of recursion is amount of memory
required to make it work. don’t forget that the program stack
grows each time a function call is made. If a recursion function
buried itself a thousand levels deep, a program would almost
certainly run out of memory.
• There is also the slight danger that a recursion function will go
out of control if a program contains bugs.
Why recursion

• The problem is much more clearly solved using recursion:


there are many problems where the recursion solution is clearer,
cleaner, and much more understandable. As long as the efficiency
is not the primary concern, or if the efficiencies of the various
solution are comparable, then you should use the recursive
solution.

• Some problems are much easier to solve through recursion:


there are some problems which don’t have an easy iterative
solution. Here you should use recursion. The “ Towers of Hanoi”
problem is a problem where an iterative solution would be very
difficult.
Towers of Hanoi

• Problem: Given three posts (towers) and n disks of decreasing


size, move the disks from one post to another one at a time without
putting a larger disk on a smaller one.
• Only one disk can be moved at a time, and that too the top disk.
• No disk can be placed on top of smaller disk.

• Case 1: Given one disk only

A B C A B C
• Case 2: Given two disks

A B C A B C
(Start) (i)

A B C A B C
(ii) (finish)
• Case 3: Given three disks
• Move disk 1 from pin A to pin C
• Move disk 2 from pin A to pin B
• Move disk 1 from pin C to pin B
• Move disk 3 from pin A to pin C
• Move disk 1 from pin B to pin A
• Move disk 2 from pin B to pin C
• Finally move disk 1 from pin A to pin C
A B C A B C

A B C A B C

A B C A B C
Algorithm for towers of hanoi problem
Tower(N,BEG,END,AUX)
1. If N = 1,then:
(a) Write:BEG->END
(b) Return
[End of If structure]
2.[Move N-1 disks from peg BEG to peg AUX]
Call Tower(N-1,BEG,AUX,END)
3.Write:BEG->END
4. [Move N-1 disks from peg AUX to peg END]
Call Tower(N-1,AUX,END,BEG)
5. Return
Tail Recursion
• A recursive function is said to be tail recursive if there are no
pending operations to be performed on return from a recursive
call. Tail recursive functions are often said to "return the value of the
last recursive call as the value of the function." Tail recursion is very
desirable because the amount of information which must be stored
during the computation is independent of the number of recursive
calls. Some modern computing systems will actually compute tail-
recursive functions using an iterative process.
• The factorial function “fact” is usually written in a non-tail-recursive
manner:
int fact (int n) { /* n >= 0 */  
  if (n == 0) 
return 1;
   return n * fact(n - 1);
}
Notice that there is a "pending operation," namely multiplication, to
be performed on return from each recursive call. Whenever there is
a pending operation, the function is non-tail-recursive.
Information about each pending operation must be stored, so
the amount of information is dependent of the number of calls.
Converting Recursive Functions to be
Tail Recursive
• A non-tail recursive function can often be converted
to a tail-recursive function by means of an
"auxiliary" parameter. This parameter is used to
form the result.
• The idea is to attempt to incorporate the pending
operation into the auxiliary parameter in such a way that
the recursive call no longer has a pending operation. The
technique is usually used in conjunction with an
"auxiliary" function. This is simply to keep the syntax
clean and to hide the fact that auxiliary parameters
are needed.
• The factorial function can be written in a tail-recursive way: 
int fact_aux(int n, int result)
{
   if (n == 1) return result;
   return fact_aux(n - 1, n * result)
}
int fact(n)
{    
return fact_aux(n, 1);
}
The "auxiliary" function fact_aux is used to keep the syntax of fact(n)
the same as before. The recursive function is really fact_aux, not
fact. Note that fact_aux has no pending operations on return from
recursive calls. The value computed by the recursive call is simply
returned with no modification. The amount of information which must
be stored is constant (the value of n and the value of result),
independent of the number of recursive calls

You might also like