Vous êtes sur la page 1sur 58

Classification of Algorithms

Algorithms can be categorized into different classes depending upon the paradigms
used to design these algorithms. The names of these classes are same as the name of the
paradigm used.
Some of the paradigms are:
 Divide and conquer: Specifies a technique in which a problem is reduced to one or
more sub problems. This process of reducing the problem into sub problems is
repeatedly performed until the final sub problem is easy to solve. For example, in
merge sort algorithm, a list is divided into sub lists. Then each sub list is sorted
separately. Finally, all the sorted sub lists are merged, and the resultant list is a
sorted list.
 Dynamic programming: Specifies a technique that avoids re-computation of
solutions that are already computed. In dynamic programming algorithm, a problem
is divided into sub problems. These sub problems are then solved and the solutions
of these sub problems are stored somewhere so that it can be used again to solve any
other problem if required. For example in an algorithm of finding the shortest path
between two nodes of a weighted graph, the shortest path can be found by using the
pre-calculated shortest paths between adjacent vertices.
 The greedy method: Specifies a technique, which is similar to dynamic
programming technique. The difference between the dynamic programming
technique and the greedy method technique is that in greedy method technique you
do not have to solve all the sub problems. Instead, you can select a sub problem that
can produce the best solution of the problem. For example, if you need to search for
an element in a tree, you can start traversing from either the left or right of the sub
tree. You can decide which sub tree is to be traversed first depending upon the value
of the key element that needs to be searched. If the value of the key element is less
than the value of the right sub tree, then traversing the left sub tree may yield a
better solution.
 Linear programming: Specifies a method in which a program is divided into a
finite number of linear functions that contain several variables. These functions are
then subjected to a number of constraints. These constraints are in the form of linear
inequalities. These linear inequalities are used to minimize or maximize the inputs
to the linear function. For example, when you need to write an algorithm to find the
maximum flow in a directed graph, you can use linear programming paradigm. With
the help of linear programming paradigm, you can find and add an augmented path
to already established flow in the graph. The addition of this augmented path
provides the maximum flow of liquid in the pipe.

Performance of Algorithms
The performance of an algorithm can be characterized depending upon two factors, the
space complexity and time complexity. The basic idea underlying the time complexity
is to determine a function of n, where n is the size of the problem for which the
algorithm is to be written. This function represents an expression of the number of steps
required to solve the problem. Since counting the actual number of steps to perform a
task is not easy, the time complexity is not measured by counting the actual number of
steps. Instead, the time complexity is measured as the number of critical operations
performed to complete a task. There are some standard notations that are used to
represent the measure of time complexity. These notations are explained as follows:
 Θ-Notation (Same order): Θ -Notation is defined as the expression f(n) = Θ (g(n))
where n is the size of the problem. This notation bounds the function f(n) within
constant factors. You need to find three positive constants n0, c1 and c2. The
values of these constants should be such that if the value of f(n) is calculated for the
values, which are larger than n0, the value of f(n) always lies between c1g(n) and
c2g(n) inclusive. This can be explained with the help of following figure:
c 2g (n )

f (n )

c 1g (n )

n
n0
Figure Depicting the Θ-Notation
 O-Notation (Upper Bound): O-notation (Upper Bound) is defined as an expression
f(n) = O(g(n)) where n is the size of the problem. This notation gives an upper
bound for the function f(n) within constant factors. You need to find two positive
constants n0 and c. The values of these constants should be such that if the value of
f(n) is calculated for the values, which are larger than n0, the value of f(n) always
lies on or below cg(n). This can be explained with the help of following figure:
c ( gn )

f (n )

n n
0
f (n ) O= ( g ( n ) )
Figure Depicting the O-Notation
 Ω-Notation (Lower Bound): Ω -Notation (Lower Bound) is defined as an expression
f(n) = Ω (g(n)) where n is the size of the problem. It gives a lower bound for the
function f(n) within constant factors. You need to find two positive constants n0,
and c. The values of these constants should be such that if the value of f(n) is
calculated for the values, which are larger than n0, the value of f(n) always lies on
or above cg(n). This can be explained with the help of following figure:

f (n )

c ( gn )

n n
0

Figure Depicting the Ω-Notation

Solutions to Chapter One Questions


1. ___________ is the process of executing a correct program on data sets and
measuring the time and space it takes to compute the results?
Ans.
Profiling

2. Define algorithm? What are its properties?


Ans.
An algorithm is a set of instructions that provide step-by-step specifications to perform
a task.
The properties of an algorithm are:
 Input: Specifies the data set that is applied to the algorithm to check its validity.
 Output: Specifies the data set that is produced as a result of the algorithm
execution.
 Definiteness: Specifies that the instructions described in the algorithm should be
well defined and should not create any ambiguity.
 Termination: Specifies that the instructions described in the algorithm must contain
a proper termination condition.
 Effectiveness: Specifies that the algorithm take less time and less memory space
during its execution.

3. What is debugging and what is profiling?


Ans.
Debugging is the process of identifying and fixing the errors in a program. Errors in a
program can be identified by executing the program with a sample dataset.
Profiling is the process of measuring the performance of the program by executing it on
different data sets. Performance of a program is measured by recording the time and
memory space that the program takes during its execution.
4. One of the properties of an algorithm is beauty (true/false)
Ans.
False

FAQ
1. Can we represent algorithms in a pictorial form?
Ans:
Yes, you can represent algorithms in the pictorial form using flow charts. Flow charts
make use of many geometrical shapes, such as rectangles and circles to represent the
input, output, and instructions of an algorithm.

2. What should I do if I have to solve a problem that contains many complex tasks?
Ans:
You can write separate algorithms for each task and then access these algorithms in
other algorithms in a sequence. For example, if you have to solve a problem in which
you have to perform the following tasks:
 Calculate the difference of two numbers
 Calculate the sum of other two numbers
 Print the output of both the operations
