You are on page 1of 37

Searching & Sorting

Components in a Search:
List of Comparable I tems:
7 14 22 5 12 18 40
key Item:
key = 5
A =
Linear Search:
7 14 22 5 12 18 40
key = 18
A =
key == a[0]?
key key key key key key
key == a[1]? key == a[2]? key == a[3]? key == a[4]? key == a[5]?
Done!
0 1 2 3 4 5 6 index
public boolean linearSearch(int [ ] aList, int size, int key){

boolean found = false;
int index = 0;

while(!found && (index < size))
if (key == aList[i])
found = true;
else
index++;
return found;
};


Linear Search:
Algorithm Analysis:
Best Case Analysis:
Worst Case Analysis:
Average Case Analysis:
1
n
(n + 1)/2
Number of compares:
key is at A[0]
key is at A[size-1] OR not found
key can appear in each of the n index
positions with equal probability
7 14 22 5 12 18 40
A =
Algorithm Analysis:
Average Case Analysis: (n + 1)/2
Algorithm Analysis:
# of Comparisons:
Probability
Contributions
1
1/7
1 * 1/7
2
1/7
2 * 1/7
3
1/7
3 * 1/7
. . .
. . .
. . .
Binary Search:
17 24 32 35 12 48 50
key = 24
aList =
57
key
key = = aList[mid] ?

key
Done!
Ordered!
key
public static boolean binarySearch(int [ ]a, int first, int last, int key){
int index = -1;
if (first > last)
return false;
else {
index = (first + last)/2;
if (key = = a[index])
return true;
else if (key < a[index])
return binarySearch(a, first, index -1, key);
else
return binarySearch(a, index + 1, last, key);
} //end else
} //end binarySearch

