Transcript File

Data Structures
Chapter 1Introduction
Mohamed Mustaq.A
Introduction
Overview
•
•
•
•
•
History of algorithms.
Examples of algorithms.
Algorithms vs. programs.
Data structures.
Abstract data types.
1- 2
What is an algorithm?
• An algorithm is a step-by-step procedure for solving a
stated problem.
• For example, consider the problem of multiplying two
numbers. There are many possible algorithms for solving
this problem:
– multiplication using a table (suitable only for small
numbers)
– long multiplication
– multiplication using logarithms
– multiplication using a slide ruler
– binary fixed-point or floating-point multiplication (in a
computer).
1- 3
Algorithms History
• Euclid (~ 300 BCE), Eratosthenes (~ 200 BCE)
– arithmetic, geometric algorithms.
• al Khwarizmi (~ 800)
– arithmetic, algebraic, geometric algorithms.
• Napier (~ 1600)
– arithmetic using logarithms.
• Newton (~ 1700)
– differentiation, integration.
• Turing (~ 1940)
– code breaking, solvability.
1- 4
Example: finding a midpoint (1)
• Midpoint algorithm:
To find the midpoint of a given straight-line segment AB:
1. Draw intersecting circles of equal radius, centered at A
and B respectively.
2. Let C and D be the points where the circles intersect.
3. Draw a straight line between C and D.
4. Let E be the point where CD intersects AB.
5. Terminate with answer E.
• Could be performed by a human equipped with drawing
instruments.
1- 5
Example: finding a midpoint (2)
• Animation:
1. Draw intersecting circles
of equal radius, centered
at A and B respectively.
2. Let C and D be the
points where the circles
intersect.
3. Draw a straight line
between C and D.
4. Let E be the point
where CD intersects AB.
5. Terminate with answer
E.
A
D
E
C
B
1- 6
Example: GCDs (1)
• The greatest common divisor (GCD) of two positive
integers is the largest integer that exactly divides both. E.g.,
the GCD of 77 and 21 is 7.
• Euclid’s GCD algorithm:
To compute the GCD of positive integers m and n:
1. Set p to m, and set q to n.
2. Until q exactly divides p, repeat:
2.1. Set p to q, and set q to (p modulo q).
3. Terminate with answer q.
• Could be performed by a human, perhaps equipped with
calculator.
1- 7
Example: GCDs (2)
• Animation:
To compute the GCD of positive integers m and n:
1. Set p to m, and set q to n.
2. Until q exactly divides p, repeat:
2.1. Set p to q, and set q to (p modulo q).
3. Terminate with answer q.
m 77
n 21
p 14
77
21
q 14
21
7
1- 8
Example: GCDs (3)
• Implementation in C++:
// gcd() Calculates the Great Common Divisor of two positive integers
int gcd(int m, int n)
{
int p = m, q = n;
while (p % q != 0) {
int r = p % q;
p = q;
q = r;
}
return q;
}
Example: GSD.cpp
1- 9
Example: square roots (1)
• The positive square root of a positive number a is
the positive number r such that r2 = a.
• Square-root algorithm:
To compute approximately the positive square root
of a positive number a:
1. Set r to the mean of 1 and a.
2. For a few iterations (e.g. 10):
2.1 Set r to the mean of r and a/r (r = (r+a/r)/2).
3. Terminate with answer r.
• Could be performed by a human, perhaps equipped
with log tables or a calculator.
1- 10
Example: square roots (2)
• Animation:
To compute approximately the positive square root
of a positive number a:
1. Set r to the mean of 1 and a.
2 is iterations
2. For
Untila rfew
approximately
(e.g. 10):
equal to a, repeat:
2.1 Set r to the mean of r and a/r.
3. Terminate with answer r.
a
2.0
r 1.414
1.417
1.5
1- 11
Example: square roots (3)
• Implementation in C++:
float sqrt2 (float a) {
// Compute approximately the positive square
// root of positive number a.
float r = (1.0 + a)/2;
for (int i = 0; i < 10; i++)
r = (r + a/r)/2;
return r;
}
Example: SQRT2.cpp
1- 12
Algorithms vs. programs (1)
• Algorithms:
– can be performed by humans or machines
– can be expressed in any suitable language
– may be as abstract as we like.
• Programs:
– must be performed by machines
– must be expressed in a programming language
– must be detailed and specific.
1- 13
Algorithms vs. programs (2)
• Algorithms are expressed in (precise) English.
• Steps may be numbered consecutively:
Do this and then do that.
1. Do this.
2. Do that.
• The extent of a conditional is indicated by indentation:
7. If …:
7.1. Do this.
Do this and then do that, but
7.2. Do that.
only if condition … is true.
• The extent of a loop is indicated by indentation:
8. While …, repeat:
Do this and then do that, as
8.1. Do this.
long as condition … is true.
8.2. Do that.
1- 14
Algorithms vs. programs (3)
• If we wish to use the algorithm on a computer, we
must first code it in a programming language.
• There may be many ways of coding the algorithm,
and there is a wide choice of programming
languages. But all the resulting programs are
implementations of the same underlying algorithm.
• Here we express our implementations in C++.
(Alternatives would be C, Pascal, Java, etc.)
1- 15
Data structures
• A data structure is a systematic way of
organizing a collection of data.
• A static data structure is one whose capacity is
fixed at creation.
E.g.: array.
• A dynamic data structure is one whose capacity
is variable, so it can expand or contract at any time.
E.g.: linked list, binary tree.
• For each data structure we need algorithms for
insertion, deletion, searching, etc.
1- 16
Example: representing strings
• Possible data structures to represent the string “Hany”:
0
Array:
Linked list:
1
2
3
4
‘H’ ‘a’ ‘n’ ‘y’ ‘\n’
‘H’
‘a’
‘n’
‘y’
1- 17
Example: representing sets
• Possible data structures to represent the set of words
{bat, cat, mat, rat, sat}:
(Sorted)
array:
(Sorted)
linked list:
Binary
search
tree:
0
1
2
3
4
bat
cat
mat
rat
sat
bat
cat
5
mat
6
rat
7
sat
cat
bat
rat
mat
sat
1- 18
Abstract data types
• When we write application code, we don’t care how strings
are represented: we just declare variables of type String,
and manipulate them using String operations.
• Similarly, we don’t care how sets are represented: we just
declare variables of type Set, and manipulate them using
Set operations.
• An abstract data type is a data type whose representation
is of no concern to, and is hidden from the application code.
Examples: String, Set.
• Abstract data types are an excellent way to design large
programs.
1- 19
Preconditions and Postconditions
• An important topic:
preconditions and
postconditions.
• They are a method of specifying
what a function accomplishes.
1- 20
Preconditions and Postconditions
Frequently a programmer must
communicate precisely what a function
accomplishes, without any indication of
how the function does its work.
1- 21
Example
• A head of a
programming team
wants one of his
programmers to write a
function for part of a
project.
THE HEAD OF THE TEAM
PROVIDES THE
PROGRAMER THE
FUNCTION
REQUIREMENTS TO
WRITE (what the
function must
accomplish)
THE HEAD OF THE TEAM
DOESN'T CARE
WHAT METHOD THE
FUNCTION USES,
AS LONG AS THESE
REQUIREMENTS
ARE MET (doesn’t
care
how a function works)
1- 22
What are Preconditions and
Postconditions?
• One way to specify such requirements is with a
pair of statements about the function.
• The precondition statement indicates what
must be true before the function is called.
• The postcondition statement indicates what
will be true when the function finishes its
work.
• The two statements work together.
1- 23
Example
void write_sqrt( double x)
// Precondition: x >= 0.
// Postcondition: The square root of x has
// been written to the standard output.
...
1- 24
Example
void write_sqrt( double x)
{
// Precondition: x >= 0.
// Postcondition: The square root of x has
// been written to the standard output.
• The precondition and postcondition
appear as comments in your
program.
...
}
1- 25
Example
void write_sqrt( double x)
{
// Precondition: x >= 0.
// Postcondition: The square root of x has
// been written to the standard output.
• In this example, the precondition
requires that
x >= 0
be true whenever the function is
called.
}
...
1- 26
Example
Which of these function calls
meet the precondition ?
write_sqrt( -10 );
write_sqrt( 0 );
write_sqrt( 5.6 );
1- 27
Example
Which of these function calls
meet the precondition ?
write_sqrt( -10 );
write_sqrt( 0 );
write_sqrt( 5.6 );
The second and third calls are fine, since
the argument is greater than or equal to zero.
1- 28
Example
Which of these function calls
meet the precondition ?
write_sqrt( -10 );
write_sqrt( 0 );
write_sqrt( 5.6 );
But the first call violates the precondition,
since the argument is less than zero.
1- 29
Example
void write_sqrt( double x)
// Precondition: x >= 0.
// Postcondition: The square root of x has
// been written to the standard output.
• The postcondition always indicates
what work the function has
accomplished, in this case, when
the function returns the square root
of x has been written.
...
}
1- 30
Another Example
bool is_vowel( char letter )
// Precondition: letter is an uppercase or
// lowercase letter (in the range 'A' ... 'Z' or 'a' ... 'z') .
// Postcondition: The value returned by the
// function is true if Letter is a vowel;
// otherwise the value returned by the function is
// false.
...
1- 31
Another Example
What values will be returned
by these function calls ?
is_vowel( 'A' );
is_vowel( 'Z' );
is_vowel( '?' );
1- 32
Another Example
What values will be returned
by these function calls ?
is_vowel( 'A' );
is_vowel( 'Z' );
is_vowel( '?' );
true
false
Nobody knows, because the
precondition has been violated.
(might return true, or it might
return false)
1- 33
Another Example
What values will be returned
by these function calls ?
is_vowel( '?' );
Violating the precondition
might even crash the computer.
1- 34
Careful programmers follow these rules:
• When you write a function, you should make
every effort to detect when a precondition has
been violated.
• If you detect that a precondition has been
violated, then
– print an error message, and
– halt the program.
1- 35
Careful programmers follow these rules:
• When you write a function, you should
make every effort to detect when a
precondition has been violated.
• If you detect that a precondition has been
violated, then
– print an error message, and
– halt the program...
• ...rather than causing a disaster.
1- 36
Example
void write_sqrt( double x)
// Precondition: x >= 0.
// Postcondition: The square root of x has
// been written to the standard output.
{
assert(x >= 0);
...
A function can be used to ensure
that a precondition is not violated.
The C++ assert() function is useful
for detecting violations of a
precondition, prints a message, and
then halts the program.
1- 37