Chapter 12
Sorting and searching

This chapter discusses
Two fundamental list operations.
Sorting
Searching
Sorted lists.
Selection/bubble sort.
Binary search.
Loop invariant.

Ordering lists
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”)

Implementing comparison
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.

Selection Sort
Find the smallest element in the list, and put it in first.
Find the second smallest and put it second, etc.

Selection Sort (cont.)
Find the smallest.
Interchange it with the first.
Find the next smallest.
Interchange it with the second.

Selection Sort (cont.)
Find the next smallest.
Interchange it with the third.
Find the next smallest.
Interchange it with the fourth.

Selection Sort (cont.)
To interchange items, we must store one of the variables temporarily.

Slide 9

Slide 10

Analysis of selection sort
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).

Bubble sort
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.

Pass 1

Pass 1 (cont.)

Pass 2

Pass 3 &4

Slide 17

Analysis of bubble sort
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.

Slide 19

Slide 20

Binary search
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.

Binary search

Binary search
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

Binary search (cont.)
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;
}

Binary search (cont.)

Completing the search
/**
 * 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;
}

Sequential/linear search
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
}

Relative efficiency

Loop invariant
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.

Back to binary search
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()

The key invariant
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).

The key invariant
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

Partial correctness:
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.

Partial correctness:
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

Loop termination
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.

We’ve covered
Sorting
selection sort
bubble sort
Searching
Sequential/linear search
binary search
Verifying correctness of iterations
partial correctness
loop invariant
key invariant
termination

Glossary

Glossary (cont.)