You are on page 1of 38

CO1401

Programming

Week 7
Algorithms, Binary Search
Algorithms

• An algorithm is a step-by-step description of how to


solve a problem.
• It is a formula or procedure for solving a problem.
• A central element of programming is algorithms,
• e.g. searching, sorting, AI algorithms...
• They sit alongside another central concern of
programming: data structures
• e.g. stacks, linked lists, binary trees....

2 Programming
Algorithms

• An algorithm is a step-by-step guide to solving a


problem.
• It is a solution.
• We use a lot of algorithms.
• They are comparatively formal.
• Assume that they are correct. Do not modify a given
algorithm. So no arbitrary changing of an algorithm.
• Some have formal proofs, i.e. a formal
mathematical proof.
• Some have experimental proofs.
• Long tradition of use.
• There are variants.
3 Programming
Efficiency

• Implementation is different from algorithm.


• We saw this in the previous lecture when I talked
about different ways to implement a linear search.
• The implementation is important.
• There are good and poor implementations of an
algorithm.
• An implementation could have bugs.
• Implementations differ as to their efficiency.
• We can also optimise code: rewrite code to improve
efficiency.

4 Programming
Efficiency and Algorithms

• However, algorithms can be judged by efficiency:

• Speed
• Memory

• For example, it is possible to say that, given an


ordered list, the "binary search" algorithm is faster
than the "linear search" algorithm.
• On average...
• This estimation of efficiency is independent of
implementation.

5 Programming
Measuring Algorithms - Linear Search

• The algorithm itself can be judged for efficiency.


• The best way to do this is to look at the number of
apparent steps in the algorithm. How many steps or
operations does it call for?

• What this is describing is resource use.

• We're going to start by examining the "Linear search"


algorithm.

6 Programming
Measuring Algorithms - Linear Search

• Need to be careful about stating any assumptions. The


context may have a big effect upon things.
• Important:
• I will assume that the item is in the list.
• I will also assume that each item on the list is
equally likely to be the value we're looking for.

7 Programming
Description of the algorithm

• The aim of the algorithm is to find a particular value in


the list (or array).
• Start at the beginning and then go through to the end of
the array.
• Check each of the elements of the array one at a time.
• Return the index of search term (if it is found - we're
assuming that the item is on the list).

• Looked at efficiency gains in the last lecture.


• Obviously more efficient to stop as soon as the search
term has been found.
• Let's consider the efficiency of the better version.
8 Programming
How to measure Efficiency

• It is common to consider
• best case: what's the best thing that could happen.
The best performance.
• worst case: what the worst thing that could
happen. The worst performance.
• average case: on average what happens. We
consider performing the search time and time
again. We then calculate what happens when we
average all of the tests out.
• Our measurement will be the number of times that
we have to examine the list.

9 Programming
Efficiency of linear search

• We've got an equal


chance of finding
the value at any
location.
• So we'd examine the
list 1, 2 or 3 times

1+2+3=6
6/3=2

• On average we find
the number the
second time we
examine the list
10 Programming
Efficiency of linear search

11 Programming
Binary search

• Let's compare this with another (and better) algorithm.


• Again, I will assume that the item is in the list and that
each item on the list is equally likely to be the value
we're looking for.

• Binary search only works on ordered lists.


• Binary search is a divide and conquer algorithm.
• We engage in a process of halving the list. Each time we
halve the number of items to be checked.

12 Programming
• The algorithm is quite simple in concept.
• Searching for a value in an ordered list. An example of an
ordered list would be a telephone directory or dictionary.

• First Pass: Open the directory at the half way point and
choose a word from the page.
• If our target (the search term) is alphabetically lower
than the chosen word then our target must be in the
first half of the directory.
• If our target is alphabetically higher than the chosen
word then our target must be in the second half of the
directory.

13 Programming
• Let's say it was in the first half of the directory.
• Second Pass: Using just the first half of the directory,
divide it into two and choose another word.
• Again if our target is alphabetically lower than the
chosen the word then our target must be in the first half
of the section. (In other words, in the first quarter of the
whole directory).
• If our target is alphabetically higher than the chosen the
word then our target must be in the second half of the
section. (In other words, in the second quarter of the
whole directory).

• Continue the process until we find the target word.


14 Programming
15 Programming
• Another way to think about the algorithm is a
guessing game.
• I'll secretly think of a number between 1 and a 100.
You have to guess what number I've thought of. You
make a guess and I'll tell you "higher" or "lower".
• You make another guess and so on.
• Each time you make a guess the best solution to
choose a number in the middle of the particular
range.
• Each iteration effectively halves the search space.

16 Programming
int BinarySearch(int a[], int low, int high, int target)
{
while (low <= high)
{
int middle = ( low + high ) / 2;
if ( target < a[middle] )
{
high = middle - 1;
}
else if ( a[middle] < target )
{
low = middle + 1;
}
else
{
return middle;
}
}
return -1; // not found, what to do?
}
int main()
{
int arr[10] = { 0, 2, 3, 5, 7, 8, 9, 11, 14, 15 };

cout << BinarySearch( arr, 0, 9, 5 ) << endl;


cout << BinarySearch( arr, 0, 9, 0 ) << endl;
cout << BinarySearch( arr, 0, 9, 15 ) << endl;
cout << BinarySearch( arr, 0, 9, -1 ) << endl;
cout << BinarySearch( arr, 0, 9, 20 ) << endl;
}