You can write separate algorithms for each of the first two tasks and then print the
output by writing a separate algorithm for the final task.

3. Are there any algorithmic notations to write a nested conditional statement?


Ans:
Yes, there is an algorithmic notation that you can use to write a nested conditional
statement, and it is as follows:
if <condition 1>
if <condition 2>
Block2
end if
Block1
end if

4. What should I do if I have to terminate a loop structure in the middle, when a


particular condition arises, which is different from the terminating condition of the
loop?
Ans:
You can use Break statement to terminate the loop when a particular condition arises,
which is different from the terminating condition of the loop.
Chapter Two

Complete Binary Tree and its Array representation


In a binary tree structure, each node can have minimum zero and maximum two child
nodes, left child node and right child node. A child node having no other child node is
known as a leaf node. If all the leaf nodes of a binary tree of height n are at the depth n
or n-1, the binary tree is called complete binary tree. In a complete binary tree, all the
nodes are filled either from left to right or from right to left. In the following figures,
figure A shows an incomplete binary tree, and the figure B shows a complete binary
tree:

Figure A
Figure B
In figure A, the leaf nodes having value 5 and 2 are at the level 2 and 4 respectively,
therefore, this violates the condition for the complete binary tree. However, in figure B
all the leaf nodes are at level n and n-1.
A complete binary tree can be represented by a simple one-dimensional array. The
following figure shows the array representation of the above complete binary tree,
considering the nodes are filled from left to right:

Array Representation of a Binary Tree

B-tree
While working with large sets of data, you need to store the data in secondary memory,
such as magnetic disk and floppy disk. However, the magnetic disk is slower in data
processing as compared to primary memory, such as RAM. Therefore, the process to
retrieve data from the secondary memory takes long time. For this, a balanced-tree (B-
tree) data structure is used, which minimizes the data access time. To minimize the
access time, each node in a B-tree contains an associated child node, where each child
node contains the data keys less than or equal to its preceding nodes. A data key
represents the data value contained in a node. A node has an additional right-most tree,
which contains data keys greater than its preceding nodes. Each node in the B-tree
structure tends to have large numbers of child nodes, as a result, you can find any key in
the structure by traversing a few nodes. Therefore, a B- tree minimizes the number of
disk accesses to find the desired key.
The following figure shows an example of a simple B-tree:

B-tree
The preceding figure shows a B-tree structure. In the figure, each node has three data
keys, which are less than or equal to the preceding data keys. However, the right-most
node has data keys more than the preceding data keys.
Operations Performed on a B-tree
The various operations that you can perform on a B-tree structure are:
 Finding a key in a B-tree structure: To search a data key, such as 12, in the above
B-tree data structure, first of all compare the first data key of root node, 6, with the
data key to be searched, 12. However, the data key 12 is greater than 6, therefore,
the next data key, 11, is compared with data key 12. The data key 12 is greater than
11, therefore, the next data key 16 is compared with data key 12. However, the data
key 12 is less than 16, therefore, the associated child node is selected and the first
data key 12 is compared with it. Now, these two data keys have same value,
therefore, this data key in the structure is the desired data key.
 Inserting a key in a B-tree structure: To insert a data key, such as 15, in the above
B-tree data structure, first of all compare the first data key of root node, 6, with the
data key, 15, to be inserted. The data key 15 is greater than 6, therefore, the next
data key 11 is compared with data key 15. The data key 15 is greater than 11,
therefore, the next data key 16 is compared with data key 15. However, the data key
15 is less than 16, therefore, the associated child node is selected and data key 15 is
arranged in this node in the ascending order.
The following figure shows the B-tree structure after inserting a data key 15:

B-tree after Inserting a Data Key 15

Solutions to Chapter Two Questions


1. Give at least 5 real life examples where we use stack operations.
Ans.
The real life examples of stacks are:
 Bangles in a hand: The bangles wore in a hand follow last-in-first-out (LIFO)
strategy of stack. The bangle that you wear first is the last one to be taken out while
removing all the bangles from the hand. The bangle that is worn last is the first one
to be taken out.
 Same circumference circular rings in a pole: The rings having same
circumference placed into a pole also follow LIFO strategy. The topmost ring,
which was the last to be placed in the pole, is the first one to be taken out.
 Sacks full of wheat placed one over other: The sack at the top is removed first and
the sack at the bottom is removed last.
 The bolts screwed to a single nut: When the bolts are screwed to a single nut, the
last screwed bolt is unscrewed first and the bolt that was screwed first is unscrewed
in the last.
 Battery cells in a torch: The battery cells in a torch also follow the same LIFO
strategy of stack.
2. Give at least 5 real life examples where queue is used.
Ans.
Real life examples of queue are:
 A queue of people at ticket-window: The person who comes first gets the ticket
first. The person who is coming last is getting the tickets in last. Therefore, it
follows first-in-first-out (FIFO) strategy of queue.
 Vehicles on toll-tax bridge: The vehicle that comes first to the toll tax booth leaves
the booth first. The vehicle that comes last leaves last. Therefore, it follows first-in-
first-out (FIFO) strategy of queue.
 Phone answering system: The person who calls first gets a response first from the
phone answering system. The person who calls last gets the response last.
Therefore, it follows first-in-first-out (FIFO) strategy of queue.
 Luggage checking machine: Luggage checking machine checks the luggage first
that comes first. Therefore, it follows FIFO principle of queue.
 Patients waiting outside the doctor's clinic: The patient who comes first visits the
doctor first, and the patient who comes last visits the doctor last. Therefore, it
follows the first-in-first-out (FIFO) strategy of queue.

3. Name 10 situations that can be represented by means of graphs. Explain what each
vertex and edge represents.
Ans.
The situations that can be represented by means of graphs are:

Example Vertex represents Edge represents

Displacement Position or state Distance between the two vertices


connected through the edge

Shortest Path City Distance between the two vertices


connected through the edge

