algorithm design II - Copy_021021
algorithm design II - Copy_021021
Computer hardware refers to the physical parts the computer such as monitor, keyboard,
CPU, hard disk … Software refers to the set of instructions called program that directs the
hardware. Programs are written to solve problems or carry out tasks on the computer,
program is like the translation of the various steps to solve a problem or carry out tasks
called algorithm into a language that the computer can understand. So as we are thinking of
an algorithm, we must keep in mind that the computer will only do what we instruct it to do.
Therefore we must know the computer problem solving approach.
The first step in writing instructions to carry out a task with the computer is to determine
what the output should be, that is exactly what the task should produce.
The second step is to identify the data input required for obtaining the output.
The third step is to determine how to process the inputs in order to obtain the desired
output. That is to determine what formula, method, way or steps that can be used to obtain
the output.
The problem solving approach should be adopted each time we are looking for the algorithm
that produces a solution of problem.
Example: A car travels 150km in 2h. How fast is the car moving?
Output: speed
Input: distance, time
Processes: Ask for the distance and time, set the speed to: distance/time, display the speed.
1. Read the problem carefully until you understand what the algorithm should do and
have the clear idea of the output.
2. Apply the problem solving approach that is determine the output, the input and
processes, methods, ways or steps to apply for solving the problem.
3. Implement the chosen processes to solve the problem while respecting the
conditions, if there is any.
4. Test the algorithm, that is try the algorithm with the exact or some randomly values
to ensure the correctness and the effectiveness of the algorithm.
1. input: there must be zero or more quantities which are externally supplied;
2. output: at least one quantity must be produced;
3. definiteness: each instruction must be clear and unambiguous;
4. finiteness: if we trace out the instructions of an algorithm, then for all cases the
algorithm will terminate after a finite number of steps;
5. Effectiveness: every instruction must be sufficiently basic that it can in principle be
carried out by a person using only pencil and paper. It is not enough that each
operation be definite, but it must also be feasible.
An algorithm can be expressed in a variety of notations. The common ones are: Natural
languages, pseudo codes and flowchart.
a) Natural language.
A natural language is a human written or spoken language used by a community. Natural
language expressions of algorithms are rarely used for complex or technical processes.
Below is an algorithm (in natural language) which collects two numbers , sum up the
numbers , finds the difference of the numbers and then displays both the sum and the
difference of the numbers.
b) FLOWCHARTS
A flowchart is a diagrammatic or symbolic representation that illustrates the sequence of
operations to be performed to get the solution of a problem, using symbols called charts and
arrows. These charts play a vital role in the programming of the problem and are quite
helpful in understanding the logic of complicated and lengthy problems. In flowcharts,
symbols are used to represent activities while arrows to represent the direction of activity
through the process. Typical examples of these symbols include the following:
Terminal symbol, oval shape, it Indicates the starting or ending of the program, process, or
interrupt program.
Process symbol, a rectangle, it indicates any type of internal operation inside the
Processor or Memory
Decision symbol, the diamond represents a decision branching point or a question that can
be answered in a binary format (Yes/No, True/False)
Connector symbol, the circle allows the flowchart to be drawn without intersecting lines or
without a reverse flow. It also indicates that the flow continues where a matching symbol
(containing the same letter) has been placed.
Off-page-connector, used to indicate that the flowchart continue in the next page
Example: let us use the flowchart to write an algorithm to perform the summation of two
numbers a and b , taking from the user.
start A
sum=a+b
write (a,b)
write (sum )
read (a,b)
A end
c) Pseudo codes
Unlike a flowchart which is a graphic-based tool, pseudo codes are text-based algorithmic
design tools. In other words, a pseudo code is a way of writing an algorithm using short
natural language statements that are similar to programming language statements. Each
statement here expresses just an action or a step that the computer has to carry out in
performing the task. With pseudo codes every algorithm must start with the keyword
“Algorithm”, following by the name you have chosen for the algorithm, and must end by the
keyword “end”, the general syntax is :
Algorithem name-of –the-algorithm
Var variable1,variable2 (as types)
Begin
statment1
statment2
statment2
end.
This is the value that object contains at the end of its use in the algorithm.
g) The meaning of the variable.
It is advisable to indicate in a short sentence the role of each variable in the algorithm. It
can be a comment.
b) Real
Real numbers take their values in a finite set of integers and decimals. The operators
allowed on real are:
Division (/)
All others operators above can be applied on real
c) Characters
These are symbols used to represent words or phrases in natural languages. Each of
these symbols is represented in the computer by an 8 bits code known as ASCII
(American Standard Code for Information Interchange). We distinguish alphabetic,
numeric and special character. A constant character is written in single quote.
d) Boolean
A Boolean expression is an expression that yields two possible results (that is TRUE or
FALSE). On such object, possible logical operator like AND, OR and NOT can be
performed.
Display the value of a variable on an output device (like the monitor) using the
keyword Write
e.g Write (“enter the value of a ”)
b) CONDITIONAL BRANCHING IF
This structure chooses a single subtask from a list of one or more alternatives others
according to the prescribed condition. A condition is an expression that yields Boolean
results (that is “TRUE” or “FALSE”). The relational operators used to express condition are:
Endif.
Exercise : represent the flow chart of this syntax.
Exercise ; write an algorithm to computer and display the solution of the equation : ax+b=0.
2nd form
If (condition) then
Statement1
Else
Statement2
End if
Here the condition is evaluated, if it is true, the statement1 is executed and if it is false,
statements2 is executed.
Exercise: represent the flow chart of this syntax and write the algorithm to compute the
absolute value of an integer. The write an algorithm that reads two integers and displays
their maximum.
Exercise write an algorithm that request for the coefficients a, b and c of the second
quadratic equation ax2+bx+c=0 , then compute the solution of the equation.
Exercise write an algorithm that a binary digit and display it in letter. Write an algorithm
that reads a positive integer corresponding to the number of a day within the week,
compute and displays the day’s name in full.
Exercise : write an algorithm that reads the average of a student and displays the grade . the
grades are assigned as follows:
100% : excellent, greater than or equal to 90% : very good, greater than or equal to 80% :
good, greater than or equal to 60%: fairly good, greater than or equal to 50%: average,
greater than or equal to : fail.
In this loop, the condition is evaluated, if it is true then, “statement” is executed, condition
is reevaluated and the cycle continues, until condition becomes false, which mean the end of
the loop.
Exercise: draw the flowchart of the above loop. Write an algorithm which reads a positive
integer n and then compute and display the sum of the first n integers.
Repeat
Statement
Until (condition)
In this loop, the statement is executed and the condition is evaluated, if the condition is false
, then statement is executed again , and the cycle continue until the condition becomes true,
it is the end of the loop.
Exercise : draw the flowchart of this loop and write an algorithm that reads a positive integer
n, compute and displays its square root.
Write an algorithm that reads a sequence of positive values, computes and displays the sum,
the number of values, the minimum , the maximum, the average , the variance and the
standard deviation. You may indicate the end of the sequence by a negative or null value.
c) FOR LOOP
Syntax
For counter from start_value to stop_value
Statements
Endfor
Here , statement will be executed for a value of counter from start_value to stop_value. The
for loop is used when the number of iteration is known in advance.
Exercise draw the flowchart of the For loop and write an algorithm that read a number n,
computes and displays its factorial.
Write an algorithm that requests for a positive integer n, computes and displays the sum of
its factors.
CHAPTER TWO
Candidate := record
Candidate_number: integer
Candidate_namer: String
Candidate_mark: real
Endrecord
In this example the word candidate is the record name and Candidate_number is a
record’s field.
d) Linked Lists
A finite set of entries with a certain order is known as a list. Two common forms of list
data structures are list linked list and arrays. A linked list is a data structure consisting of
a number of nodes, each containing one element and one or more links to others nodes.
Linked list permit insertion and removal of nodes at any point of the list. Linked list do no
allow random access
e) Queue
In computer science, a queue (/ˈkjuː/ KEW) is a particular kind of abstract data type or
collection in which the entities in the collection are kept in order and the principal (or
only) operations on the collection are the addition of entities to the back terminal
position, known as enqueue, and removal of entities from the front terminal position,
known as dequeue. This makes the queue a First-In-First-Out (FIFO) data structure. In a
FIFO data structure, the first element added to the queue will be the first one to be
removed. This is equivalent to the requirement that once a new element is added, all
elements that were added before have to be removed before the new element can be
removed.
f) Stalk
In computer science, a stack is a particular kind of data structure or collection in which
the principal (or only) operations on the collection are the addition of an entity to the
collection, known as push and removal of an entity, known as pop. The relation between
the push and pop operations is such that the stack is a Last-In-First-Out (LIFO) data
structure. In a LIFO data structure, the last element added to the structure must be the
first one to be removed. This is equivalent to the requirement that, considered as a
linear data structure, or more abstractly a sequential collection, the push and pop
operations occur only at one end of the structure, referred to as the top of the stack. G)
g) Trees
In computer science, a tree is a type of data structure in which each element is attached
to one or more elements directly beneath it. The elements of this hierarchical data
structure are called nodes. The node which at the top of the tree is called root and the
node with no children is called leaf.
h) Tables
A table is a group of records, each of which is composed of fields common to all the
other records. The main purpose of this data structure is to improve data access by
reducing search time.
i) Files
A file is made up of one or more tables.
TUTORIAL ONE
Tutorials on algorithms
Conational structures
Use the conditional structure if or case to answer each of the following questions
1. Write an algorithm to accept two integers and check whether they are equal or not
5. Write an algorithm to read the age of a Cameroonian and determine whether it is eligible
for casting his/her own vote.
7. Write an algorithm to accept the height of a person in centimeter and categorize the person
according to their height.
10. Write an algorithm to find the eligibility of admission for a professional course based on
the following criteria:
Marks in Maths >=65
Marks in Phy >=55
Marks in Chem>=50
Total in all three subject >=180
or
Total in Math and Subjects >=140
12. Write an algorithm to read roll number, name and marks of three subjects and calculate
the total and the average of the student.
13. Write a an algorithm to read temperature in centigrade and display a suitable message
according to temperature state below :
Temp < 0 then Freezing weather
Temp 0-10 then Very Cold weather
Temp 10-20 then Cold weather
Temp 20-30 then Normal in Temp
Temp 30-40 then Its Hot
Temp >=40 then Its Very Hot
19. Write an algorithm to calculate and print the Electricity bill of a given customer. The
customer id., name and unit consumed by the user should be taken from the keyboard and
display the total amount to pay to the customer. The charge are as follow :
Unit Charge/unit
Up to 199 120
200 and above but less than 400 150
400 and above but less than 600 180
600 and above 200
20. Write a program in C to accept a grade and declare the equivalent description :
Grade Description
E Excellent
V Very Good
G Good
A Average
F Fail
21. Write an algorithm to read any day number in integer and display day name in the word.
22. Write an algorithm to read any digit, display in the word.
23. Write an algorithm to read any Month Number in integer and display Month name in the
word
24. Write an algorithm to read any Month Number in integer and display the number of days
for this month.
25. Write an algorithm which is a Menu-Driven Program to compute the area of the various
geometrical shape.
Loops
Use the For loop, the while and the repeat until loop to answer the following questions
4. Write an algorithm to read 10 numbers from keyboard and find their sum and average.
1) Greedy Algorithms
Greedy algorithms try to find a localized optimum solution, which may eventually lead to
globally optimized solutions. However, generally greedy algorithms do not provide globally
optimized solutions.
Counting Coins
This problem is to count to a desired value by choosing the least possible coins and the greedy
approach forces the algorithm to pick the largest possible coin. If we are provided coins of ₹
1, 2, 5 and 10 and we are asked to count ₹ 18 then the greedy procedure will be −
Though, it seems to be working fine, for this count we need to pick only 4 coins. But if we
slightly change the problem then the same approach may not be able to produce the same
optimum result.
For the currency system, where we have coins of 1, 7, 10 value, counting coins for value 18
will be absolutely optimum but for count like 15, it may use more coins than necessary. For
example, the greedy approach will use 10 + 1 + 1 + 1 + 1 + 1, total 6 coins. Whereas the same
problem could be solved by using only 3 coins 7+7+1
Hence, we may conclude that the greedy approach picks an immediate optimized solution and
may fail where global optimization is a major concern.
Examples
Most networking algorithms use the greedy approach. Here is a list of few of them −
There are lots of similar problems that uses the greedy approach to find an optimum solution.
In divide and conquer approach, the problem in hand, is divided into smaller sub-problems
and then each problem is solved independently. When we keep on dividing the subproblems
into even smaller sub-problems, we may eventually reach a stage where no more division is
possible. Those "atomic" smallest possible sub-problem fractions are solved. The solution of
all sub-problems is finally merged in order to obtain the solution of an original problem.
Broadly, we can understand divide-and-conquer approach in a three-step process.
Divide/Break
This step involves breaking the problem into smaller sub-problems. Sub-problems should
represent a part of the original problem. This step generally takes a recursive approach to
divide the problem until no sub-problem is further divisible. At this stage, sub-problems
become atomic in nature but still represent some part of the actual problem.
Conquer/Solve
This step receives a lot of smaller sub-problems to be solved. Generally, at this level, the
problems are considered 'solved' on their own.
Merge/Combine
When the smaller sub-problems are solved, this stage recursively combines them until they
formulate a solution of the original problem. This algorithmic approach works recursively and
conquer & merge steps works so close that they appear as one.
Examples
Merge Sort
Quick Sort
Binary Search
Strassen's Matrix Multiplication
Closest pair points
There are various ways available to solve any computer problem, but the mentioned are a
good example of divide and conquer approach.
3) Dynamic Programming
Dynamic programming approach is similar to divide and conquer in breaking down the
problem into smaller and yet smaller possible sub-problems. But unlike, divide and conquer,
these sub-problems are not solved independently. Rather, results of these smaller sub-
problems are remembered and used for similar or overlapping sub-problems.
Dynamic programming is used where we have problems, which can be divided into similar
sub-problems, so that their results can be re-used. Mostly, these algorithms are used for
optimization. Before solving the in-hand sub-problem, dynamic algorithm will try to examine
the results of the previously solved sub-problems. The solutions of sub-problems are
combined in order to achieve the best solution.
Comparison
In contrast to divide and conquer algorithms, where solutions are combined to achieve an
overall solution, dynamic algorithms use the output of a smaller sub-problem and then try to
optimize a bigger sub-problem. Dynamic algorithms use memorization to remember the
output of already solved sub-problems.
Example
The following computer problems can be solved using dynamic programming approach −
Dynamic programming can be used in both top-down and bottom-up manner. And of course,
most of the times, referring to the previous solution output is cheaper than recomputing in
terms of CPU cycles.
a) A top-down design
A top-down approach (also known as stepwise design) is essentially the breaking down of a
system to gain insight into the sub-systems that make it up. In a top-down approach an
overview of the system is formulated, specifying but not detailing any first-level subsystems.
Each subsystem is then refined in yet greater detail, sometimes in many additional
subsystem levels, until the entire specification is reduced to base elements. Once these base
elements are recognized then we can build these as computer modules. Once they are built
we can put them together, making the entire system from these individual components.
top-down approach starts by identifying the major components of the system, decomposing
them into their lower-level components and iterating until the desired level of detail is
achieved. Most design methodologies are based on the top-down approach.
A top-down approach is suitable only if the specifications of the system are clearly known
and the system development is from scratch. However, if a system is to be built from an
existing system, a bottom-up approach is more suitable, as it starts from some existing
components.
b) A bottom-up design
A bottom-up design approach starts with designing the most basic or primitive components
and proceeds to higher-level components that use these lower-level components.
Suppose X is an algorithm and n is the size of input data, the time and space used by the
algorithm X are the two main factors, which decide the efficiency of X.
Time Factor − Time is measured by counting the number of key operations such as
comparisons in the sorting algorithm.
Space Factor − Space is measured by counting the maximum memory space required
by the algorithm.
The complexity of an algorithm fn gives the running time and/or the storage space required by
the algorithm in terms of n as the size of input data.
Space Complexity
Space complexity of an algorithm represents the amount of memory space required by the
algorithm in its life cycle. The space required by an algorithm is equal to the sum of the
following two components −
A fixed part that is a space required to store certain data and variables, that are
independent of the size of the problem. For example, simple variables and constants
used, program size, etc.
A variable part is a space required by variables, whose size depends on the size of the
problem. For example, dynamic memory allocation, recursion stack space, etc.
Time Complexity
Time complexity of an algorithm represents the amount of time required by the algorithm to
run to completion. Time requirements can be defined as a numerical function Tn, where Tn
can be measured as the number of steps, provided each step consumes constant time.
For example, addition of two n-bit integers takes n steps. Consequently, the total
computational time is Tn = c ∗ n, where c is the time taken for the addition of two bits. Here,
we observe that Tn grows linearly as the input size increases.
Asymptotic Analysis
Asymptotic Notations
Following are the commonly used asymptotic notations to calculate the running time
complexity of an algorithm.
Ο Notation
Ω Notation
θ Notation
Big Oh Notation, Ο
The notation Οn is the formal way to express the upper bound of an algorithm's running time.
It measures the worst case time complexity or the longest amount of time an algorithm can
possibly take to complete.
Omega Notation, Ω
The notation Ωn is the formal way to express the lower bound of an algorithm's running time.
It measures the best case time complexity or the best amount of time an algorithm can
possibly take to complete.
Theta Notation, θ
The notation θn is the formal way to express both the lower bound and the upper bound of an
algorithm's running time. It is represented as follows −
constant Ο1
logarithmic Οlogn
linear Οn
n log n Οnlogn
quadratic Ο(n2)
cubic Ο(n3)
polynomial nΟ1
exponential 2Οn
Linear search is a very simple search algorithm. In this type of search, a sequential search is
made over all items one by one. Every item is checked and if a match is found then that
particular item is returned, otherwise the search continues till the end of the data collection.
Algorithm
Step 1: Set i to 1
Step 2: if i > n then go to step 7
Step 3: if A[i] = x then go to step 6
Step 4: Set i to i + 1
Step 5: Go to Step 2
Step 6: Print Element x Found at index i and go to step 8
Step 7: Print element not found
Step 8: Exit
Pseudocode
end if
end for
end procedure
Binary search is a fast search algorithm with run-time complexity of Οlogn. This search
algorithm works on the principle of divide and conquers. For this algorithm to work properly,
the data collection should be in the sorted form.
Binary search looks for a particular item by comparing the middle most item of the collection.
If a match occurs, then the index of item is returned. If the middle item is greater than the
item, then the item is searched in the sub-array to the left of the middle item. Otherwise, the
item is searched for in the sub-array to the right of the middle item. This process continues on
the sub-array as well until the size of the subarray reduces to zero.
Binary search halves the searchable items and thus reduces the count of comparisons to be
made to very less numbers.
Pseudocode
Procedure binary_search
A ← sorted array
n ← size of array
x ← value to be searched
Set lowerBound = 1
Set upperBound = n
if A[midPoint] < x
set lowerBound = midPoint + 1
if A[midPoint] > x
set upperBound = midPoint - 1
if A[midPoint] = x
EXIT: x found at location midPoint
end while
end procedure
Sorting refers to arranging data in a particular format. Sorting algorithm specifies the way to
arrange data in a particular order. Most common orders are in numerical or lexicographical
order.
The importance of sorting lies in the fact that data searching can be optimized to a very high
level, if data is stored in a sorted manner. Sorting is also used to represent data in more
readable formats. Following are some of the examples of sorting in real-life scenarios −
Sorting algorithms may require some extra space for comparison and temporary storage of
few data elements. The algorithms that do not require any extra space and sorting is said to
happen in-place, or for example, within the array itself. This is called in-place sorting.
Bubble sort is an example of in-place sorting.
However, in some sorting algorithms, the program requires space which is more than or equal
to the elements being sorted. Sorting which uses equal or more space is called not-in-place
sorting. Merge-sort is an example of not-in-place sorting.
Selection Sort
The principle of Selection Sort is to find the smallest element of the data sequence (from
index 0 to n-1) and put it to the beginning of the sequence. This procedure is then applied on
the yet unsorted areas (1 to n-1, 2 to n-1 and so on), until the area from n-2 to n-1 has been
sorted.
Selection sort is a simple sorting algorithm. This sorting algorithm is an in-place comparison-
based algorithm in which the list is divided into two parts, the sorted part at the left end and
the unsorted part at the right end. Initially, the sorted part is empty and the unsorted part is the
entire list.
The smallest element is selected from the unsorted array and swapped with the leftmost
element, and that element becomes a part of the sorted array. This process continues moving
unsorted array boundary by one element to the right.
This algorithm is not suitable for large data sets as its average and worst case complexities are
of Ο(n2), where n is the number of items.
. Algorithm
Pseudocode
for i = 1 to n - 1
/* set current element as minimum*/
min = i
for j = i+1 to n
if list[j] < list[min] then
min = j;
end if
end for
end for
end procedure
Insertion Sort
This is an in-place comparison-based sorting algorithm. Here, a sub-list is maintained which
is always sorted. For example, the lower part of an array is maintained to be sorted. An
element which is to be 'insert'ed in this sorted sub-list, has to find its appropriate place and
then it has to be inserted there. Hence the name, insertion sort.
The array is searched sequentially and unsorted items are moved and inserted into the sorted
sub-list in the same array. This algorithm is not suitable for large data sets as its average and
worst case complexity are of Ο(n2), where n is the number of items.
Algorithm
Now we have a bigger picture of how this sorting technique works, so we can derive simple
steps by which we can achieve insertion sort.
Pseudocode
end for
end procedure
Algorithm
We assume list is an array of n elements. We further assume that swap function swaps the
values of the given array elements.
begin BubbleSort(list)
return list
end BubbleSort
Pseudocode
We observe in algorithm that Bubble Sort compares each pair of array element unless the
whole array is completely sorted in an ascending order. This may cause a few complexity
issues like what if the array needs no more swapping as all the elements are already
ascending.
To ease-out the issue, we use one flag variable swapped which will help us see if any swap
has happened or not. If no swap has occurred, i.e. the array requires no more processing to be
sorted, it will come out of the loop.
loop = list.count;
end for
end for
end procedure return list
Merge sort is a sorting technique based on divide and conquer technique. With worst-case
time complexity being Οnlogn, it is one of the most respected algorithms.
Merge sort first divides the array into equal halves and then combines them in a sorted
manner.
Algorithm
Merge sort keeps on dividing the list into equal halves until it can no more be divided. By
definition, if it is only one element in the list, it is sorted. Then, merge sort combines the
smaller sorted lists keeping the new list sorted too.
Pseudocode
We shall now see the pseudocodes for merge sort functions. As our algorithms point out two
main functions − divide & merge.
Merge sort works with recursion and we shall see our implementation in the same way.
l1 = mergesort( l1 )
l2 = mergesort( l2 )
var c as array
return c
end procedure
To know about merge sort implementation in C programming language, please click here.
Quick Sort
Quick sort is a highly efficient sorting algorithm and is based on partitioning of array of data
into smaller arrays. A large array is partitioned into two arrays one of which holds values
smaller than the specified value, say pivot, based on which the partition is made and another
array holds values greater than the pivot value.
Quick sort partitions an array and then calls itself recursively twice to sort the two resulting
subarrays. This algorithm is quite efficient for large-sized data sets as its average and worst
case complexity are of Οnlogn, where n is the number of items.
Partition in Quick Sort
Following animated representation explains how to find the pivot value in an array.
The pivot value divides the list into two parts. And recursively, we find the pivot for each sub-
lists until all lists contains only one element.
Based on our understanding of partitioning in quick sort, we will now try to write an
algorithm for it, which is as follows.
while True do
while A[++leftPointer] < pivot do
//do-nothing
end while
end while
swap leftPointer,right
return leftPointer
end function
Using pivot algorithm recursively, we end up with smaller possible partitions. Each partition
is then processed for quick sort. We define recursive algorithm for quicksort as follows −
To get more into it, let see the pseudocode for quick sort algorithm −
if right-left <= 0
return
else
pivot = A[right]
partition = partitionFunc(left, right, pivot)
quickSort(left,partition-1)
quickSort(partition+1,right)
end if
end procedure