Sorting Algorithms
1. Bubble Sort
2. Insertion Sort
3. Quicksort
4. Merge Sort
Bubble Sort
Strategy: During each iteration move the greatest
remaining element to the back of the list.
At some intermediate stage of the execution of this algorithm, the array to
be sorted, call it A, will have the following properties:
low
high
A
Goal: Sort list of integers in the range of indices low<= i < high in ascending order
i
back segment front segment
sorted in ascending order
every element in the back
segment is greater than or
equal to every element in the
front segment.
unsorted
Bubble Sort
Strategy: During each iteration move the greatest remaining
element to the back of the unsorted list (front segment).
low
high
A
Goal: Sort list of integers in the range of indices low<= i < high in ascending order
i
back segment front segment
Compare A[j] with A[j+1] and swap if A[j] > A[j+1]
Goal: Move largest remaining integer to the back of the front segment
sorted in ascending order
every element in the back
segment is greater than or
equal to every element in the
front segment
An intermediate stage picture shows
j
Every element is less
than or equal to A[j]
unsorted
front segment middle segment
When j = i 1, the greatest element in
the front segment is at index j
j i
Decrement i and the statements about
the back segment remain true
public static void bubbleSort(int a[], int low, int high){
boolean sorted = false;
for (int i = high; (i > 0) && !sorted; i-- ){
sorted = true;
for (int j = low; j < i - 1; j++){
if (a[ j ] > a[ j+1]){
int temp = a[ j ];
a[ j ] = a[ j+1 ];
a[ j+ 1] = temp;
sorted = false;
} //end if
} //end for
} //end bubbleSort

End the search when no
exchanges are needed
A swap has occurred,
continue the sort for
another iteration of i
3
15
45
40
8
12
5
22
14
3
15
45
40
8
12
5
22
14
3
15
45
40
8
12
22
5
14
3
15
45
40
8
22
12
5
14
3
15
45
40
22
8
12
5
14
3
15
45
40
22
8
12
5
14
3
15
45
40
22
8
12
5
14
3
45
15
40
22
8
12
5
14
45
3
15
40
22
8
12
5
14
45
3
15
40
22
8
12
5
14
45
3
15
40
22
8
12
14
5
45
3
15
40
22
8
14
12
5
45
3
15
40
22
14
8
12
5
45
3
15
40
22
14
8
12
5
45
3
15
40
22
14
8
12
5
45
3
40
15
22
14
8
12
5
45
40
3
15
22
14
8
12
5
45
40
3
15
22
14
12
8
5
45
40
3
15
22
14
12
8
5
45
40
3
15
22
14
8
12
5
45
40
3
15
22
14
8
12
5
45
40
3
15
22
14
12
8
5
45
40
3
22
15
14
12
8
5
45
40
22
3
15
14
12
8
5
45
40
22
3
15
14
12
8
5
45
40
22
15
3
14
12
8
5
45
40
22
15
3
14
12
8
5
45
40
22
15
14
3
12
8
5
45
40
22
15
14
3
12
8
5
45
40
22
15
14
12
3
8
5
45
40
22
15
14
12
3
8
5
45
40
22
15
14
12
8
3
5
45
40
22
15
14
12
8
3
5
45
40
22
15
14
12
8
5
3
Bubble Sort in Action
Insertion Sort
Insertion sort is the strategy used by the card player who picks up the card
he or she is dealt one at a time and inserts it into his or her existing hand
A snapshot of the algorithm at an intermediate stage:
A:
low high
i
front segment back segment
sorted in ascending order unsorted, some elements in the back
segment may be less than some (or
all) elements in the front segment
Strategy: put the element, call it x, at index i into its proper place in the front segment
temp
x
1. Copy A[i] into local variable temp
x
This creates a hole at index i
2. Set index j = i - 1
j
3. while(temp < A[j])
A[j+1] = A[j];
This effectively moves the hole left
4. Found place for x. A[j] = temp
j j
x
5. Increment i front segment grows by 1
i
Implementation of this
algorithm is left as an
exercise.
Quicksort
Partition the array between indices low and high select a
pivot and move all values that are less than or equal to the
pivot to the left of the pivot index and all values greater than
the pivot to the right of the pivot index.
1. Step 1 randomly choose a pivot index between low and high.
Alternatively select low as the pivot index. (It is as good as any choice)
2. Step 2 move the pivot to position A[low]
3. Step 3 set partition indices i = low + 1, j = high - 1
A:
low
high
P
i
v
o
t

i
j
Quicksort
A:
low
high
P
i
v
o
t

i
j
1. Step 4a while( A[i] <= A[low]) i++; //move pivot index i to right
2. Step 4b while(A[j] > A[low]) j--; //move pivot index j to the left
i j
y x
3. Step 5 swap A[i] and A[j]
x y
All entries less
than or equal to
the pivot
All entries
greater than
the pivot
unprocessed
4. Repeat Steps 4a, 4b, and 5 until i > j //(unprocessed segment is empty)
i j
5. Step 6 swap A[low] and A[j] //move pivot to back of front seg.
p
i
v
o
t
Partition
A:
low
high
21 10 17 24 44 41 25 10 19 6 47
Randomly select index greater than or equal to low
less than high as the pivotIndex.
swap A[low] and A[pivotIndex]
21 17
int i = low + 1;
i
int j = high 1;
j
while ((i <= j) && (A[i] <= A[low])) i++;
i i
while (A[j] > A[low]) j--;
j
j
if (i < j) swap(A[i], A[j]);
19 24
}
while (i < = j) {
i
i j
10 47
i j j
swap(A[low], A[j]);
21 10
Quicksort
When a call to partition terminates, the pivot separates all
the entries that are less than or equal to the pivot from
those entries greater than the pivot.
public static void quickSort (int [ ] A, int low, int high) {
if (high low >= 2) {
pivotIndex = partition (A, low, high);
quickSort (A, low, pivotIndex);
quickSort (A, pivotIndex + 1, high);
}
The high index is off right
low
high
p
i
v
o
t
entries <= pivot entries > pivot
quickSort front segment
quickSort back segment
Quicksort
first call
2
nd
call
3
rd
call
Each time the (sub) list is partitioned exactly one value (the pivot) is
placed in its correct position.
If the list is equally divided during each partitioning, it will require
about lg (n) calls to quickSort to produce a sorted list.
Quicksort
Analysis of the performance of quickSort assume a list of size N
Count the (approximate) number of compares needed to sort the list.
Best case:
Worst case:
Average case:
Each pivot divides the remaining list in half
Number of recursive calls:
Number of compares :
Number of recursive calls:
Number of compares:
Number of recursive calls:
Number of compares:
lg N
< N during each level of recursion
Each pivot is at the front or back of the list
N - 1
< N during each level of recursion
< c lg N, for some constant c
< N during each level of recursion
Merge Sort
Strategy: Recursively split the list in half and merge the the
two returned segments.
12 27 25 16 29 15 14 5
12 16 27 25 14 5 29 15
12 29 15 14 5 27 25 16 A =
12 16 25 27 5 14 15 29
12 16 25 27 5 14 15 29
12 16 25 27 5 14 15 29
5 12 14 15 16 25 27 29
split merge
12 29 15 14 5 27 25 16 A =
B =
if (A[first] <= A[last])
B[next] = A[first];
first++;
else
B[next] = A[last];
last++;
first
last
next
5 12 14 15 16 25 27 29
Merge Process
public static void mergeSort (int [ ] A, int first, int last) {
if (last first > 1) {
int middle = (first + last)/2;
mergeSort(A, first, middle);
mergeSort (A, middle, last);
merge (A, first, middle, last);
}
}
first middle last
The terminal index is off right.
private static void merge( int [ ] A, int first, int mid, int last) {
int [ ] tempArray = new int[last - first];
int i = first, j = middle, k;
for (k = 0; i < middle && j < last; k++)
if (A[i] <=A[j})
tempArray[k] = A[i++];
else
tempArray[k] = A[j++];
for ( ; i < middle; k++)
tempArray[k] = A[i++];
for ( ; j < last; k++)
tempArray[k] = A[j++];
for (int index = 0; index < last - first; index++)
A[first + index] = tempArray[iindex];
}
Merge the two halves
until one runs out
Append the remaining
elements to the end of
tempArray
Copy the contents of
tempArray back into A
12 27 25 16 29 15 14 5
12 16 27 25 14 5 29 15
12 16 25 27 5 14 15 29
12 29 15 14 5 27 25 16 A =
Levels = ? log(n) + 1
Work = ? n
Total Complexity =
n(log(n) + 1)
Number of compares at each level during merge
Shell Sort
Strategy: set a gap (initially let gap = n/2),
insertion sort elements separated by a
distance of gap, reduce the gap by increments
after each iteration until it is = 1, and
continue.
Shell Sort
0 1 2 3 4 5 6 7 8
Example: an array of int, length n = 9
24 3 44 27 10 41 47 25 31
gap = n/2 = 4
for (int i = gap; i < A.length; i++) {
int temp = A[i];
for ( ; j >= gap && temp < A[j-gap]; j -= gap)
A[j] = A[j gap];
A[j] = temp; }
A
i
24 10
i i
44 41
i
27 3
i
gap = max(1, (int) gap /2) = 2
i
i
3 31
i
41 24
i
i
i
27 47 31 27
i
44 25 41 25
1
3 10 27 25 47 44
public static <E extends Comparable<? super E>>
void shellsort(E[ ] a) {
for (int gap = a.length/2; gap > 0; gap = Math.max(1, (int)gap/2.2))
for (int i = gap; i < a.length; i++) {
E temp = a[i];
int j = i;
for( ; j >= gap && temp.compareTo(a[j-gap]) < 0; j-=gap)
a[j] = a[j gap];
a[j] temp;
}
}
use gap = (int)gap/2.2 for the best performance
Constructing an ordered list
We want our ordered list to be:
Generic hold items of any class derived from Object
Resizable able to expand to accommodate the need
Self-maintaining order is preserved after insert and
remove operations
Comparing two Objects
Primitive types can be compared using the relational operators,
but in Java operators cannot be overloaded by the application
programmer. (And primitive types cannot be stored in our
generic ordered list.)
Suppose we wanted to hold objects of a class Person in an
OrderedArray container that we are constructing. We must:
Declare that class Person implements Comparable
Implement the method compareTo that is in the Comparable
interface OR
Provide a class PersonComparator that extends Comparator
Provide a constructor in class OrderedArray that takes a
Comparator object as a parameter (if using Comparator)
Comparing Two Objects
Consider a class Person
public class Person implements Comparable {
private String sirName;
private int age, weight, height;
private double salary;
//constructors and other methods
public int compareTo (Object other) {
/**this method returns a negative number if this object is less
than other, 0 if they are equal, and a + integer if this > other*/
/**choose sirName as the attribute to compare String objects
are themselves Comparable*/
return sirName.compareTo(((Person).other).sirName);
}
}
Must cast object other to class Person
ADT OrderedList
TYPES: Object, Integer, Boolean
FUNCTIONS:
Create: ( ) OrderedList
Dissolve: OrderedList ( )
insert: OrderedList, Object OrderedList
remove: OrderedList, Object -/-> OrderedList
remove: OrderedList, Integer -/-> OrderedList, Object
retrieve: OrderedList, Integer -/-> Object
findIndex: OrderedList, Object Integer
contains: OrderedList, Object Boolean
isEmpty: OrderedList Boolean
size: OrderedList Integer
Class OrderedList
public class OrderedList {
private Comparable [ ] buffer;
private int size, capacity;
private void resize( ) {
/**add additional capacity to buffer when inserting into a full list*/
public OrderedList( ) { } //default constructor create buffer of capacity 16
public OrderedList(int cap) { } //user specified initial capacity
public void insert(Comparable theObject) {
/**if full, resize add an additional 16 spaces
down cast theObject and store result in a local variable temp
starting at size 1 compare each item in buffer with temp and
move one place to the right if greater **see next sheet for details
insert the contents of temp into buffer at index holding the hole
*/}
(continued on following slides)

Performing a Comparison
Compare the i
th
buffer element with the contents of temp
//temp contains (Person)theObject
//inside of a iterative loop we perform the following comparison
Person thisPerson = (Person)buffer[i];
if (thisPerson.compareTo(temp) > 0) {
//move thisPerson one space to the right
}
else {
//this is the index where theObject is placed
}
Need to compare 2
Person objects
Use the compareTo()
method of Person to
order list elements
Continuing declaration of OrderedList
public void remove(Comparable theDumped) {
/**preconditions: list not empty and list contains theDumped
post-condition: first occurrence of theDumped is removed */
}
public Comparable remove(int theIndex) {
/**preconditions: list not empty and 0 <= theIndex < size
post-condition: contents of buffer at theIndex is removed and returned*/
}
public boolean contains(Comparable theTarget) {
/**use down cast and method compareTo of Person to test if theTarget is
found in buffer.*/
}
public Comparable retrieve(int theIndex) {
/**preconditions: list not empty and 0 <= theIndex < size
post-condition: contents of buffer at theIndex is returned*/
}
Remaining methods
public int findIndex (Comparable target) {
/**post-condition: returns index of first occurrence of target if found, else 1*/
public boolean isEmpty( ) { }
public int size( ) { }
} //end of class declaration
It is left as an exercise for you to implement class
OrderedList as described in these overheads.

You might also like