Title: Chapter 14: Sorting and Searching
1Chapter 14 Sorting and Searching
2Ordering lists
- To order a list, there must be an order on the
element class. - Well assume
- There is an int method compare defined for the
class whose instances we want to order.
- Example to order a ListltStudentgt need
public int compare (Student first, Student second)
- Thus if s1 and s2 are Student objects,
- if compare(s1,s2)lt 0, s1 comes before s2.
- if compare(s1,s2)gt 0, s2 comes before s1.
- if compare(s1,s2) 0, does not matter which
comes first, s1 and s2 are equivalent w.r.t the
ordering.
3Ordering lists
- Ordering alphabetically by name, compare(s1,s2)
is negative if s1s name preceded s2s name
alphabetically, positive if s2s name preceded
s1s name , and zero if if s1s and s2s name are
identical. - Ordering by decreasing grade, compare(s1,s2) is
negative if s1s grade was greater than s2s,
positive if s1s grade was smaller than s2s and
zero if the grades are identical.
4Order properties
- We write
- s1 lt s2 when compare(s1,s2) lt 0
-
- An ordering is antisymmetric it cannot be the
case that both s1 lt s2 and s2 lt s1. - An ordering is transitive. That is, if s1 lt s2
and s2 lt s3 for objects s1, s2, and s3, then s1
lt s3. - If s1.equals(s2) then compare(s1, s2) 0
5Ordered list
- A list is ordered
- s1 lt s2, then s1 comes before s2 on the list
for all indexes i, j compare(list.get(i),list.
get(j)) lt 0 implies i lt j.
for all indexes i and j, i lt j impliescompare(lis
t.get(j),list.get(i))lt 0
6Selection Sort
- Design
- Find the smallest element in the list, and put it
in as first. - Find the second smallest and put it as second,
etc.
7Selection Sort
- Find the smallest.
- Interchange it with the first.
- Find the next smallest.
- Interchange it with the second.
8Selection Sort
- Find the next smallest.
- Interchange it with the third.
- Find the next smallest.
- Interchange it with the fourth.
9Selection sort
- To interchange items, we must store one of the
variables temporarily.
- While making list.get(0) refer to list.get(2),
loose reference to original entry referenced
by list.get(0).
10Selection sort algorithm
/ Sort the specified ListltStudentgt using
selection sort. _at_ensure for all indexes
i, j compare(list.get(i),list.get(j)) lt 0
implies i lt j. / public void sort
(ListltStudentgt list) int first // index of
first element int last // index of last
element int small last list.size() -
1 first 0 while (first lt last) small
smallestOf(list,first,last) interchange(list,fi
rst,small) first first1
11Selection sort algorithm
/ Index of the smallest of
list.get(first) through list.get(last) / private
int smallestOf (ListltStudentgt list,int first,
int last) int next //
index of next element to examine. int
small // index of smallest of //
get(first)..get(next-1) small first next
first1 while (next lt last) if
(compare(list.get(next), list.get(small)) lt 0 )
small next next next1 return
small
12Selection sort algorithm
/ Interchange list.get(i) and list.get(j)
require 0 lt i lt list.size() 0 lt j lt
list.size() ensure list.old.get(i).equal
s(list.get(j)) list.old.get(j).equals(list.
get(i)) / private void interchange
(ListltStudentgt list,
int i, int j) Student temp
list.get(i) list.set(i, list.get(j)) list.set(
j, temp)
13Analysis 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
time2, n-2 times timen-2, 1 times. - (n-1)x(n-first) (n-1)(n-2)21 (n2-n)/2
- As n increases, the time to sort the list goes up
by this factor (order n2).
14Bubble 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.
15Pass 1
16Pass 2
17Pass 3
Pass 4
18Bubble sort algorithm
// Sort specified ListltStudentgt using bubble
sort. public void sort (ListltStudentgt list)
int last// index of last element to position on
pass last list.size() - 1 while (last gt 0)
makePassTo(list, last) last last-1
// Make a pass through the list, bubbling an
element // to position last. private void
makePassTo (ListltStudentgt list, int last) int
next // index of next pair to examine. next
0 while (next lt last) if
(compare(list.get(next1), list.get(next)) lt 0
) interchange(list, next, next1) next
next1
19Fine-tuning bubble sort algorithm
- Making pass through list no elements interchanged
then the list is ordered. - If list is ordered or nearly so to start with,
can complete sort in fewer than n-1 passes. - With mostly ordered lists, keep track of whether
or not any elements have been interchanged in a
pass.
20Generalizing the sort methods
- Sorting algorithms are independent of
- the method compare, as long as it satisfies
ordering requirements. - The elements in the list being sorted.
21Generalizing the sort methods
- Want to generalize the sort to ListltElementgt
instances with the following
specification
public ltElementgt void selectionSort
( ListltElementgt list, OrderltElementgt order)
- Thus
- Need to learn about generic methods.
- Need to make the inOrder method part of a class.
22Generic methods
- Can define a method with types as parameters.
- Method type parameters are enclosed in angles and
appear before the return type in the method
heading.
Method type parameter
public ltElementgt void swap (ListltElementgt
list, int i, int j) Element temp
list.get(i) list.set(i,list.get(j)) list.set(j
,temp)
- swap is now a generic method it can swap to list
entries of any given type.
23Generic swap
- When swap is invoked, first argument will be a
List of some type of element, and local variable
temp will be of that type. - No special syntax required to invoke a generic
method. - When swap is invoked, the type to be used for the
type parameter is inferred from the arguments.
24Generic swap
- For example, if roll is a ListltStudentgt,
- ListltStudentgt roll
- And the method swap is invoked as
- swap(roll,0,1)
- Type parameter Element is Student, inferred from
roll. - The local variable temp will be of type Student.
25Generic sorts
- Define methods in a sort utility class, as
generic methods.
public class ListUtilities public static
ltElementgt void selectionSort(ListltElementgt
list) public static ltElementgt void
bubbleSort(ListltElementgt list)
- Since each sort is generic, need to provide the
sort methods with the compare method to use when
comparing elements. - Cant give compare as an argument to the sort
- But we can give it an object containing compare.
26compare as function object
- Wrap up method compare in an object to pass it
as an argument to sort.
/ An ordering on the class Element. The
ordering is transitive and antisymmetric
/ public interface ComparatorltElementgt /
Whether or not e1 precedes e2 in the
ordering. Returns a negative integer if e1
precedes e2, a positive integer if e2
precedes e1, zero / int compare (Element
e1, Element e2)
27compare as function object
- Can define sort to have both a list and an order
as arguments.
/ An ordering on the class Element. The
ordering is transitive and antisymmetric
/ public static ltElementgt void selectionSort (
ListltElementgt list,
ComparatorltElementgt order)
- The order can then be passed to auxiliary methods
private static ltElementgt int smallestOf (
ListltElementgt list, int first, int last,
ComparatorltElementgt order) int next int
small small first next first1 while
(next lt last) if (order.compare(
list.get(next),list.get(small)) lt 0) small
next next next1 return small
28Implementing Comparator interface
- To sort a list of Student by grade, define a
class (GradeOrder) implementing the interface,
and then instantiated the class to obtain the
required object.
//Order Students by decreasing finalGrade class
GradeOrder implements ComparatorltStudentgt
public int compare(Student s1, Student s2)
return s1.finalGrade() - s2.finalGrade()
- There is no need of constructor, as there is no
data to initialize. - With roll an instance of DefaultListltStudentgt
ListUtilities.selectionSort(roll, new
GraderOrder())
29Anonymous classes
- Define the class and instantiate it in one
expression. - For example,
new ComparatorltStudentgt() int compare(Student
s1, Student s2) return s1.finalGrade() -
s2.finalGrade()
- This expression
- defines an anonymous class implementing interface
ComparatorltStudentgt, and - creates an instance of the class.
- Can use above as the Comparator argument to a
sort.
30Sorting a roll by grade
- If roll is a ListltStudentgt, to sort it invoke
ListUtilities.selectionSort(roll, new
GradeOrder())
- Or, using anonymous classes
ListUtilities.selectionSort(roll, new
OrderltStudentgt() int compare(Student s1,
Student s2) return s1.finalGrade() -
s2.finalGrade() )
31Sorts as generic objects
- wrap sort algorithm and ordering in the same
object. - Define interface Sorter
//A sorter for a ListltElementgt. public interface
SorterltElementgt //e1 precedes e2 in the sort
ordering. public int compare (Element e1,
Element e2) //Sort specified ListltElementgt
according to //this.compare. public void
sort (ListltElementgt list)
32Sorts as generic objects
- Provide specific sort algorithms in abstract
classes, leaving the ordering abstract.
public abstract class SelectionSorterltElementgt
implements SorterltElementgt // Sort specified
ListltElementgt using selection sort. public void
sort (ListltElementgt list)
Selection sort algorithm
- To create a concrete Sorter, we extend the
abstract class and furnish the order
class GradeSorter extends SelectionSorterltStudentgt
public int compare (Student s1, Student
s2) return s2.finalGrade() s1.finalGrade()
33Sorts as generic objects
- Instantiate the class to get an object that can
sort
GradeSorter gradeSorter new GradeSorter() grade
Sorter.sort(roll)
- Using an anonymous class,
SelectionSorterltStudentgt gradeSorter new
SelectionSorterltStudentgt() public int compare
(Student s1, Student s2) return
s2.finalGrade() s1.finalGrade()
gradeSorter.sort(roll)
34Interface java.util.Comparator
- The package java.util defines the interface
ComparatorltTypegt that is the same as the
Comparator interface we introduced.
35Interface Comparable the natural order
- Package java.lang defines interface
ComparableltTypegt that imposes an order on any
class that implements it. - When implementing ComparableltTypegt implementing
class is written as the type argument for
Comparable.
public class PlayingCard implements
ComparableltPlayingCardgt
- Comparable specifies only one method
public int compareTo (Type other)
36Interface Comparable the natural order
- It defines an ordering in the way that compare
does. - if e1.compareTo(e2) lt 0, then e1 precedes e2 in
the order - if e1.compareTo(e2) gt 0, then e2 precedes e1 in
the order - if e1.compareTo(e2) 0, then e1 and e2 are
equivalent with respect to the order. - compareTo is required to satisfy same properties
as those required for compare. (reflexive,
anti-symmetric, transitive)
37Interface Comparable the natural order
- Comparables natural order should be consistent
with equals
e1.compareTo(e2) if and only if e1.equals(e2)
- Use Comparable when defining a class that has a
fixed, intrinsic order. - Comparators can be used to define multiple
orderings on an existing class. - Do not override compareTo.
38Interface Comparable the natural order
- Redefine the class PlayingCard specifying that it
implements Comparable. - This natural ordering must be consistent with
equals if two playing cards with same rank and
suit are equivalent with respect to the natural
ordering, they must be equal.
39public class PlayingCard implements
ComparableltPlayingCardgt public
boolean equals (Object other) if (other
instanceof PlayingCard) return this.rank
((PlayingCard)other).rank this.suit
((PlayingCard)other).suit else return
false public int compareTo (PlayingCard
other) if (this.equals(other)) return
0 else if ((this.rank lt other.rank)
(this.rank other.rank this.suit lt
other.suit)) return -1 else return 1
40Ordered Lists
- Typically need to maintain lists in specific
order. - We treat ordered and unordered lists in different
ways. - may add an element to the end of an unordered
list but want to put the element in the right
place when adding to an ordered list. - Interface OrderedList ( does not extend List)
- public interface OrderedListltElementgt
- A finite ordered list.
41Ordered Lists
- OrderedList shares features from List, but does
not include those that may break the ordering,
such as - public void add(int index, Element element)
- public void set( ListltElementgt element, int i,
int j) - A Comparator is provided when an OrderedList is
created. - OrderedList invariant
- ordering() returns the order used by the class.
- for all indexes i, jordering().compare(get(i),get
(j)) lt 0 implies i lt j. - OrderedList add method is specified as
- public void add (Element element)
- Add the specified element to the proper place in
this OrderedList.
42Binary 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.
43Binary Search for 42
list.get(7) lt 42 No need to look below 8
list.get(11) gt 42 No need to look above 10
list.get(9)lt42 No need to look below 10
Down to one element, at position 10 this isnt
what were looking for, so we can conclude that
42 is not in the list.
44Generic search method itemIndex
private ltElementgt int itemIndex (Element item,
ListltElementgt list, ComparatorltElementgt
order) Place for item on list found using binary
search. require list is sorted according
to order. ensure 0 lt result result lt
list.size() for all indexes i i lt result
implies order.inOrder(list.get(i),item)lt
0 for all indexes i i gt result implies
!order.inOrder(list.get(i),item) gt 0
- It returns an index such that
- all elements prior to that index are smaller than
item searched for, and - all of items from the index to end of list are
not.
45Implementation of itemIndex
private ltElementgt int itemIndex (Element item,
ListltElementgt list, ComparatorltElementgt order)
int low // the lowest index being
examined int high // the highest index
begin examined // for all indexes i // i
lt low gt order.compare(list.get(i),item) lt 0 //
for all indexes i // i gt high gt
order.compare(list.get(i),item) gt 0 int mid//
middle item between low and high. low 0 high
list.size() - 1 while (low lt high)
mid (lowhigh)/2 if (order.compare(list.get(
mid),item) lt 0) low mid1 else
high mid-1 return low
46Searching for 42 in
47Searching for 42
low
high
low
42 is not found using itemIndex algorithm
48Searching for 12
49Searching for 12
low
high
12 found in list at index 3
50indexOf using binary 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,lis
t) -1 - else item list.get(indexOf(item, list)),
- and indexOf(item, list) is smallest value for
which - this is true
- /
- public ltElementgt int indexOf (Element item,
- ListltElementgt list, ComparatorltElementgt
order) - int i itemIndex(item, list, order)
- if (i lt list.size() list.get(i).equals(item))
- return i
- else
- return -1
51Recall sequential (linear) search
- public int indexOf (Element element)
- int i 0 // index of next element to examine
- while (i lt this.size()
!this.get(i).equals(element)) - i i1
- if (i lt this.size())
- return i
- else
- return -1
52Relative algorithm efficiency
- Number of steps required by the algorithm with a
list of length n grows in proportion to - Selection sort n2
- Bubble sort n2
- Linear search n
- Binary search log2n
53Extra Slides Loop Invariant
54Loop invariant
- Loop invariant condition that remains true as
we repeatedly execute loop body it captures the
fundamental intent in iteration. - Partial correctness assertion that loop is
correct if it terminates. - Total correctness assertion that loop is both
partially correct, and terminates.
55Loop invariant
- loop invariant
- it is true at the start of execution of a loop
- remains true no matter how many times loop body
is executed.
56Correctness of itemIndex algorithm
- private ltElementgt int itemIndex (Element
item, ListltElementgt list, OrderltElementgt order)
- int low 0
- int high list.size() - 1
- while (low lt high)
- mid (lowhigh)/2
- if (order.inOrder(list.get(mid),item))
- low mid1
- else
- high mid-1
-
- return low
-
57Key invariant
- Purpose of method is to find index of first list
element greater than or equal to a specified
item. - Since method returns value of variable low, we
want low to satisfy this condition when the loop
terminates
for all indexes i i lt low implies order.inOrder(
list.get(i),item) for all indexes i i gt low
implies !order.inOrder(list.get(i),item)
58Key invariant
- This holds true at all four key places (a, b, c,
d). - Its 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 condition holds before executing the if
statement and list is sorted in ascending order,
it will remain true after executing the if
statement (condition c).
59Key invariant
- We are guaranteed that
- for 0 lt i lt mid
- order.inOrder(list.get(i), item)
- After the assignment, low equals mid1 and so
- for 0 lt i lt low
- order.inOrder( list.get(i), item)
- This is true before the loop body is done
- for high lt i lt list.size(
- !order.inOrder( list.get(i), item)
60Partial correctness
- If 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 lt
mid lt high. - low lt 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 loop is
exited.
61Partial correctness
- The following conditions are satisfied on loop
exit - low high1
- for all indexes i i lt low implies
- order.inOrder(list.get(i),item)
- for all indexes i i gt high implies
- !order.inOrder(list.get(i),item)
- which imply
- for all indexes i i lt low implies
- order.inOrder(list.get(i),item)
- for all indexes i i gt low implies
- !order.inOrder(list.get(i),item)
62Loop 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.