Professional Documents
Culture Documents
Review
1.1 CONCEPT OF ALGORITHM
very difficult to make people realize that it is not really the computer but the man behind computer
A common man’s belief is that a computer can do anything and everything that he imagines. It is who does
everything.
In the modern internet world, man feels that just by entering what he wants to search into the computers
he can get information as desired by him. He believes that, this is done by computer. A common man
seldom understands that a man made procedure called search has done the entire job and the only support
provided by the computer is the execution speed and organized storage of information.
In the above instance, a designer of the information system should know what one frequently searches
for. He should make a structured organization of all those details to store in memory of the computer.
Based on the requirement, the right information is brought out. This is accomplished through a set of
instructions created by the designer of the information system to search the right information matching the
requirement of the user. This set of instructions is termed as program. It should be evident by now that it
is not the computer, which generates automatically the program but it is the designer of the information
system who has created this.
Thus, the program is the one, which through the medium of the computer executes to perform all the
activities as desired by a user. This implies that programming a computer is more important than the
computer itself while solving a problem using a computer and this part of programming has got to be done
by the man behind the computer. Even at this stage, one should not quickly jump to a conclusion that
coding is programming. Coding is perhaps the last stage in the process of programming. Programming
involves various activities form the stage of conceiving the problem up to the stage of creating a model to
solve the problem. The formal representation of this model as a sequence of instructions is called an
algorithm and coded algorithm in a specific computer language is called a program.
One can now experience that the focus is shifted from computer to computer programming and then
to creating an algorithm. This is algorithm design, heart of problem solving.
In other words, viewed little more formally, an algorithm is a step by step formalization of a mapping
function to map input set onto an output set.
The problem of writing down the correct algorithm for the above problem of brushing the teeth is left
to the reader.
The pseudo code used resembles PASCAL and C language control structures. Hence, it is expected that
the reader be aware of PASCAL/C. Even otherwise at least now it is required that the reader should
know preferably C to practically test the algorithm in this course work.
However, for the sake of completion we present the commonly employed control constructs present in
the algorithms.
1. A conditional statement has the following form
If < condition> then
Block 1
Else
Block 2
If end.
This pseudo code executes block1 if the condition is true otherwise block2 is executed.
2. The two types of loop structures are counter based and conditional based and they are as follows
For variable = value1 to value2 do
Block
For end
Here the block is executed for all the values of the variable from value 1 to value 2.
There are two types of conditional looping, while type and repeat type.
While (condition) do
Block
While end.
Here block gets executed as long as the condition is true.
Repeat
Block
Until<condition>
Here block is executed as long as condition is false. It may be observed that the block is executed at
least once in repeat type.
SUMMARY
In this chapter, the concepts of algorithm are presented and the properties of the algorithm are also
given. The concept of designing algorithm is explained with a specific example. The concepts of validating
the algorithms and test the devised algorithms is also presented.
EXERCISE
1. __________ is the process of executing a correct program on data sets and measuring the time and space it
takes to compute the results.
2. Define algorithm? What are its properties
3. What is debugging and What is profiling?
4. One of the properties of an algorithm is beauty (true / false)
Chapter 2
Elementary Data Structures
2.1 FUNDAMENTALS
enhancing the qualities of associated algorithms. In this chapter, we review only the non-primitive
Data structure is a method of organizing data with a sort of relationship with an intension of data structures. The
non-primitive data structures can be broadly classified into two types linear
and non-linear data structures. Under linear data structures Arrays, Stacks and Queues and under non-
linear data structures graphs and trees are reviewed.
2.2 LINEAR DATA STRUTURES
A data structure in which every data element has got exactly two neighbors or two adjacent elements
except two elements having exactly one data element is called a linear data structure. Otherwise it is
called a nonlinear data structure.
2.2.1 Array and its representation
Array is a finite ordered list of data elements of same type. In order to create an array it is required to
reserve adequate number of memory locations. The allocated memory should be contiguous in nature.
The size of the array is finite and fixed up as a constant. Some of the important operations related to
arrays are,
Creation () g A[n], Array created (reservation of adequate number of memory locations) memory
reserved;
Write (A, i, e) g Updated array with ‘e’ at it h position;
Compare (i, j, Relationl operator) g Boolean;
In general, if w is the size of the data element, then ith element is at (B + (i – l) w)th location. i.e., A[i]
= B + (i – l) w.
REPRESENTATION OF A TWO DIMENSIONAL ARRAY
The two dimensional array A[l1..u1] [l2..u2] may be interpreted as n = u1-l1+1 rows and m = u2 -l2+1
columns i.e., each row consists of u2-l2+1 elements.
1,1 1,2 1,3 …. 1,m 2,1 2,2 2,3 … 2,m …. ….. n,1 n,2 …. n,m
Given the indices (i, j), the address can be computed using A[i, j] = B + (i-1) m+ (j-1).
In general, if li £ i £ui and lj £ j £uj , then A[i, j] = B + { (i - li ) (uj – lj +1) +(j - lj )}w.
For higher n-dimensional arrays, the address can be computed as
A( i1, i2, i3, ….in ) where l1 £ i1 £u1, l2 £ i2 £u2 , … ln £ in £un
A( i1, i2, i3 , ….in ) = B + { (i1 - l1 ) (u2 - l2 +1)(u3-l3+1) ….(un - ln+1) + (i2 - l2) (u3 - l3 +1)(u4-l4+1) ….
(un- ln +1) + (i3 - l3 ) (u4 - l4 +1) (u5-l5 +1) ….(un- ln +1)
+ ……+
(in -1 - ln -1) (un - ln +1) + (in - ln) }w
The algorithm thus designed to compute the row major address is as follows
Algorithm: Address Computation (Row Major)
Input: (1) n, dimension
(2) l1 , l2, l3 , … ln n lower limits
+= wPliBA )(
jjj
j1
=
+ - = l u P where ) 1 (
kkj
+=jk 1
Algorithm ends.
2.2.2 Stacks
A stack is an ordered list in which all insertions and deletions are made at one end, called the top. Stack
is a linear data structure which works based on the strategy last-in-first out (LIFO). It is a linear data
structure which is open for operations at only one end (both insertions and deletions are defined at only
one end). One natural example of stack, which arises in computer programming, is the processing of
procedure calls and their terminations. Stacks are generally used to remember things in reverse. It finds
a major use in backtracking approaches.
Some of the functions related to a stack are
Create ( ) g S;
Insertion(S, e) g updated S;
Deletion (S) g S, e;
Isfull(S) g Boolean;
Isempty(S) g Boolean;
Top(S) g e;
Destroy(S)
It has to be noted that with respect to a stack, insertion and deletion operations are, in general, called
PUSH and POP operations respectively. Following are the algorithms for some functions of stack.
Algorithm: Create
Output: S, Stack created
Method:
Declare S[SIZE] //Array of size=SIZE
Declare and Initialize T=0 //Top pointer to remember the number of elements
Algorithm ends
Algorithm: Isempty
Input: S, stack
Output: Boolean
Method:
If (T==0)
Return (yes)
Else
Return (no)
If end
Algorithm ends
Algorithm: Isfull
Input: S, stack
Output: Boolean
Method:
If (T==SIZE)
Return (yes)
Else
Return (no)
If end
Algorithm ends
Algorithm: Push
Input: (1) S, stack; (2) e, element to be inserted; (3) SIZE, size of the stack;
(4) T, the top pointer
Output: (1) S, updated; (2) T, updated
Method:
If (Isfull(S)) then
Print (‘stack overflow’)
Else
T=T+1;
S[T] =e
If end
Algorithm ends
Algorithm: Pop
Input: (1) S, stack;
Output: (1) S, updated; (2) T, updated (3) ‘e’ element popped
Method:
If (Isempty(S)) then
Print (‘stack is empty’)
Else
e = S[T]
T=T-1;
If end
Algorithm ends
2.2.3 Queues
A queue is an ordered list in which all insertions take place at one end called the rear end, while all
deletions take place at the other end called the front end. Queue is a linear data structure which works
based on the strategy first-in-first out (FIFO). Unlike stacks, queues also arise quite naturally in the
computer solution of many problems. Perhaps the most common occurrence of a queue in computer
applications is for scheduling of jobs. A minimal set of useful operations on queue includes the following.
Create ( ) g Q;
Insertion (Q, e) g updated Q;
Deletion (Q) g Q, e;
Isfull (Q) g Boolean;
Isempty (Q) g Boolean;
Front (Q) g e;
Back (Q);
Destroy (Q);
Following are the algorithms for some functions of queue.
Algorithm: Create
Output: Q, Queue created
Method:
Declare Q[SIZE] //Array with size=SIZE
Declare and Initialize F=0, R=0
//Front and Rear pointers to keep track of the front element and the rear element respectively
Algorithm ends
Algorithm: Isempty
Input: Q, Queue
Output: Boolean
Method:
If (F==0)
Return (yes)
Else
Return (no)
If end
Algorithm ends
Algorithm: Isfull
Input: Q, Queue
Output: Boolean
Method:
If (R==SIZE)
Return (yes)
Else
Return (no)
If end
Algorithm ends
Algorithm: Front
Input: Q, Queue
Output: element in the front
Method:
If (Isempty (Q))
Print ‘no front element’
Else
Return (Q[F])
If end
Algorithm ends
Algorithm: Rear
Input: Q, Queue
Output: element in the rear
Method:
If (Isempty (Q))
Print ‘no back element’
Else
Return (Q[R])
If end
Algorithm ends
Algorithm: Insertion
Input: (1) Q, Queue; (2) e, element to be inserted; (3) SIZE, size of the Queue;
(4) F, the front pointer; (5) R, the rear pointer
Output: (1) Q, updated; (2) F, updated; (3) R, updated
Method:
If (Isfull (Q)) then
Print (‘overflow’)
Else
R=R+1;
Q[R]=e
If (F==0)
F=1;
If end
If end
Algorithm ends
Algorithm: Deletion
Input: (1) Q, Queue; (2) SIZE, size of the Queue; (3) F, the front pointer; (4) R, the rear pointer
Output: (1) Q, updated; (2) F, updated; (3) R, updated; (4) e, element if deleted;
Method:
If (Isempty (Q)) then
Print (‘Queue is empty’)
Else
e = Q[F]
If (F==R)
F=R=0;
Else
F=F+1;
If end
If end
Algorithm ends
However, the linear queue makes less utilization of memory i.e., the ‘return (isfull (Q)) =yes’ does not
necessarily imply that there are n elements in the queue. This can be overcome by the using an alternate
queue called the circular queue.
Method:
If (Isempty (CQ)) then
Print (‘Queue is empty’)
Else
e = CQ[F]
If (F==R)
F=R=0;
Else
F=F mod SIZE +1;
If end
If end
Algorithm ends
l The number of elements adjacent to a given element is called ‘arity’ or the degree of the
element. i.e., degree = number of relations the element has with others.
Fig. 2.1
edge ek are called the end vertices of ek. The most common representation of graph is by means of a
diagram, in which the vertices are represented as points and each edge as a line segment joining its end
vertices.
In the Fig. 2.1 edge e1 having same vertex as both its end vertices is called a self-loop. There may be
more than one edge associated with a given pair of vertices, for example e4 and e5 in Fig. 2.1. Such
edges are referred to as parallel edges.
A graph that has neither self-loop nor parallel edges are called a simple graph, otherwise it is called
general graph. It should also be noted that, in drawing a graph, it is immaterial whether the lines are
drawn straight or curved, long or short: what is important is the incidence between the edges and vertices.
Because of its inherent simplicity, graph theory has a very wide range of applications in engineering,
physical, social, and biological sciences, linguistics, and in numerous other areas. A graph can be used to
represent almost any physical situation involving discrete objects and a relationship among them.
2.3.1.1 Finite and Infinite Graphs
Although in the definition of a graph neither the vertex set V nor the edge set E need be finite, in most
of the theory and almost all applications these sets are finite. A graph with a finite number of vertices as
well as a finite number of edges is called a finite graph; otherwise, it is an infinite graph.
2.3.1.2 Incidence and Degree
When a vertex vi is an end vertex of some edge ej , vi and ej are said to be incident with (on or to) each
other. In Fig. 2.1, for example, edges e2, e6 , and e7 are incident with vertex v4 . Two nonparallel edges are
said to be adjacent if they are incident on a common vertex. For example, e2 and e7 in Fig. 2.1 are
adjacent. Similarly, two vertices are said to be adjacent if they are the end vertices of the same edge. In
Fig. 3.1, v4 and v5 are adjacent, but v1 and v4 are not.
The number of edges incident on a vertex vi , with self-loops counted twice is called the degree, d(vi ),
of vertex vi . In Fig. 2-1, for example, d(v1) = d(v3 ) = d(v4) = 3, d(v2) = 4, and d(v5 ) = 1. Since each edge
contributes two degrees, the sum of the degrees of all vertices in G is twice the number of edges in G.
Fig. 2.2 Graph containing isolated vertices, series edges and a pendant vertex.
G. The entries in the matrix are either zero or one. i.e., = otherwise
i
Xj
0
Thus the matrix where each column and row corresponds to the vertex in the
graph G shown in Fig.
2.4 is
V1 V2 V3 V4 V5 V6
V1 0 1 0 0 1 0
V2 1 0 1 1 1 0
V3 0 1 0 0 0 0
V4 0 1 0 0 1 1 (2)
V5 1 1 0 1 0 0
V6 0 0 0 1 (2) 0 0
This matrix X uniquely represents the graph. It is indeed possible to reconstruct the graph back from
the matrix. The high entry in the matrix says the vertex corresponding to the row and vertex corresponding
to the column is adjacent. Since, two vertices are adjacent if there is an edge connecting them, and the
matrix represents the same, the above matrix X is called an adjacency matrix.
Adjacency matrix is a symmetric matrix. If the diagonal elements are high then the graph has a self
loop, the respective row index gives the vertex label with self loop. The sum of the it h row elements gives
the degree of the vertex Vi . While calculating the row sum of the adjacency matrix of a non-simple graph,
a weightage 1 has to be given if the diagonal cell is high and additional weightage to every parallel edge.
2.3.2.2 Incidence Matrix
Let G be a graph with n vertices, e edges, and no self-loops. Define an n by e matrix A =[a ij ], whose
n rows correspond to the n vertices and the e columns correspond to the e edges, as follows:
The matrix element
abcdef gh
v1 0 0 0 1 0 1 0 0
v2 0 0 0 0 1 1 1 1
v3 0 0 0 0 0 0 0 1
v4 1 1 1 0 1 0 0 0
v5 0 0 1 1 0 0 1 0
v6 1 1 0 0 0 0 0 0
(b)
4. Parallel edges in a graph produce identical columns in its incidence matrix, for example, columns
1 and 2 in Fig. 2.5.
2.3.3 Trees
The concept of a tree is probably the most important in graph theory, especially for those interested in
applications of graphs.
A tree is a connected graph without any circuits. The graph in Fig 2.6 for instance, is a tree. It follows
immediately from the definition that a tree has to be a simple graph, that is, having neither a self-loop nor
parallel edges (because they both form circuits).
SUMMARY
This chapter devotes itself to present an overview of very fundamental data structures essential for
the design of algorithms. One of the basic technique for improving algorithms is to structure the data in
such a way that the resulting operations can be carried out efficiently. Though the chapter does not
present all the data structure, we have selected several which occur more frequently in this book. This
chapter also presents some terminologies used in the graph. The notions such as arrays, stack, queue,
graphs and trees have been exposed.
EXERCISE
1. Give at least 5 real life examples where we use stack operations
2. Give at least 5 real life applications where queue is used.
3. Name 10 situations that can be represented by means of graphs. Explain what each vertex and edge represent
4. Draw a connected graph that becomes disconnected when any edge is removed from it
5. Draw all trees of n labeled vertices for n=1,2,3,4 and 5
6. Sketch all binary trees with six pendent edges
7. Write adjacency and incidence matrix for all the graphs developed
Chapter 3
Some Simple Algorithms
on the proper understanding of the logic constructs rather than the programming constructs specific
Algorithm is a blueprint, the program follows to achieve the end result. The end result thus depends to the programming
language. In this chapter we present some simple problems and discuss the
issues in solving the problem and finally design the algorithms for the same.
a b c
The ‘a’ ,‘b’ ,‘c’ are the memory locations from now on called the variables. When we generalize this,
it appears as
c= a + b
To make it even more simple, we have two inputs and one output. To store one output and two inputs
we need three variables or memory locations. The Algorithm to add two numbers is now given below.
24
Chapter 3 - Some Simple Algorithms
25
BSIT 41 Algorithms
Algorithm : Add_two_numbers
Input : a, b, two numbers to be added
Output : c updated
Method
c= a + b
Display c
Algorithm ends
b = small
k1 = a
k2 = c
end_if
if (small> c)
c = small
k1 = a
k2 = b
end_if
Display small
If (k1 > k2 )
Display k2
Display k1
Else
Display k1
Display k2
end_if
Algorithm ends
Display ‘III-Quadrant’
end_if
end_if
Algorithm ends
ac b b 4 + -
R2=
12-
a
ac b b 4 - -
R2=
22-
a
And these are two roots of the equation.
The term (b2-4ac) in the solution to the root is called the discriminant of the root. Basically the roots
can be real or imaginary in nature. If the roots are real in nature then they can be either real and distinct,
or both of them can be equal. If they are imaginary the roots exists in complex conjugates.
The problem of identifying the nature of the roots is achieved in checking the nature of the discriminant.
The nature of the discriminant reflects the nature of the solution of the quadratic equation.
If the discriminant is negative then the roots will be of imaginary in nature.
i.e if (b2-4ac) = some –ve value.
And these are two roots of the equation.
The term (b2-4ac) in the solution to the root is called the discriminant of the root. Basically the roots
can be real or imaginary in nature. If the roots are real in nature then they can be either real and distinct,
or both of them can be equal. If they are imaginary the roots exists in complex conjugates.
The problem of identifying the nature of the roots is achieved in checking the nature of the discriminant.
The nature of the discriminant reflects the nature of the solution of the quadratic equation.
If the discriminant is negative then the roots will be of imaginary in nature.
i.e if (b2-4ac) = some –ve value.
2-
ac b 4
Then, is complex in nature, because square root of any negative number always results in
an imaginary result.
29
BSIT 41 Algorithms
Now the roots R1 and R2 has imaginary parts and hence they are imaginary in nature.
Now the other possibility is that the roots being real. For that to happen the disciminant (b2-4ac) = 0.
If it is equal to zero than the discriminant vanishes and hence the roots are real and equal,which are R1
= R2 = -b/2a.
In case (b2-4ac) > 0 , then the roots are real and distinct. The algorithm to find the solution to a
quadratic equation is given below.
Algorithm: Quadratic_solver
Input : a,b,c the co-efficients of the Quadratic Equation
Output : The two roots of the Equation
Method
disc = ((b*b) –(4*a*c))
if (disc = 0)
display ‘roots are real and equal’
r1 = -b/2a
r2 = -b/2a
display r1
display r2
else
if(disc>0)
display ‘ roots are real and distinct’
r1 = (-b+sqrt(disc))/2a
r2 = (-b-sqrt(disc))/2a
else
display ‘roots are complex’
if(flag = 0)
31
BSIT 41 Algorithms
if(flag = 0)
display ‘Number is prime’
else
display ‘Number is not prime’
end_if
Algorithm ends
32
Chapter 3 - Some Simple Algorithms
Method
fact = 1
for i = 1 to n in steps of 1 do
fact = fact*i
end_for
display ‘factorial = ‘,fact
Algorithm ends
The above example is of matrix addition. Matrix addition is possible iff orders of the two matrices are
same. Respective matrix elements are added together in a third matrix and the results are thus obtained.
The procedure is thus described below.
The two Matrices has to read initially in a two dimensional array and then the respective row element
and column elements in the Matrices have to be added to get a third matrix, which leads to the realization
of Matrix addition.
Algorithm : Matrix Addition
Input : n , order of the matrices
a(n,n),b(n,n) the two input matrices
Output : c(n,n) the resultant Sum matrix
Method
{
Accept ‘n’
for(i = 1 to n in steps + 1 do)
for(j= 1 to n in steps of + 1do)
accept a(i,j)
end_for
end_for
4.1 SEARCHING
‘k’, then, we have to search the entire file from the beginning till the end to check whether the
Let us assume that we have a sequential file and we wish to retrieve an element matching with key
element matching k is present in the file or not.
There are a number of complex searching algorithms to serve the purpose of searching. The linear
search and binary search methods are relatively straight forward methods of searching.
4.1.1 Sequential search
In this method, we start to search from the beginning of the list and examine each element till the end
of the list. If the desired element is found we stop the search and return the index of that element. If the
item is not found and the list is exhausted the search returns a zero value.
In the worst case the item is not found or the search item is the last (nt h ) element. For both situations
we must examine all n elements of the array.
The algorithm for sequential search is as follows,
Algorithm : sequential search
Input : A, vector of n elements
K, search element
Output : j –index of k
37
BSIT 41 Algorithms
38
Chapter 4 - Searching and Sorting
Method : i=1
While(i<=n)
{
if(A[i]=k)
{
write(“search successful”)
write(k is at location i)
exit();
}
else
i++
if end
while end
write (search unsuccessful);
algorithm ends.
4.1.2 Binary Search
Binary search method is also relatively simple method. For this method it is necessary to have the
vector in an alphabetical or numerically increasing order. A search for a particular item with X resembles
the search for a word in the dictionary. The approximate mid entry is located and its key value is examined.
If the mid value is greater than X, then the list is chopped off at the (mid-1)t h location. Now the list gets
reduced to half the original list. The middle entry of the left-reduced list is examined in a similar manner.
This procedure is repeated until the item is found or the list has no more elements. On the other hand, if
the mid value is lesser than X, then the list is chopped off at (mid+1) t h location. The middle entry of the
right-reduced list is examined and the procedure is continued until desired key is found or the search
interval is exhausted.
The algorithm for binary search is as follows,
Algorithm : binary search
Input : A, vector of n elements
K, search element
39
BSIT 41 Algorithms
4.2 SORTING
One of the major applications in computer science is the sorting of information in a table. Sorting
algorithms arrange items in a set according to a predefined ordering relation. The most common types of
data are string information and numerical information. The ordering relation for numeric data simply
40
Chapter 4 - Searching and Sorting
involves arranging items in sequence from smallest to largest and from largest to smallest, which is called
ascending and descending order respectively.
The items in a set arranged in non-decreasing order are {7,11,13,16,16,19,23}. The items in a set
arranged in descending order is of the form {23,19,16,16,13,11,7}
Similarly for string information, {a, abacus, above, be, become, beyond}is in ascending order and {
beyond, become, be, above, abacus, a}is in descending order.
There are numerous methods available for sorting information. But, not even one of them is best for all
applications. Performance of the methods depends on parameters like, size of the data set, degree of
relative order already present in the data etc.
4.2.1 Insertion Sorting
The first class of sorting algorithm that we consider comprises algorithms that sort by insertion. An
algorithm that sorts by insertion takes the initial, unsorted sequence,
} ... s s s s S S S ' : ... : '
{ 3 S = , and computes a series of sorted sequences n ' 1
0 , as follows:
:2:1n:
In the ith step, the element at position i in the array is inserted into the sorted sequence
S ' which occupies array positions 0 to (i-1). After this is done, array positions 0 to i
i
S . Array positions (i+1) to (n-1) contain the remaining n-i-
contain the i+1 elements of 1
'+
i
1 elements of the unsorted sequence S.
41
BSIT 41 Algorithms
As shown in Fig. 4.1, the first step (i=0) is trivial—inserting an element into the empty list involves no
work. Altogether, n-1 non-trivial insertions are required to sort a list of n elements.
Method
for j= 2 to n in steps of 1 do
item = a[j]
i = j-1
while((i>=1) and (item<a[i])) do
a[i+1] = a[i]
i = i-1
while end
a[i+1] = item
for end
Algorithm ends
4.2.2 Selection Sorting
Such algorithms construct the sorted sequence one element at a time by adding elements to the sorted
sequence in order. At each step, the next element to be added to the sorted sequence is selected from the
remaining elements.
Because the elements are added to the sorted sequence in order, they are always added at one end.
This is what makes selection sorting different from insertion sorting. In insertion sorting elements are
added to the sorted sequence in an arbitrary order. Therefore, the position in the sorted sequence at which
each subsequent element is inserted is arbitrary.
Both selection sorts described in this section sort the arrays in place. Consequently, the sorts are
implemented by exchanging array elements. Nevertheless, selection differs from exchange sorting because
at each step we select the next element of the sorted sequence from the remaining elements and then we
move it into its final position in the array by exchanging it with whatever happens to be occupying that
position.
Straight Selection Sorting
The simplest of the selection sorts is called straight selection . Fig.4.2 illustrates how straight selection
works. In the version shown, the sorted list is constructed from the right (i.e., from the largest to the
smallest element values).
43
BSIT 41 Algorithms
At each step of the algorithm, a linear search of the unsorted elements is made in order to determine
the position of the largest remaining element. That element is then moved into the correct position of the
array by swapping it with the element which currently occupies that position.
supported by most of the languages. At the same time, it is also a fact that most beginners are
We look at the concept of recursion, which is one of the very powerful programming concepts, confused by the
way it works and are unable to use it effectively. Also, some languages may
not support recursion. In such cases, it may become necessary to rewrite recursive functions into non-
recursive ones. All these and many other aspects are dealt with in this chapter.
Recursion is an offshoot of the concept of subprograms. A subprogram as we know is the concept of
writing separate modules, which can be called from other points in the program or other programs. Then
came a concept wherein any subprogram can call any other subprogram. The control goes to the called
subprogram, performs the assigned tasks and comes back to the caller programs.
Then comes the question – can a program call itself? Theoretically it is possible. If so, where do we
use them normally? A subprogram is called to perform a function, which the caller subprogram cannot
perform itself. But if the caller program calls itself, what purpose does it serve? The answer is, the
subprogram no doubt, calls itself, but with a different value of the parameter. In fact, in most cases, the
calling continues until some specific value of the parameter is reached.
We now understand that recursion is a process of defining a process/ problem/ an object in terms of
itself. Recursion is one of the applications of stacks. The recursive mechanisms are extremely powerful,
but even more importantly; many times they can express an otherwise complex process, very clearly.
Any program can be written using recursion. Of course, the recursive program in that case could be
tougher to understand. Hence, recursion can be used when the problem itself can be defined recursively.
The general procedure for any recursive algorithm is as follows,
1. Save the parameters, local variables and return addresses.
45
BSIT 41 Algorithms
46
Chapter 5 - Recursion
2. If the termination criterion is reached perform final computation and go to step 3, otherwise
perform final computations and go to step 1.
3. Restore the most recently saved parameters, local variables and return address and go to the
latest return address.
Suppose we are asked to evaluate N!. If we somehow know (N-1)! then we can evaluate N! = N*(N-
1)!. But how do we get (N-1)!? The same logic can be employed to evaluate (N-1)! = (N-1) * (N-2)!.
The problem of finding the factorial of a given number can be recursively defined as
- * 1 ) 1 ( n if n
Factorial n
= 1 1 n if
else
if (n == 0) // Our terminating condition
return 1;
else
return (n + SumPosInt( n -1 ); // recursive step
if end
if end
Algorithm ends
if (a[mid]< K)
Binary search(A, K, Low, mid)
else
Binary Search(A, K, High, mid)
if end
if end
else
return(0)
if end
Algorithm ends.
max = a(p)
min = a(q)
Else
max = a(q)
min = a(p)
If End
Else
m ¬ (p+q)/2
max-min(p,m,max1,min1)
max-min(m+1,q,max2,min2)
max f large(max1,max2)
min f small(min1,min2)
If End
If End
Algorithm Ends.
Similarly compare A(2) with B(2), since A(2) is smaller, it will be the third element and so on. Finally,
C is built up as C[ ]= {2, 3, 5, 6, 8, 9, 14, 15, 18, 27, 30, 32}.
However the main problem remains. In the above example, we presume that both A & B are originally
sorted. Then only they can be merged. But, how do we sort them in the first? To do this and show the
consequent merging process, we look at the following example. Consider the series A= (7 5 15 6 4). Now
divide A into 2 parts (7, 5, 15) and (6, 4). Divide (7, 5, 15) again as ((7, 5) and (15)) and (6, 4) as ((6) (4)).
Again (7, 5) is divided and hence ((7, 5) and (15)) becomes (((7) and (5)) and (15)).
Now since every element has only one number, we cannot divide again. Now, we start merging them,
taking two lists at a time. When we merge 7 and 5 as per the example above, we get (5, 7) merge this with
15 to get (5, 7, 15). Merge this with 6 to get (5, 6, 7, 15). Merging this with 4, we finally get (4, 5, 6, 7 and
15). This is the sorted list.
You are now expected to take different sets of examples and see that the method always works.
We design two algorithms in the following. The main algorithm is a recursive algorithm (some what
similar to the binary search algorithm that we saw earlier) which calls at times the other algorithm called
MERGE. The algorithm MERGE does the merging operation as discussed earlier.
Algorithm: MERGESORT
Input: low, high, the lower and upper limits of the list to be sorted
A, the list of elements
Output: A, Sorted list
Method:
If (low<high)
mid¬ (low + high)/2
MERGESORT(low, mid)
MERGESORT (mid, high)
MERGE(A, low, mid, high)
If end
Algorithm ends
You may recall that this algorithm runs on lines parallel to the binary search algorithm. Each time it
divides the list (low, high) into two lists(low, mid) and (mid+1, high). But later, calls for merging the two
lists.
53
BSIT 41 Algorithms
Algorithm: Merge
Input: low, mid, high, limits of two lists to be merged i.e., A(low, mid) and A(mid+1, high)
A, the list of elements
Output: B, the merged and sorted list
Method:
h = low, i = low, j = mid + 1;
While ((h dŠ mid) and (j dŠ high)) do
If (A(h) dŠ A(j) )
B(i) = a(h);
h = h+1;
else
B(i) = A(j);
j = j+1;
If end
i = i+1;
If (h > mid)
For k = j to high
B(i) = A(k);
i = i+1;
For end
Else
For k = h to mid
B(i) = A(k);
i = i+1
For end
If end
While end
Algorithm ends
54
Chapter 5 - Recursion
The first portion of the algorithm works exactly similar to the explanation given earlier, except that
instead of using two lists A and B to fill another array C, we use the elements of the same array A[low,mid]
and A[mid+1,high] to write into another array B.
Now it is not necessary that both the lists from which we keep picking elements to write into B should
get exhausted simultaneously. If the fist list gets exhausted earlier, then the elements of the second list are
directly written into B, without any comparisons being needed and vice versa. This aspect will be taken
care of by the second half of the algorithm.
5.10 QUICKSORT
This is another method of sorting that uses a different methodology to arrive at the same sorted result.
It “Partitions” the list into 2 parts (similar to merge sort), but not necessarily at the centre, but at an
arbitrarily “pivot” place and ensures that all elements to the left of the pivot element are lesser than the
element itself and all those to the right of it are greater than the element. Consider the following example.
75 80 85 90 95 70 65 60 55
To facilitate ordering, we add a very large element, say 1000 at the end. We keep in mind that this is
what we have added and is not a part of the list.
75 80 85 90 95 70 65 60 55 1000
A(1) A(2) A(3) A(4) A(5) A(6) A(7) A(8) A(9) A(10)
Now consider the first element. We want to move this element 75 to its correct position in the list. At
the end of the operation, all elements to the left of 75 should be less than 75 and those to the right should
be greater than 75. This we do as follows:
Start from A(2) and keep moving forward until an element which is greater than 75 is obtained.
Simultaneously start from A(10) and keep moving backward until an element smaller than 75 is obtained.
A(1) A(2) A(3) A(4) A(5) A(6) A(7) A(8) A(9) A(10)
75 80 85 90 95 70 65 60 55 1000
Now A(2) is larger than A(1) and A(9) is less than A(1). So interchange them and continue the
process.
75 55 85 90 95 70 65 60 80 1000
Again A(3) is larger than A(1) and A(8) is less than A(1), so interchange them.
75 55 60 90 95 70 65 85 80 1000
Similarly A(4) is larger than A(1) and A(7) is less than A(1), interchange them
55
BSIT 41 Algorithms
75 55 60 65 95 70 90 85 80 1000
In the next stage A(5) is larger than A(1) and A(6) is lesser than A(1), after interchanging we have
75 55 60 65 70 95 90 85 80 1000
In the next stage A(6) is larger than A(1) and A(5) is lesser than A(1), we can see that the pointers
have crossed each other, hence Interchange A(1) and A(5).
70 55 60 65 75 95 90 85 80 1000
We have completed one series of operations. Note that 75 is at its proper place. All elements to its left
are lesser and to it’s right are greater.
Next we repeat the same sequence of operations from A(1) to A(4) and also between A(6) to A(10).
This we keep repeating till single element lists are arrived at.
Now we suggest a detailed algorithm to do the same. As before, two algorithms are written. The
main algorithm, called QuickSort repeatedly calls itself with lesser and lesser number of elements. However,
the sequence of operations explained above is done by another algorithm called PARTITION
Algorithm: QuickSort
Input: p, q, the lower and upper limits of the list of elements A to be sorted
Output: A, the sorted list
Method:
If (p < q)
j = q+1;
PARTITION (p, j)
QuickSort(P, j-1)
Quicksort(j+1, q)
If end
Algorithm ends
Algorithm: PARTITION
Input: m, the position of the element whose actual position in the sorted list has to be found
p, the upper limit of the list
Output: the position of mt h element
56
Chapter 5 - Recursion
Method:
v = A(m);
i = m;
Repeat
Repeat
i = i+1
Until (A(i) e> v);
Repeat
p=p-1
Until (A(p) d” v);
If (i < p)
INTERCHANGE(A(i), A(p))
If end
Until (i e” p)
A(m) = A(p) ;
A(p) = v;
Algorithm ends
with n vertices to be minimally connected there have to be n-1 edges. A tree is, therefore, a
As already seen in Chapter 2, a tree is a minimally connected graph without a circuit. For a graph connected graph with
n vertices and (n-1) edges. It can also be said to be a graph with n vertices
and (n-1) edges without a circuit.
Sometimes a specific node is given importance. Then, it is called a “rooted” tree. This tree is a
collection of vertices and edges in which a vertex has been identified as the root and the remaining
vertices are categorized into many classes (k >= 0), where each class is a rooted tree. Such a rooted tree
class is called the sub-tree of the given tree.
(b)
(a) (c)
Fig. 6.1 (a) A complete binary tree (b) A full binary tree (c)A binary tree showing levels
binary tree
58
Chapter 6 - Representation and Traversal of a Binary Tree
59
BSIT 41 Algorithms
In the above definition if k is restricted to be maximum of 2 then the rooted tree is called “binary
tree”. If k = 0, it implies that there are no children. A node without any children is called a “leaf” node.
The number of levels in the tree is called the “depth” of the tree. A “complete” binary tree is one
which allows sequencing of the nodes and all the previous levels are maximally accommodated before the
next level is accommodated. i.e., the siblings are first accommodated before the children of any one of
them. And a binary tree which is maximally accommodated with all leaves at the same level is called
“full” binary tree. A full binary tree is always complete but complete binary tree need not be full. Fig. 6.1
(a) and (b) shows the examples for complete and full binary trees.
The maximum number of vertices at each level in a binary tree can be found out as follows:
k
i.e., 1 2 -
l
21=+
10==k
matrix. Here the row indices correspond to the parent nodes and the column corresponds to the child
nodes. i.e., A row corresponding to the vertex vi having the entries ‘L’ and ‘R’ indicate that vi has as its
left child the index corresponding to the column with the entry ‘L’ and the index corresponding to the
column with ‘R’ entry as its right child. The column with no entries corresponds to the root node. All other
columns have only one element. Each row may have 0, 1 or 2 entries. Zero entry in the column indicates
that the node is the root. Zero entry in the row means that, that element is a leaf node, only one entry
means that the node has only one child and two entries denote that the node has both the children. “L” is
used to represent left child and “R” is used to represent right child entries.
11-n
% 100 = n
2×
nn
The space utilization decreases as n increases. For large ‘n’, the percentage of utilization becomes
negligible. This is, therefore, not the most efficient method of representing a binary tree.
6.2.2 Single Dimensional Array Representation
Since the two dimensional array is a sparse matrix, we can consider the prospect of mapping it onto a
single dimensional array for better space utilization. In this representation, we have to note the following
points:
l The left child of the ith node is placed at the 2it h position.
4 5 6 7 8 9 10 11 1 2 13 14 15 1 6 17 18 19 2 0 21 22 23 2 4 25 26 27 2 8 2 9 30 31
DEF GH I JK
If l is the depth of the binary tree then, the number of possible nodes in the binary tree is 2l + 1-1. Hence
it is necessary to have 2l +1 -1 locations allocated to represent the binary tree.
If ‘n’ is the number of nodes, then the percentage of utilization is
1-n
100
1×+l
2-
l
For a complete and full binary tree, there is 100% utilization and there is a maximum wastage if the
binary tree is right skewed or left skewed, where only l+1 spaces are utilized out of the 2l+ 1 – 1 spaces
possible.
1+l
i.e., is the worst possible utilization in the single dimensional array representation.
100
1×
12-
+l
An important observation to be made here is that the organization of the data in the binary tree decides
the space utilization of the representation used.
The other alternative way of representing the binary tree is based on Linked Allocation (dynamic
allocation method).
62
Chapter 6 - Representation and Traversal of a Binary Tree
There are three major methods of traversals and the rest are reversals of them. They are:
1. Pre-order traversal
2. In-order traversal
3. Post-order traversal
Pre-Order Traversal
In this traversal, the nodes are visited in the order of root, left child and then right child. i.e.,
1 Visit the root node first.
2 Go to the first left sub-tree.
3 After the completion of the left sub-tree, Go to the right sub-tree.
Here, the leaf nodes represent the stopping criteria. We go to the sibling sub-tree after the traversal of
a sub-tree. The pre-order traversal sequence for the binary tree shown in Fig. 6.3 is : A B D E G H C F
IJK
In-Order Traversal
In this traversal, the nodes are visited in the order of left child, root and then right child. i.e., the left
sub-tree is traversed first, then the root is visited and then the right sub-tree is traversed. Here also, the
leaf nodes denote the stopping criteria. The in-order traversal sequence for the above considered example
(Fig. 6.3) is: D B G E H A F J I K C
Post_Order Traversal
In this traversal, the nodes are visited in the order of left child, right child and then root. i.e., the left
sub-tree is traversed first, then the sibling is traversed next. The root is visited last. The post-order
traversal for the above example (Fig. 6.3) is: D G H E B J K I F C A
6.3.1 Traversal of a Binary Tree Represented in an Adjacency
Matrix
The steps involved in traversing a binary tree from the adjacency matrix representation, firstly requires
to find out the root node. Then it entails to traverse through the left subtree and then the right subtree in
specific orders. In order to remember the nodes already visited it is necessary to maintain a stack data
structure. Thus, following are the steps involved in traversing trough the binary tree given in an adjacency
matrix representation.
1 Locate the root (the column sum is zero for the root)
2 Display
64
Chapter 6 - Representation and Traversal of a Binary Tree
‘L’ found
Inorder Traversal
Algorithm: Inorder Traversal
Input: A[], one dimensional array representing the binary tree
i, the root address //initially i=1
Output: Inorder sequence
Method:
If (A[i] != 0)
Inorder Traversal (A, 2i)
Display(A[i])
Inorder Traversal (A, 2i +1)
If end
Algorithm ends
Postorder Traversal
Algorithm: Postorder Traversal
Input: A[], one dimensional array representing the binary tree
i, the root address //initially i=1
Output: Postorder sequence
Method:
If (A[i] != 0)
Postorder Traversal (A, 2i)
Postorder Traversal (A, 2i +1)
Display(A[i])
If end
Algorithm ends
We shall now look into the tree traversals in linked representation
67
BSIT 41 Algorithms
References
1. Sartaj Sahni, 2000, Data structures, algorithms and applications in C++, McGraw Hill international edition.
2. Horowitz and Sahni, 1983, Fundamentals of Data structure, Galgotia publications
3. Horowitz and Sahni, 1998, Fundamentals of Computer algorithm, Galgotia publications.
4. Narsingh Deo, 1990, Graph theory with applications to engineering and computer science, Prentice hall
publications.
5. Tremblay and Sorenson, 1991, An introduction to data structures with applications, McGraw Hill edition.
6. Horowitz, Sahni and Rajasekaran, 2000, Computer algorithms, Galgotia publications
7. Dromey R. G., 1999, How to solve it by computers, Prentice Hall publications , India.