Download presentation source

Download Report

Transcript Download presentation source

CS100A, Fall 1997
Lecture, 11 November:
Searching and sorting
Linear search: Find the position of x in array b.
Need a more specific specification.
How is the result conveyed to the user? What to do if x
occurs several times? What to do if x is not in b?
CS100A, Fall 1997.
Lecture, 11 Nov.
1
Find an integer k that satisfies
0 <= k <= b.length and
x is not in b[0..k-1] and
(k = b.length or x = b[k]
Loop, start at beginning of array. Use invariant:
P: 0 <= k <= b.length and
x is not in b[0..k-1]
0
b.length
x not in here
b
k=
while (
k
;
){
}
CS100A, Fall 1997.
Lecture, 11 Nov.
2
// Yield an integer k that finds the first occurrence
// of x in b, i.e. that satisfies:
//
0 <= k <= b.length and
//
x is not in b[0..k-1] and
//
(k = b.length or x = b[k] )
static public int find ( int x, int [ ] b) {
int k= 0;
/* invariant P: 0 <= k <= b.length and
x is not in b[0..k-1] */
while (k != b.length && b[k] != x)
k= k+1;
return k;
}
0
b
k
b.length
x not in here
CS100A, Fall 1997.
Lecture, 11 Nov.
3
Binary search
Like a search in a telephone directory.
Find x in array b.
Store an integer in k to truthify
b[0..k] <= x < b[k+1..b.length-1]
0
b
k
<= x
b.length
>x
This means that every
value in here is <= x
This means that every
value in here is > x
CS100A, Fall 1997.
Lecture, 11 Nov.
4
Binary search
Store an integer in k to truthify
b[0..k] <= x < b[k+1..b.length-1]
0
k
b.length
<= x
b
>x
invariant:
0
b
k=
k
j
<= x
;
?
j=
>x
;
while (
int e=
b.length
){
;
// -1 <= k < e < j <= b.length
if (b[e] <= x )
else
}
CS100A, Fall 1997.
Lecture, 11 Nov.
5
Binary search
// Binary search for x in array b:
// Yield the integer k that satisfies
//
-1 <= k <= b.length
and
//
b[0..k] <= x < b[k+1..b.length-1]
static public int binarySearch( int x, int [ ] b) {
int k= -1; int j= b.length;
// invariant: -1 <= k < j <= b.length and
b[0..k] <= x < b[j..b.length-1]
while ( k+1 != j ) {
int e= ((k+j) / 2;
// {-1 <= k < e < j <= b.length}
if (b[e] <= x) k= e;
else
j= e;
}
return k;
}
CS100A, Fall 1997.
Lecture, 11 Nov.
6
•
•
•
•
•
Points about this binary search
on a sorted array
It works when the array is empty (b.length= 0)
If x is in b, it finds its rightmost occurrence.
If x is not in b, it finds the position after which
x “belongs”)
In general, it’s faster than a binary search that
stops as soon as x is found: The latter requires
an extra test in the loop body, which makes
each iteration slower; further, stopping as soon
as x is found saves only one iteration, on the
average.
It’s easy to verify the correctness of the
algorithm (using the loop invariant).
CS100A, Fall 1997.
Lecture, 11 Nov.
7
How fast is binary search?
b.length
no. of iterations log (b.length)
0
= 2**0 -1
0
0
1
= 2**1 -1
1
1
3
= 2**2 -1
2
2
7
= 2**3 -1
3
3
15
= 2**4 -1
4
4
32767 = 2**15-1
15
15
1048575= 2**20-1
20
20
j is the base 2 logarithm of the integer 2**j
(of 2 multiplied by itself j times).
m is the base 10 logarithm of the integer 10**m.
To search an array of a million entries using binary search
requires only 20 iterations!
To search an array of a million entries using linear search
requires between 1 and a million iterations.
Linear search is a linear algorithm: the time it takes is
proportional in the worst case to the size of the array.
Binary search is a logarithmic algorithm: the time it takes is
proportional to the logarithm of the size of the array.
CS100A, Fall 1997.
Lecture, 11 Nov.
8
Sorting: algorithm Selection Sort
Put array b in ascending order.
Think of having a loop that, at iteratively, places the next
smallest value in its final position. This is the method
behind the following loop invariant:
0
b
k
<=, sorted
>=
section is sorted and its
values are smaller than
those in the other section
k=
while (
b.length
These values are no
smaller than those in
the other section
;
){
}
CS100A, Fall 1997.
Lecture, 11 Nov.
9
Sorting: algorithm Selection sort
// Sort b (into ascending order)
static public void selectionSort(int [ ] b) {
k= 0;
// invariant: b[0..k-1] is sorted and
//
b[0..k-1] <= b[k..b.length-1]
while (k != b.length ) {
// Find position j of minimal value in b[k..b.length-1]
int j= k; int h= k+1;
// invariant b[j] is minimal value of b[k..h-1]
while (h != b.length) {
if (b[h] < b[j])
j= h;
h= h+1;
}
// Swap b[k] and b[j]
int t= b[k];
b[k]= b[j];
b[j]= t;
k= k+1;
}
CS100A, Fall 1997.
Lecture, 11 Nov.
10
How fast is insertionSort?
How many comparisons of array elements does it do in the
worst case?
At iteration k:
The inner loop iterates with h being k+1, …, b.length-1,
and each iteration of the inner loop makes 1 array-element
comparison. So, at iteration k, the loop makes
b.length - k-1 array comparisons
k
number of comparisons
0
b.length-1
1
b.length-2
…
b.length-1 0
1 + 2 + … + b.length-1 = (b.length-1)*(b.length)/2
Called a “b.length squared” algorithm
CS100A, Fall 1997.
Lecture, 11 Nov.
11
Sorting: algorithm Insertion Sort
Put array b in ascending order, using following invariant:
0
k
b.length
b Values that were originally in b[0..k-1], sorted
k= 0;
while ( k != b.length) {
// Place b[k] in its sorted position in b[0..k]
int temp= b[j];
h= k;
// invariant: ?
while (h != 0 && b[h-1] > temp) {
b[h]= b[h-1];
h= h-1
b[h]= temp;
}
k= k+1;
}
CS100A, Fall 1997.
Lecture, 11 Nov.
12
Algorithm Partition
Given is h < k. Let x be the value initially in b[h]:
h h+1
k
x
b
Rearrange b[h..k] to make it look like:
h
b
k
<= x
x
>= x
Use loop invariant:
h h+1
b
x
<= x
i
j
?
k
>= x
and write loop to end up with:
h h+1
b
x
<= x
j i
k
>= x
CS100A, Fall 1997.
Lecture, 11 Nov.
13
Algorithm Partition
/* k-h >= 2. Let x be the value initially in b[h]. Rearrange
b[h..k] to achieve b[h..j-1] <= b[j] = x < b[j+1..k], and
return j */
static public int partition (int b [ ], int h, int k) {
int i= h+1; int j= k;
/*invariant:
h h+1
b
x
<= x
i
j
?
k
>= x
while (i <= j ) {
if (b[i] <= x) i= i+1;
else (x <= b[j]) j= j-1;
else { // b[j] < x < b[i]
// Swap b[i] and b[j]
int t= b[i]; b[i]= b[j]; b[j]= i;
i= i+1; j= j-1;
}
}
// Swap b[h] and b[j]
int t1= b[h]; b[h]= b[j]; b[j]= t1;
return j;
CS100A, Fall 1997.
}
Lecture, 11 Nov.
*/
14
Iterative version of algorithm
QuickSort to sort b[H..K]
When an array segment is partitioned:
H
b
<= x
j
x
K
>= x
need to keep track of segments still to be sorted. Use three
variables n, h, k and two arrays low, high for this purpose.
Invariant: array is sorted when b[h..k] and b[low[t], high[t]],
for 0 <= t < n, are sorted
Example:
n=3
h..k is 1..6
low[0]..high[0] is 8..114
low[1]..high[1] is 19.. 222
low[2]..high[2] is 140..160
Need to sort
b[1..6]
b[8..114]
b[199..222]
b[140..160]
After partitioning, save space by putting larger of the two
segments b[h..j-1] and b[j+1..k] into low-high.
CS100A, Fall 1997.
Lecture, 11 Nov.
15
// Sort array section b[H..K], where K-H <= 2**30
public static void quickSort( int [ ] b, int H, int K ) {
int [ ] low= new int (30);
int [ ] high= new int (30);
int n= 0; int h= H; int k= K;
// invariant: b[H..K] will be sorted iff b[h..k] and
// b[low[t]..high[t]], for 0 <= t < n, are sorted.
while ( k-h > 1 || 0 != n ) {
if (k-h <= 1) {
Sort b[h..k] directly, if it is not empty;
if (n = 0) return;
n= n-1; h= low[n]; k= high[n];
}
else {
int j= partition(b, h, k);
// Put biggest of h..j-1, j+1..k in arrays low and high
// and the other one in h..k
if (j-h <= k-j)
{low[n]= j+1; high[n]= k; n= n+1; k= j-1;}
else {low[n]= h; high[n]= j-1; n= n+1; h= j+1;}
}
}
CS100A, Fall 1997.
16
}
Lecture, 11 Nov.