algorithms

68
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.

Upload: mukesh-kumar

Post on 26-Nov-2014

11 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Algorithms

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

Page 2: Algorithms

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 0

n

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:

cg (n )

f (n )

n 0 f (n ) = O (g (n )) n

Figure Depicting the O-Notation

Page 3: Algorithms

Ω-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:

cg (n )

f (n )

n 0n

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.

Page 4: Algorithms

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.

Page 5: Algorithms

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:

Page 6: Algorithms

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

Page 7: Algorithms

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

Page 8: Algorithms

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

Page 9: Algorithms

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.

Page 10: Algorithms

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.

Page 11: Algorithms

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.

Page 12: Algorithms

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 per year

Population for an year

Variation in the population between the two vertices connected through the edge

In mathematical expressions

Value Conditions and calculations

Daily temperature report

Temperature for a specific time

Variation in the temperature between the vertices connected through the edge

Page 13: Algorithms

Child-parent relationship

Name of the person Relationship

Organization chart Designation Order or flow

Chemical structure Chemical elements Bonding between the elements

Page 14: Algorithms

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:

Page 15: Algorithms
Page 16: Algorithms

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:

Page 17: Algorithms

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:

Page 18: Algorithms

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.

Page 19: Algorithms

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:

Page 20: Algorithms

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)

}

Page 21: Algorithms

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.

Page 22: Algorithms

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

{

Page 23: Algorithms

code to be executed

} while (condition is satisfied)

Page 24: Algorithms

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,

Page 25: Algorithms

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

Page 26: Algorithms

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

Page 27: Algorithms

else m = c end if else m = a end ifelse if (b<c) if (a<c) m = a else m = c end if else m = b end ifend if

Page 28: Algorithms

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 = 1for (j = n to n - r + 1 in steps of -1 do) //where j is a loop variable

per = per*jend_for Display ' Permutation = ', perb) 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 algorithmfact = 1for (j =1 to r in steps of 1 do) //where j is a loop variablefact = fact*jend_forcomb = per / factDisplay ' 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=truefor (i=2 to n/2 in steps of 1 do) if (n % i =0) prime = false breakend_ifend_forif (prime = true)Display 'Prime number is =', nend_for

Page 29: Algorithms

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 = 0while (number > 0)

n = number % 10 //n denotes a digit extracted from the numbernumber = number / 10new_number = new_number +n new_number= new_number*10

end whilenew_number = new_number/10Display '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 = 0while (number > 0)

n = number%10a(count)=ncount = count+1

end whilehalf = count/2palin = truefor (j=1 to half in steps of 1 and k=count to half in steps of –1 do)

if (a (j)! =a(k))palin = falsebreak

end ifif (palin = true)

Display 'Number is a palindrome'else

Display 'Number is not a palindrome'end if

Page 30: Algorithms

end for

Page 31: Algorithms

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 = 0while (the next character ch in the string is not empty)

a(count) = chcount = count+1

end whilehalf = 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 = falsebreak

end ifif (palin = true)

Display 'String is a palindrome'else

Display 'String is not a palindrome' end ifend 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)?

Page 32: Algorithms

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.

Page 33: Algorithms

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

Page 34: Algorithms

a = a + b

b = a - b

a = a - b

Display 'The values of a and b are ', a, b

Page 35: Algorithms

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.

Page 36: Algorithms

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]

Page 37: Algorithms

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:

Page 38: Algorithms
Page 39: Algorithms

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.

Page 40: Algorithms

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:

Page 41: Algorithms

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.

Page 42: Algorithms

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

Page 43: Algorithms

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.

Page 44: Algorithms

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.

Page 45: Algorithms

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

Page 46: Algorithms

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

Page 47: Algorithms

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}

Page 48: Algorithms

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)

Page 49: Algorithms

((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.

Page 50: Algorithms

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:

Page 51: Algorithms

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.

Page 52: Algorithms

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).

Page 53: Algorithms

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.

Page 54: Algorithms

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:

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.

+

2 3 5

*

Page 55: Algorithms

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 level are fully accommodated before the next level is accommodated.

All levels are maximally accommodated.

Number of nodes at the last (n) level may or may not equal to 2n.

Number of nodes at the last (n) level is exactly equal to 2n.

Leaf nodes may or may not be at the same level.

All leaf nodes are at the same level.

A complete binary tree may or may not be full binary tree.

A full binary tree is always a complete binary tree.

Page 56: Algorithms

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:

Page 57: Algorithms

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.

Page 58: Algorithms

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.