City Map Places of the city Distance between the two vertices
connected through the edge

Air route Different airports Distance between the two vertices


connected through the edge

Population Growth Population for an Variation in the population between


per year year the two vertices connected through
the edge

In mathematical Value Conditions and calculations


expressions

Daily temperature Temperature for a Variation in the temperature


report specific time between the vertices connected
through the edge
Child-parent Name of the person Relationship
relationship

Organization chart Designation Order or flow

Chemical structure Chemical elements Bonding between the elements


4. Draw a connected graph that becomes disconnected when any edge is removed from
it.
Ans.
The following figure shows a graph that becomes disconnected when any edge is
removed from it:

Disconnected Graph

5. Draw all trees of n labeled vertices for n=1,2,3,4 and 5.


Ans.
The following figures show the trees for various values of n, where n represents the
number of vertices in a tree.
For n=1

For n=2

For n =3
There can be a number of trees with 3 labeled vertices. Some of the examples of the
trees with 3 labeled vertices are:
For n=4
Again, there can be a number of trees with 4 labeled vertices. Some of the examples of
the trees with 4 labeled vertices are:

For n=5
Again, there can be a number of trees with 5 labeled vertices. Some of the examples of
the trees with 5 labeled vertices are:
6. Sketch all binary trees with six pendent edges.
Ans.
The following figures show binary trees with six pendent edges:

Binary Tree with Six Pendent Edges


The preceding figures, A, B, and C, show three examples of binary trees having six
pendent edges. All the binary trees having six leaf nodes come under this category.

7. Write adjacency and incidence matrix for all the graphs developed.
Ans.
The following tables show adjacency and incidence matrices for the graph of question
no. 4:
FAQ
1. How will you insert an element in an empty queue?
Ans:
You need to increase the value of rear end by one and then insert the value at the
location where the rear end of the queue points.

2. Can a three-dimensional array be represented on a paper?


Ans:
Yes, a three-dimensional array can be represented on a paper by using blocks where
each block represents a two-dimensional array.

3. Where do you implement stack operation in a program?


Ans:
You implement stack operation during recursion and function call operations in a
program.

4. Can a matrix have equal number of rows and columns? What is the name of this
matrix?
Ans:
Yes, a matrix can have equal number of rows and columns. This matrix is called a
square matrix.

5. Can a tree be structured?


Ans:
Yes, a tree can be structured. A structured tree is used to represent a hierarchical
relationship among the various nodes of the tree. For example, parent-child relationship
in a family can be well represented using a structured tree.

6. What are the basic differences between a graph and a tree?


Ans:
The basic differences between a graph and a tree are:
A tree cannot have any cycle, however, a graph can have a cycle in its structure.
All the nodes in a tree structure should be connected to a root node either directly or
through any other node, however, in a graph, it is not necessary.
The numbers of edges in a tree are always one less than the number of nodes, however,
in a graph, edges are less than the vertex but no relation exists between the vertex and
its edges.
Chapter Three

Control Structures
Control structures are used in an algorithm to determine the flow of the algorithm. Two
types of control structures used in an algorithm are:
 Conditional statements
 Looping statements

Conditional Statements
Conditional statements determine the flow of algorithms based on whether the
condition is true or not. A conditional statement is of four types:
 if statement
 if else statement
 if...elseif...else statement
 switch statement
The if statement is a conditional statement used to execute a set of code when a
specified condition is true. The syntax of using the if statement is:
if (condition)
{
code to be executed
}
An example of using the if statement is:
if (a is equal to b)
{
accept (a)
}
The if else statement is a conditional statement used to execute a set of code when a
specified condition is true and another set of code when the condition is false. The
syntax of using the if else statement is:
if (condition)
{
code to be executed
}
else
{
code to be executed
}
An example of using the if else statement is:
if (a>b)
{
display (a)
}
else
{
display (b)
}
The if...elseif...else statement is a conditional statement used to execute a set of code
when a specified condition is true from a set of conditions. The syntax of using the
if...elseif...else statement is:
if (condition)
{
code to be executed
}
else if (condition)
{
code to be executed
}
else
{
code to be executed
}
The example of using the if...elseif...else statement is:
if (a<5)
{
display (a)
}
else if (a>5 and a<10)
{
display (b)
}
else
{
display (c)
}
The switch statement is a conditional statement used to replace if...elseif...else
statement. The syntax of using the switch statement is:
switch(choice)
{
case 1:
executable code
break
case 2:
executable code
break
case 3:
executable code
break
default:
executable code
}

Note
You use the break statement after the executable code to
terminate the switch case statement.
The example of using the switch statement is:
switch(choice)
{
case 1:
display (apple)
break
case 2:
display (mango)
break
case 3:
display (pineapple)
break
default:
display (banana)
}
Looping statements determine the flow of algorithms based on number of iterations
required for the algorithm. Looping statements are of three types:
 while loop
 do while loop
 for loop
The while loop statement is used to execute a block of code as long as the specified
condition is true. If the condition is false initially the block of code is not executed at
all. The syntax of using the while loop is:
while (condition)
{
code to be executed
}
An example of using the while loop is:
while (a>b)
{
display (a)
}
The do while looping statement is used to execute a block of code as long as the
specified condition is true. The do statement executes the code at least once before
checking the condition. The syntax of using the do while loop is:
do
{
code to be executed
} while (condition is satisfied)
The example of using the do while loop is:
do
{
display (a)
} while (a>b)
The for looping statement is used to execute a set of statements until the test condition
is terminated.
The syntax of using the for loop is:
for (initialization, test condition, action)
{
code to be executed
}
An example of using the for loop is:
for (a=1 to 5 in steps of +1)
{
display (a)
}
The following figure shows the categorization of control structures:

Categorization of Control Structures

Multiplying Two Matrices