18 Programming
• Should check for array bounds at every stage of the
algorithm.
• In every pass of the algorithm we need to divide the
range of elements we're interested in into two, i.e. we
need to find the index half way between a minimum
value and a maximum.

• Advanced: A quick search of web will produce some


articles and discussion about bugs and pitfalls within
the algorithm.
• A potential bug is the fact that (min + max) / 2 could
result in an overflow because of the integer addition.
This would cause the index to be a negative number.
19 Programming
• There is a templated based binary search in the C++
libraries: binary_search()
• #include <algorithm>

• There is also an array based search : bsearch(). Note


you need to use a function pointer to get this to work
• #include <stdlib>

20 Programming
21 Programming
22 Programming
Global variables and constants

23 Programming
• A global variable is a variable whose scope is the whole
of the program.
• Global variables are not considered good practice.
• In order to understand a program you need to know
what the variables are doing. You need to know the
current state of the program.
• This becomes difficult with global variables because
every function could change the state of the program
since every function can change a global variable.

24 Programming
• Constants are not considered variables because their
value is fixed.
• A function cannot use a constant to change the state of
the program.
• Constants may be faster than non-constants.
• For future reference: constants should really be
declared inside a namespace.

25 Programming
C-style character arrays
and printf

26 Programming
• I was struck by how many examples people were finding used
printf.
• It also turns up a lot in the MSDN help files.
• You need to know a little about c-style character arrays in
order to use printf.
• When people talk about strings in the context of printf they
mean the old style C character array.
• This is an array of characters.
• The array is always 1 size longer than the characters in the
character array.
• This extra space is for the addition of a 0 (zero) at the end of
the character array. The last "character" in the array is a 0. It's
called a terminating 0.

27 Programming
character arrays and Arrays

• A c-style character array is held in computer memory


as an array of characters.

str[0] str[1] str[2] str[3] str[4] str[5] str[6] str[7]


‘h’ ‘e’ ‘l’ ‘l’ ‘o’ 0 ? ?

• Note that the null terminator is an the end of the text


not at the end of the array.

28 Programming
character array Elements
• The individual elements of the character array can be
accessed in the same way as normal character
variables.

char str[3];
str[0] = ‘h’;
str[1] = ‘i’;
str[2] = 0;

• The first variable in an array in C++ is always at


position 0. The first character of the character array is
therefore at 0th element of the character array.
29 Programming
Exercise

str[0] str[1] str[2] str[3] str[4] str[5]


‘h’ ‘a’ ‘l’ ‘o’ 0 ‘2’

• What would get printed if you did:

cout << str;


• C++ strings are a class, with lots of associated
methods and useful operators such as = for
assignment.
• The c-style character arrays are not a class.
• You do not have access to any of these nice things.
• In order to do anything similar with c-style character
arrays you need to use the <string.h>.
• Note the use of the .h
• It's not the same as the string header file you've been
using.

31 Programming
• You can initialise c-style character arrays:
char str[10] = "cat";
• You cannot assign values to them in the way you can
with C++ strings. Instead you need to use the function
strcpy:
strcpy( str, "dog" );

• There are a number of functions in "string.h" which


provide c-style character arrays with much of the
same support as the C++ string methods:
int length = strlen( str );

32 Programming
• printf is part of the older way of dealing with strings.
• It is an output function.
• It is not a class.
• The 'f' stands for "formatted", i.e. a function which
does formatted output.
• It does not use the string class.
• It uses old c-style character arrays.

33 Programming
Formatted output - printf

•need a header file


#include <stdio.h>

int printf(char *control_string, ...);

•The control string consists of two types of items:


• characters that will be printed on screen
• format specifiers that define the way the subsequent
argument are displayed
•The format specifiers are substituted by the values you give
in the parameter list on the right.
• format tag
• starts with a %
• %d
• %f
• %c
• %s c-stle string

• escape sequence
• \n newline
• \t tab

35 Programming
Examples

int i = 12;
printf ( "The number is %d.\n", i );
• The number is 12.

char str[10] = "hello";


printf ( "Say %s world.\n", str );
• Say hello world.

char ch = 'k';
printf( "mixed: %c and %d %s!\n", ch, i, str );
• mixed: k and 12 and hello!

36 Programming
Code for example

#include <iostream>
#include "stdio.h"
using namespace std;
int main()
{
int i = 12;
printf ( "The number is %d.\n", i );

char str[10] = "hello";


printf ( "Say %s world.\n", str );

char ch = 'k';
printf( "mixed: %c and %d %s!\n", ch, i, str );
}

37 Programming
Input / Output Functions

•In C++ there are functions called form and scan which
do the same thing as printf and scanf:
• cout.form("%d%s", i, s); // C++
• cin.scan("%d%s", &i, s); // C++

38 Programming

You might also like