Sorting and searching |
Two fundamental list operations. | ||
Sorting | ||
Searching | ||
Sorted lists. | ||
Selection/bubble sort. | ||
Binary search. | ||
Loop invariant. | ||
There must be a way of comparing objects to determine which should come first. There must be an ordering relation. | |
There must be an operator to compare the objects to put them in order. | |
The ordering is antisymmetric. (a < b -> b !<a) | |
The ordering is transitive. (a<b,b<c -> a<c) | |
The ordering is total with respect to some “equivalence” on the class. (a<b or a>b or a==b, but only one; here “==“ means “equivalent with respect to the ordering”) |
public boolean lessThan (Student s) | |
s1.lessThan(s2) | |
Returns true if s1<s2 and false if s1>=s2. | |
for i > 0, j < size(), | |
get(i).lessThan(get(j)) implies i < j. |
Find the smallest element in the list, and put it in first. | |
Find the second smallest and put it second, etc. |
Find the smallest. | |
Interchange it with the first. | |
Find the next smallest. | |
Interchange it with the second. | |
Find the next smallest. | |
Interchange it with the third. | |
Find the next smallest. | |
Interchange it with the fourth. |
To interchange items, we must store one of the variables temporarily. |
If there are n elements in the list, the outer loop is performed n-1 times. The inner loop is performed n-first times. i.e. time= 1, n-1 times; time=2, n-2 times; … time=n-2, 1 times. | |
(n-1)x(n-first) = (n-1)+(n-2)+…+2+1 = (n2-n)/2 | |
As n increases, the time to sort the list goes up by this factor (order n2). | |
Make a pass through the list comparing pairs of adjacent elements. | |
If the pair is not properly ordered, interchange them. | |
At the end of the first pass, the last element will be in its proper place. | |
Continue making passes through the list until all the elements are in place. |
This algorithm represents essentially the same number of steps as the selection sort. | |
If make a pass through the list without interchanging, then the list is ordered. This makes the algorithm fast if it is mostly ordered. |
Assumes an ordered list. | |
Look for an item in a list by first looking at the middle element of the list. | |
Eliminate half the list. | |
Repeat the process. |
private int itemIndex (Student item, | |
StudentList list) | |
The proper place for the specified item on the specified list, found using binary search. | |
require: | |
list is sorted in increasing order | |
ensure: | |
0 <= result <= list.size() | |
for 0 <= i < result | |
list.get(i) < item | |
for result <= i < list.size() | |
list.get(i) >= item |
private int itemIndex (Student item, | |
StudentList list) { | |
int low; //lowest index considered | |
int high; //highest index considered | |
int mid; //middle between high and low | |
low =0 | |
high = list.size() -1; | |
while (low <= high) { | |
mid = (low+high)/2; | |
if (list.get(mid).lessThan(item)) | |
low = mid+1; | |
else | |
high = mid-1; | |
} | |
return low; | |
} |
/** | |
* Uses binary search to find where and if an element | |
* is in a list. | |
* require: | |
* item != null | |
* ensure: | |
* if item == no element of list | |
* indexOf(item, list) == -1 | |
* else | |
* item == list.get(indexOf(item, list)), | |
* and indexOf(item, list) is the smallest | |
* value for which this is true | |
*/ | |
public int indexOf(Student item, | |
StudentList list){ | |
int i = itemIndex(item, list); | |
if (i<list.size() && | |
list.get(i).equals(item)) | |
return i; | |
else | |
return -1; | |
} |
public int indexOf (Student obj) { | |
int i; | |
int length; | |
length = this.size(); | |
i = 0; | |
while (i < length && !obj.equals(get(i))) | |
i = i+1; | |
if ( i < length) | |
return i; | |
else | |
return -1;// item not found | |
} | |
A loop invariant is a condition that remains true as we repeatedly execute the loop body, and captures the fundamental intent in iteration. | |
partial correctness: the assertion that a loop is correct if it terminates. | |
total correctness: the assertion that a loop is both partially correct, and terminates. | |
loop invariant: a condition that is true at the start of execution of a loop and remains true no matter how many times the body of the loop is performed. |
1.private int itemIndex (Student item, | |
StudentList list) { | |
2. low =0 | |
3. high = list.size() -1; | |
4. while (low <= high) { | |
5. mid = (low+high)/2; | |
6. if (list.get(mid).lessThan(item)) | |
7. low = mid+1; | |
8. else | |
9. high = mid-1; | |
10.} | |
11. return low; | |
12.} | |
At line 6, we can conclude | |
0 <= low <= mid <= high < list.size() |
for 0 <= i < low | ||
list.get(i) < item | ||
for high < i < list.size() | ||
list.get(i) >= item | ||
This holds true at all four key places (a, b, c, d). | ||
It is vacuously true for indexes less than low or greater than high (a) | ||
We assume it holds after merely testing the condition (b) and (d) | ||
If the condition holds before executing the if statement and the list is sorted in ascending order, it will remain true after executing the if statement (condition c). |
We are guaranteed that | |
for 0 <= i < mid | |
list.get(i) < item | |
After the assignment, low equals mid+1 and so | |
for 0 <= i < low | |
list.get(i) < item | |
This is true before the loop body is done: | |
for high < i < list.size( | |
list.get(i) >= item |
If the loop body is not executed at all, and point (d) is reached with low == 0 and high == -1. | ||
If the loop body is performed, at line 6, low <= mid <= high. | ||
low <= high becomes false only if | ||
mid == high and low is set to mid + 1 or | ||
low == mid and high is set to mid - 1 | ||
In each case, low == high + 1 when the loop is exited. |
The following conditions are satisfied on loop exit | |
low == high + 1 | |
for 0 <= i <= low | |
list.get(i) < item | |
for high < i < list.size() | |
list.get(i) >= item | |
which implies | |
for 0 <= i < low | |
list.get(i) < item | |
for low <= i < list.size() | |
list.get(i) >= item | |
When the loop is executed, mid will be set to a value between high and low. | |
The if statement will either cause low to increase or high to decrease. | |
This can happen only a finite number of times before low becomes larger than high. |
Sorting | ||
selection sort | ||
bubble sort | ||
Searching | ||
Sequential/linear search | ||
binary search | ||
Verifying correctness of iterations | ||
partial correctness | ||
loop invariant | ||
key invariant | ||
termination |