Consider,
When multiplying two matrices the number of columns in one matrix should be equal to
the number of rows in the other matrix. The procedure is described as follows:
The two matrices have to be read initially in a two dimensional array. The row elements
of first matrix are multiplied with the corresponding column elements of second matrix.
For example, the elements of the first row of the first matrix are multiplied with the
elements of the first column of the second matrix. Similarly, the elements of the second
row of the first matrix are multiplied with the elements of the second column of the
second matrix, and so on. The sums of all these multiplications realize the elements of
the resultant matrix.
Algorithm: Matrix Multiplication
Input: order of the matrices (n),
a(n,n), b(n,n) the two input matrices
Output: c(n,n) the resultant multiplication matrix
Method:
Accept n
for (i =1 to n in steps + 1 do)
for (j =1 to n in steps + 1 do)
accept a (i,j)
end_for
end_for
for (i =1 to n in steps + 1 do)
for (j =1 to n in steps + 1 do)
accept b (i,j)
end_for
end_for
for (i =1 to n in steps + 1 do)
for (j =1 to n in steps + 1 do)
for (k =1 to n in steps + 1 do)
c(i,j)= c(i,j)+ a(i,k)* b(k,j)
end_for
end_for
end_for
for (i =1 to n in steps + 1 do)
for (j =1 to n in steps + 1 do)
display c(i,j)
end_for
end_for
Solutions to Chapter Three Questions
1. Design and develop algorithms for multiplying n integers.
Hint: Follow the algorithm to add n numbers given in the text
Ans.
Algorithm: Multiply_n_Integers
Input: integers, number of integers to be multiplied (n), loop variable (i)
Output: mul, updated
Method: Display 'Enter the number of elements'
Accept n
Display 'Enter elements one by one'
for (i = 1 to n in steps of 1 do)
Accept a (i)
end_for
mul = 1
for (i = 1 to n in steps of 1 do)
mul = mul*a(i)
end_for
Display 'multiplication of n integers is = ', mul

2. Design and develop an algorithm for finding the middle element in three numbers.
Ans.
To find the middle element one has to first sort the numbers in ascending order. The
smallest number becomes the first element in the sorted list and the largest number
becomes the last element in the sorted list.
Consider three numbers 3, 1, and 7.
The smallest number amongst these three is 1; therefore, 1 becomes the first element in
the sorted list. Amongst 3 and 7, 3 is the second element. The larger number 7 is left out
and becomes the last element. Hence the middle number 3 is displayed.
Algorithm : Middle_3_Elements
Input: a, b, c the three numbers to be sorted, two temporary variables k1, and K2
Output: Middle element in the three numbers.
Method:
If (a<b)
If (a<c)
If (b<c)
m=b
else
m=c
end if
else
m=a
end if
else
if (b<c)
if (a<c)
m=a
else
m=c
end if
else
m=b
end if
end if
3. Develop an algorithm to find the number of Permutations and Combinations for a
given n and r.
Ans.
Permutation of a given number is given by n*(n-1)*(n-2)...up to r factors.
This is a generalized algorithm for n>2
Algorithm: Permutation of a number for a given r
Input: n and r
Output: Permutation of n
Method:
a) per = 1
for (j = n to n - r + 1 in steps of -1 do) //where j is a loop variable
per = per*j
end_for
Display ' Permutation = ', per
b) Combination of a number n for a given r is calculated by
nCr = nPr / r!
Calculate the permutation nPr using the above algorithm
Calculate the factorial for r using the algorithm
fact = 1
for (j =1 to r in steps of 1 do) //where j is a loop variable
fact = fact*j
end_for
comb = per / fact
Display ' Combination =', comb

4. Design an algorithm to generate all prime numbers within the limits l1 and l2.
Ans.
Algorithm: to generate all prime numbers between the limits l1 and l2.
Input: l1 and l2
Output: Prime numbers between l1 and l2
Method:
for (n=l1 to l2 in steps of 1 do)
prime=true
for (i=2 to n/2 in steps of 1 do)
if (n % i =0)
prime = false
break
end_if
end_for
if (prime = true)
Display 'Prime number is =', n
end_for
5. Design an algorithm to find the reverse of a number.
Ans.
Algorithm: Reverse of a number
Input: number
Output: Reverse of a number
Method:
new_number = 0
while (number > 0)

n = number % 10 //n denotes a digit extracted from the number


number = number / 10
new_number = new_number +n
new_number= new_number*10
end while
new_number = new_number/10
Display 'Reverse number is =', new_number

6. A number is said to be a palindrome if the reverse of a number is same as the


original. Design an algorithm to check whether a number is a palindrome or not.
Ans.
Algorithm: check whether the number is a palindrome or not
Input: number, flag
Output: number is a palindrome
Method:
count = 0
while (number > 0)

n = number%10
a(count)=n
count = count+1
end while
half = count/2
palin = true
for (j=1 to half in steps of 1 and k=count to half in steps of –1 do)

if (a (j)! =a(k))
palin = false
break
end if
if (palin = true)
Display 'Number is a palindrome'
else
Display 'Number is not a palindrome'
end if
end for
7. Design an algorithm to check whether a given string is a palindrome or not.
Ans.
Algorithm: check whether the string is a palindrome or not
Input: string, flag
Output: string is a palindrome
Method:
count = 0
while (the next character ch in the string is not empty)

a(count) = ch
count = count+1
end while
half = count/2palin = true
for (i=1 to half in steps of 1 and j=count to half in steps of –1 do)

if (a (i)! =a (j))
palin = false
break
end if
if (palin = true)

Display 'String is a palindrome'


else
Display 'String is not a palindrome' end if
end for

8. Implement all the devised algorithms and also the algorithms discussed in the
chapter.
Ans.
You can implement algorithms discussed in this chapter in various languages, such as
C++ and Java. However, you need to know the syntax of the respective language before
implementing it.

FAQ
1. Is there any operator that determines the remainder during division operation?
Ans:
Remainder can be found out using the operator %.

2. What will happen when the user tries to find out the quadrant for the coordinate input
(0,0)?
Ans:
When the user inputs (0,0) the first condition in the algorithm that is x>=0 and y>=0
gets satisfied and the program will output first quadrant as the solution.
3. How to calculate the factorial for number 0?
Ans:
!0 =1
This exception is generally specified by the programmer.
This condition can be checked using if else statement.

4. How to find the largest of three numbers a, b, and c?


Ans:
largest = a
if (largest<b)
largest = b
if (largest<c)
largest = c
Display 'Largest number is', largest

5. How to interchange the values of two numbers a and b?


Ans.
Consider a variable c to temporarily store the value of variable, a. The following
algorithm shows how to interchange the values of two numbers by using a temporary
variable.
Display 'Enter the value of a'
Accept a
Display 'Enter the value of b'
Accept b
c=a
a=b
b=c
Display 'The values of a and b are ', a, b

6. How to interchange the values of two numbers a and b without using temporary
variable?
Ans:
Display 'Enter the value of a'
Accept a
Display 'Enter the value of b'
Accept b
a=a+b
b=a-b
a=a-b
Display 'The values of a and b are ', a, b
Chapter Four

Indexed Sequential Searching


Indexed sequential search is a technique used to search an element in a given list. In
indexed sequential search technique, it is necessary to have the elements to be arranged
in the ascending order in a list. In indexed sequential search, an auxiliary table is set
aside along with the list in which the key element is to be searched. This auxiliary table
is called Index. The Index contains two columns, kindex and pindex. Column kindex
contains elements from the given list. Column pindex contains address of the memory
location where the elements of the given list represented by kindex are stored.
Indexed sequential search can be explained with the help of following example:
Suppose you have to find the key element 289 in the given list of 18 elements. Let us
take an index table that contains 3 records. Therefore, the given list is divided into three
parts each having 6 (calculated as 18/3 = 6) elements and each record in the Index
represents the 6th element in the given list.

The key element 289 is smaller than the first element 342 in the kindex. Therefore, you
do not need to search the entire list. You can simply search for the key element in the
sub list x [0..6].
Algorithm: Indexed Sequential Search
Input : n, Size of the input domain
A [1..n], array of n elements
k, search element
indexsize, size of the auxiliary table called Index
Output : j, position of k
Method :
i=0
while (i< indexsize and kindex [i]< k)
i=i+1
end_while
if i=0 then
lowlim = 0
else
lowlim = pindex [i-1]
end_if
if i=indexsize then
hilim=n-1
else
hilim=pindex [i]-1
end_if
j=lowlim
While (j<= hilim and A [j] ! = k)
j=j+1
end_while
if j> hilim then
return -1
else
return j
end_if

Bubble Sorting
The basic idea underlying the bubble sorting technique is to pass through the file
containing n number of elements n-1 number of times. In each pass, each ith element in
the file is compared with its successor (i+1)th element. If the ith element is greater than
its successor element, these elements are interchanged.
Consider the file containing the following elements:

Following changes are made during the first pass:


21 is compared with 53 (as 21< 53) no change in the order of the elements.
53 is compared with 48 (as 53> 48) interchange the elements.
53 is compared with 35 (as 53> 35) interchange the elements.
53 is compared with 12 (as 53> 12) interchange the elements.
53 is compared with 87 (as 53< 87) no change in the order of the elements.
87 is compared with 82 (as 87> 82) interchange the elements.
87 is compared with 33 (as 87< 33) interchange the elements.
The resultant order of elements after the first pass is as follows:

Similarly, the subsequent passes yield:


Algorithm : Bubble Sort
Input : n, Size of the input domain
A [1..n], array of n elements
Output : a [1...n] sorted
Method :
for (i=0 to n-1 in steps of 1 do)
for (j=0 to n-i-1 in steps of 1 do)
If (a [j]> a [j+1]) then interchange a [j] and a [j+1]
end_if
end_for
end_for

Solutions to Chapter Four Questions


1. What are the serious shortcomings of the binary search method and sequential search
method?
Ans.
A serious shortcoming of the sequential search method is that even if the element that
you are trying to search is not present in the given file, the entire file is searched at least
once.
A serious shortcoming of the binary search method is that it can be applied only to a list
in which the elements are arranged in ascending order.

2. Consider a data set of nine elements {10, 30, 45, 54, 56, 78, 213, 415, 500} and trace
the linear search algorithm to find whether the keys 30, 150, 700 are present in the data
set or not.
Ans.
In linear search algorithm, each element in the list is compared with the given key
element. If any of the elements in the list is equal to the given key element, the linear
search algorithm returns TRUE, else it returns FALSE.
Let us apply linear search to find the key element 30 in the given list.
 Take the first element 10 from the list and compare it with the key element 30.
Clearly the two elements are not equal.
 Take the next element 30 from the list and compare it with the key element 30.
Clearly, the two elements are equal. The algorithm returns the TRUE value, and the
algorithm is terminated.
Similarly, search for the key elements 150 and 700. At the end of the search, you will
find that the key elements 150 and 700 are not found in the list.
3. Trace the binary search algorithm on the same data set and same key elements of
problem 2.
Ans.
Binary search algorithm can be applied only to the sorted list of elements. Lets first
apply the binary search algorithm to find the key element 30 in the following list taken
from problem 2:
Take the middle element from the list and compare it with the key element. Clearly, the
middle element 56 > key element 30. As the key element is smaller than the middle
element, the key element can only be present in the left sub list that is as follows:

Again, take the middle element from this list and compare it with the key element.
Clearly, the middle element 45 > key element 30. As the key element is smaller than
the middle element, the key element can only be present in the left sub list that is as
follows:

Again, take the middle element from this list and compare it with the key element.
Clearly middle element 30= key element 30, therefore, the binary search algorithm
returns a TRUE value and the algorithm is terminated.
Similarly, search for the key elements 150 and 700. At the end of the search, you will
find that the key elements 150 and 700 are not found in the list.

4. Try to know more sorting techniques and make a comparative study of them.
Ans.
There are various sorting techniques, such as bubble sort, quick sort, and shell sort.
Each of these sorting techniques is defined as follows:
 Bubble sort: In the bubble sort technique two elements are compared at a time and
if the two elements are not in ascending order these elements are interchanged. This
process is repeatedly performed throughout the given list until the list is completely
sorted. To sort a list of n elements using bubble sort you need to make a total of (n-
1)2 comparisons.
 Quick sort: The basic idea underlying quick sort is to allow a specific element 'a'
within the list 'x' to find its proper position 'j'. The proper position 'j' is found such
that it satisfies the following two conditions:
The elements on the left hand side of position 'j' are all smaller than or equal to 'a'
The elements on the right hand side of position 'j' are all greater than or equal to 'a'
If 'a' satisfies these two conditions, then 'a' is the jth smallest element in the list and
'a' is placed at jth position in the finally sorted list. This process is then repeated for
sub arrays x [0..j-1] and x [j+1..n-1].
 Shell sort: In shell sort, the given list x is divided into sub lists containing every kth
element of the given list. For example, if k=5 then one sub list contains x [0], x [5],
x [10]..., another sub list contains x [1], x [6], x [11]..., and so on. The elements of
these sub lists are then compared two at a time and if the two elements are not in
ascending order, these elements are interchanged.
Now, a new value of k is chosen which is smaller than the previous value of k and
the process is repeated again. This process is repeated until the value of k is set to 1
so that the sub list consisting of the entire list is sorted.
5. Hand simulate Insertion Sort on the data set {13, 45, 12, 9, 1, 10, 40}
Ans.
Let us apply Insertion Sort algorithm on the given list:

Note
The figure 4.1 given on page 41 of the book is incorrect. It
shows the steps for straight selection sort.

6. Implement all the algorithms designed in the chapter.


You can implement algorithms discussed in this chapter in various languages, such as
C++ and Java. However, you need to know the syntax of the respective language before
implementing it.

FAQ
1. I have stored some messages received from my friends in a folder and I want to sort
these messages. How can I do that?
Ans:
To sort a list of elements you need to compare each element with the other element in
the list and then place these elements in the sorted order. The messages do not contain
any information that can be used to compare one message with the other. Therefore,
you can sort these messages only with respect to the names of your friends, which can
be easily compared.
2. Is there any other kind of selection sorting technique, which is different from the
straight selection sorting technique?
Ans:
Yes, there is one more selection sorting technique known as the general selection sort.
In general selection sort each element is selected one at a time and placed in its proper
sorted position in the given list. The elements are selected in the same order in which
they are placed in the given list.

3. Can we implement binary search technique to find an element in a data structure


other than arrays?
Ans:
Yes, you can use the binary search technique to search an element in a tree data
structure. To apply the binary search technique on a tree data structure, the left hand
child node of the tree data structure must be less than or equal to the parent node. In
addition, the right hand child node must be greater than or equal to the parent node.

4. To sort a list of alphabets, I need to compare two alphabets and place them in proper
order. How does the computer understand that alphabet a is less than b?
Ans:
The computer does not compare the alphabets as it is, but it compares the ASCII values
of alphabets, which are in the form of numerals.

5. What should I do if I have to insert an element in a given list such that the elements
in the list are in ascending order?
Ans:
Sort the elements in the given list in ascending order using insertion sorting technique.
Then select a position in the list where the new element is to be inserted. Move all the
elements that are placed at the right hand side of this position by one position to the
right. This process of moving the elements creates an empty space in the given list.
Place the new element at this newly created space in the list. The space is created such
that the element is placed in the ascending order in the list with respect to the elements
already present in the list.
Chapter Five

Nested Recursion
A recursive call is called nested if the result of the recursive call to itself depends on
the result of another recursive call to itself. The following algorithm illustrates the
functioning of nested recursion.
Algorithm: nestrecurs(i)
input: i
if(i>101)
return(i-10)
else
nestrecurs(nestrecurs(i+11))
end_if
In the above algorithm, nestrecurs(nestrecurs(i+11)) represents nested recursion. The
result of the outer recursive call, nestrecurs(nestrecurs(i+11)), depends on the result of
the inner recursive call nestrecurs(i+11).
For example, take a number i= 99. The processing takes place in four recursions when
the value of i is put in the algorithm, nestrecurs(i).
During the first pass through the algorithm, you will obtain the following value:
As i<100
nestrecurs(99) = nestrecurs(nestrecurs(110)
After the first recursive call by the inner recursive function nestrecurs(110), you will
obtain the following value:
As i>100
nestrecurs(99) = nestrecurs(100)
After the second recursive call by the outer recursive function nestrecurs(100), you will
obtain the following value:
As i=100
nestrecurs(nestrecurs(111)
After the third recursive call by the inner recursive function nestrecurs(111), you will
obtain the following value:
As i>100
nestrecurs(101)
After the fourth recursive call by the outer recursive function nestrecurs(101), you will
obtain the following value:
As i>100
91
Shell Sort
In shell sort, the original file is divided into sub files and each sub file contains kth
element of the original file. For example, if k=5 then one sub file contains x[0], x[5],
and x[10], another sub file contains x[1], x[6], and x[11], and the list of sub files
continues till the value of first element of the sub file reaches to x[4]. These sub files
are sorted and a smaller value of k is selected. The process is repeated till the value of k
is set to 1 so that the sub file consisting of the entire sub files is sorted. The following
algorithm shows the shell sort process.
algorithm: shellsort (original file)
Input: original file, k
subfile (original file, k)
sort (subfiles)
k=k-2
if(k>=1)
shellsort(sorted file)
else
return (1)
end_if
To understand the above algorithm, take an example of an original file, which is
25 67 56 39 20 103 97 37
Take the value of k = 5.Therefore, the first sub file contains the elements of the original
file at 0th and 5th position and the second sub file contains the elements of the original
file at 1st and 6th position. The third sub file contains 2nd and 7th elements, the forth
sub file contains 3rd, and the fifth sub file contains 4th element of the original file.
Now, elements of each sub file are sorted in ascending order. The following table
shows all the sub files in ascending order:

Sub file Elements

First sub file 25 103

Second sub file 67 97

Third sub file 37 56

Forth sub file 39

Fifth sub file 20

Now, the value of k is decreased by 2, therefore, the value becomes 3 after the
decrement. The value of k is greater than 1, therefore, shell sort algorithm is called
again for k=3, which represents first recursive call. The following table shows all sub
files in ascending order after the first recursive call:

Sub file Elements

First sub file 25 39 97

Second sub file 20 56 67

Third sub file 37 103

Now, again the value of k is decreased by 2, which is 1 after the decrement. The value
of k is equal to 1, therefore, shell sort algorithm is called again for k=1, which
represents the second recursive call. The following table shows all sub files in the
ascending order after the second recursive call:

Sub file Elements

First sub file 20 25 37 39 56 67 97


103

Now, again the value of k is decreased by 2, which becomes -1 after the decrement. The
value of k is now less than 1, therefore, shell sort algorithm will return the file, which is
arranged in the sorted order.

Solutions to Chapter Five Questions


1. Trace out the algorithm Merge Sort on the data set {1,5,2,19,4,17,45,12,6}
Ans.
Steps to perform Merge Sort on the data set {1,5,2,19,4,17,45,12,6} are:
(1,5,2,19,4}{17,45,12,6)
((1,5,2) (19,4)) ((17,45)(12,6))
(((1,5) (2)) ((19)(4))) (((17)(45)) ((12) (6)))
((((1) (5)) (2)) ((19)(4))) (((17)(45)) ((12) (6)))
(1,5) (2) (4,19) (17,45) (6,12)
(1,2,5) (4,19) (17,45) (6,12)
(1,2,4,5,19) (6,12,17,45)
(1,2,4,5,6,12,17,19,45)

2. Trace out the algorithm Quick Sort on the data set {12,1,5,7,19,15,8,9,10}.
Ans.
Steps to perform Quick Sort on the data set{12,1,5,7,19,15,8,9,10} are:
{(12),1,5,7,19,15,8,9,10}
{(12),1,5,7,10,15,8,9,19}
{(12),1,5,7,10,9,8,15,19}
{8,1,5,7,10,9,(12),15,19}
{(7),1,5,8,10,9}{12}{(15),19}
{5,1,(7),8,10,9}{12}{15,19}
{(5),1}{7}{(8),10,9}{12}{15}{19}
{1,(5)}{7}{(8),9,10}{12}{15}{19}
{1,(5)}{7}{(8),9,10}{12}{15}{19}
{1}{5}{7}{8}{(9),10}{12}{15}{19}
{1}{5}{7}{8}{9}{10}{12}{15}{19}

3. Implement all the algorithms designed in this chapter.


Ans.
You can implement algorithms discussed in this chapter in various languages, such as
C++ and Java. However, you need to know the syntax of the respective language before
implementing it.

4. Trace out the algorithm MaxMin on a data set consisting of at least 8 elements.
Ans.
Steps to perform MaxMin on a data set (2,4,6,3,8,1,9,7) are:
(2,4,6,3) (8,1,9,7)
((2,4)(6,3)) ((8,1)(9,7))
In sublist (4,6), max is 6 and min is 4. In sublist (8,9), max is 9 and min is 8.
Comparing max and min values of sublist (2,4) and sublist (6,3), value of max is 6 and
min is 2.
Therefore, for sublist (2,4,6,3) max is 6 and min is 2.
Similarly, comparing max and min values of sublist (8,1) and sublist (9,7), value of
max is 9 and min is 1.
Therefore, for sublist (8,1,9,7) max is 9 and min is 1.
Finally, comparing max and min values of sublist (2,4,6,3) and sublist (8,1,9,7), value
of max is 9 and min is 1.
5. List out the merits and the demerits of recursion.
Ans.
Merits of recursion are:
Mathematical functions, such as fibonacci series generation can be easily implemented
using recursion as compared to iteration technique.
Demerits of recursion are:
Many programming languages do not support recursion; hence, recursive mathematical
function is implemented using iterative methods.
Even though mathematical functions can be easily implemented using recursion, it is
always at the cost of execution time and memory space.
The recursive programs take considerably more storage and take more time during
processing.

6. The data structure used by recursive algorithms is ______.


Ans.
Stack

7. When is it appropriate to use recursion?


Ans.
Recursion is used for repetitive computations in which each action is stated in terms of
previous calculation results.

FAQ
1. What will happen if a terminating condition is not given in a recursive process?
Ans:
If the terminating condition is not given the recursive process, the recursive process will
be continued in an infinite loop.

2. What is the complexity of quick sort and merge sort for an average case?
Ans:
The complexity of both merge sort and quick sort for an average case is:
O(n log n)

3. Can I solve any problem without using recursion?


Ans:
Yes, you can solve any problem without using recursion. However, the number of
iterations in a program increases when you create a program without recursion. This is
because recursion provides an easy and efficient way to solve complex problems.

4. Give some examples of sorting where you can use recursion?


Ans:
There are various types of sorting that use recursion, such as shell sort and heap sort.
5. In the worst case complexity, which sorting technique, merge sort or quick sort,
should be used and why?
Ans:
In the worst case complexity, you should use merge sort. The complexity of merge sort
in worst case is O(n log n), which is better then the complexity of quick sort in worst
case that is O(n2).
Chapter Six

Infix, Prefix, and Postfix Expressions


Infix, prefix, and postfix are various notations that can be used for representing a
mathematical expression. In infix notation, the operator is placed between the two
operands. In prefix notation, the operator precedes the two operands whereas in postfix
notation, the operator follows the two operands. The prefixes 'pre', 'post', and 'in' refer
to the relative position of the operator with respect to the two operands.
Consider an example that represents the sum of two variables, A and B. The infix
notation for this equation is represented as A+B. The postfix notation for this equation
is represented as AB+
The prefix notation for this equation is represented as +AB.
Consider another example, A+B*C. This equation is written in the standard infix
notation. Before evaluating the expression, you must know the operation to be
performed first. The operation to be performed first can be determined from the
arithmetic precedence of operators. In the absence of parenthesis in the above equation,
it is explicit that multiplication precedes over addition. The general rule during the
conversion process is that the operations with highest precedence are converted first.
The expression obtained after this conversion is then treated as a single operand. The
above equation can be represented in infix notation with parenthesis as:
A + (B * C) parenthesis for emphasis
A + (B * C) evaluate the multiplication
A+D evaluate the addition where D= B * C
The same equation, A + B * C, can be represented in postfix notation as:
A + (B * C) parenthesis for emphasis
A + (B C*) convert the multiplication
A (BC*)+ convert the addition
A BC*+ postfix notation
The same equation, A + B * C, can be represented in prefix notation as:
A + (B * C) parenthesis for emphasis
A + (*B C) convert the multiplication
+A (*BC) convert the addition
+A *BC prefix notation
A mathematical expression can also be represented in the form of a binary tree, called
expression tree. For example, the expression, 2+3*5 can be represented as:
*

2 3 5

The inorder traversal of an expression tree yields the expression in inorder notation. The
postorder traversal of a binary tree yields the expression in postorder notation.
Similarly, the preorder traversal of a binary tree yields the expression in preorder
notation.

Strict Binary Tree


If every non-leaf node in a binary tree has non-empty left and right sub trees, the tree is
known as a strict binary tree. A strict binary tree with n leaves always contains (2n-1)
nodes.
Note: A non-leaf node is the node that is not present at the last level of the binary tree
and has at least one child node.
The following figure shows how to represent a strict binary tree:

Strict Binary Tree

Solutions to Chapter Six Questions


1. What is a binary tree?
Ans.
A binary tree is made up of nodes where each node consists of three elements, left node,
right node and a data element. The root node is the topmost node of the binary tree.

2. Differentiate between complete and full binary trees?


Ans.
The following table lists the differences between complete binary trees and full binary
trees:

Complete binary trees Full binary trees

All the nodes at the previous All levels are maximally


level are fully accommodated accommodated.
before the next level is
accommodated.

Number of nodes at the last Number of nodes at the last (n)


(n) level may or may not level is exactly equal to 2n.
equal to 2n.

Leaf nodes may or may not be All leaf nodes are at the same
at the same level. level.

A complete binary tree may or A full binary tree is always a


may not be full binary tree. complete binary tree.
3. What is the maximum number of nodes in the binary tree of level 7, 8, and 9?
Ans.
The maximum number of nodes in the binary tree is calculated by 2l+1 - 1 where l is the
level of the binary tree.
The maximum number of nodes for level 7, 27+1 - 1 = 255
The maximum number of nodes for level 8, 28+1 - 1 = 511
The maximum number of nodes for level 9, 29+1 - 1 = 1023

4. What is the wastage of memory for a binary tree with 16 nodes represented in a 1D
array, 2D array, and a linked representation?
Ans.
a) For a 1D array, the formula for calculating percentage of memory utilization is:
(n -1/2l+1 - 1)*100 where n represents the number of nodes and l represents the depth of
the tree. However, in the given question, the depth has not been specified. Therefore,
the percentage memory utilization cannot be calculated.
b) For a 2D array, the percentage of memory utilization is:
(n -1/n2)*100 = (16 -1/162)*100 = 5.86%
Therefore, the wastage of memory in 2D array is 100 - 5.86 = 94.14%
c) For a linked list, the percentage of memory utilization is:
(n -1/2n)*100 = (16 -1/2*16)*100 = 46.88%
Therefore, the wastage of memory in 1D is 100 - 46.88 = 53.13%

5. For at least 5 binary trees of different depths greater than or equal to 6 of your choice,
obtain the preorder, postorder and inorder sequences.
Ans.
The following figure shows a binary tree with 14 nodes where A is the root node:
Binary Tree with 14 Nodes
The preorder traversal sequence for the above binary tree is:
ABDHKMNLECFIJG
The infix notation for the above binary tree is:
MKNHLDBEAIFJCG
The postorder notation for the above binary tree is:
MNKLHDEBIJFGCA

FAQ
1. Determine the condition in which complete binary tree is called full binary tree.
Ans:
A complete binary tree is called full binary tree if,
 All the leaves are present only at the last level.
 All the nodes at the previous level are fully accommodated.

2. What is static allocation for representing a binary tree?


Ans:
Static allocation means that the memory allocation for representing the binary tree using
1D or 2D arrays is made statically at compile time.
3. What is dynamic allocation for representing a binary tree?
Ans:
Dynamic allocation means that the memory allocation for representing the binary tree
using linked list is made dynamically at run time.

4. What is the use of a binary tree?


Ans:
Binary trees are used in search techniques, such as binary search. Binary trees designed
for binary search are called binary search trees.
Binary search trees have the following characteristics:
 The data key in the left child node needs to be smaller than or equal to the data key
of its parent node.
 The data key in the right child node needs to be greater than or equal to the data key
of its parent node.

5. What conditions are required to make a binary tree a complete binary tree?
Ans:
Two conditions that are required to make a binary tree of depth d a complete binary tree
are:
 Any node at level less than d -1 has two children.
 Any node in the tree with a right child at level d must have a left child and every left
descendant of the parent node either is a leaf at level d or has two children.

Vous aimerez peut-être aussi