School of Computing in the College of Engineering at the University of Nebraska-Lincoln.
Before attending this lab:
-
Read and familiarize yourself with this handout.
-
Read the relevant material, watch the recommended videos, or review lecture topics on searching and sorting.
For students in the online section: you may complete the lab on your own if you wish or you may team up with a partner of your choosing. You may consult with a lab instructor to get teamed up online (via Zoom).
For students in the face-to-face section: your lab instructor will team you up with a partner.
To encourage collaboration and a team environment, labs are be structured in a peer programming setup. At the start of each lab, you will be randomly paired up with another student (conflicts such as absences will be dealt with by the lab instructor). One of you will be designated the driver and the other the navigator.
The navigator will be responsible for reading the instructions and telling the driver what to do next. The driver will be in charge of the keyboard and workstation. Both driver and navigator are responsible for suggesting fixes and solutions together. Neither the navigator nor the driver is "in charge." Beyond your immediate pairing, you are encouraged to help and interact and with other pairs in the lab.
Each week you should alternate: if you were a driver last week, be a navigator next, etc. Resolve any issues (you were both drivers last week) within your pair. Ask the lab instructor to resolve issues only when you cannot come to a consensus.
Because of the peer programming setup of labs, it is absolutely essential that you complete any pre-lab activities and familiarize yourself with the handouts prior to coming to lab. Failure to do so will negatively impact your ability to collaborate and work with others which may mean that you will not be able to complete the lab.
At the end of this lab you should be familiar with the following
-
Understand basic searching and sorting algorithms
-
Understand how comparator functions work and their purpose
-
How to leverage standard search and sort algorithms built into a framework
Recursion has been utilized in several searching and sorting algorithms. In particular, quicksort and binary search both can be implemented using recursive functions. The quicksort algorithm works by choosing a pivot element and dividing a list into two sub-lists consisting of elements smaller than the pivot and elements that are larger than the pivot (ties can be broken either way). A recursive quicksort function can then be recursively called on each sub-list until a base case is reached: when the list to be sorted is of size 1 or 0 which, by definition, is already sorted.
Binary search can also be implemented in a recursive manner. Given a sorted array and a key to be searched for in the array, we can examine the middle element in the array. If the key is less than the middle element, we can recursively call the binary search function on the sub-list of all elements to the left of the middle element. If the key is greater than the middle element, we recursively call the binary search function on the sub-list of all elements to the right of the middle element.
Searching and sorting are two solved problems. That is, most languages and frameworks offer built-in functionality or standard implementations in their standard libraries to facilitate searching and sorting through collections. These implementations have been optimized, debugged and tested beyond anything that a single person could ever hope to accomplish. Thus, there is rarely ever a good justification for implementing your own searching and sorting methods. Instead, it is far more important to understand how to leverage the framework and utilize the functionality that it already provides.
Clone the project code for this lab from GitHub using the following URL: https://github.com/cbourke/CSCE155-Java-Lab13
In this activity, you will implement a selection sort algorithm to sort an array of structures. Refer to lecture notes, your text, or any online source on how to implement the selection sort algorithm. The order by which you will sort the array will be according to the total team payroll (in dollars).
-
Familiarize yourself with the
Team
class and the methods provided to you (themain
method automatically loads the data from the data file and provides an array of teams). -
Implement the
selectionSortTeamsByPayroll
function in theMLBTeamUtils.java
file as specified -
Run your program (not everything will work yet because you have not yet implemented everything)
The Team
class has many different data fields; wins, losses
(and win percentage), team name, city, state, payroll, average salary.
Say that we wanted to re-sort teams according to one of these fields in
either ascending or descending order (or even some combination of
fields--state/city for example). Doing it the wrong way as above we
would need to implement no less than 16 different sort functions!
Most of the code would be the same though; only the criteria on which we update the index of the minimum element would differ. Instead, it would be better to implement one sorting function and make it configurable: provide a means by which the function can determine the relative ordering of any two elements. The way of doing this in Java is to define a comparator class.
Comparator
classes are simple. They are required to implement
the interface Comparator<T>
, which means specifying (coding)
one method: compare(T a, T b)
. The T
in this
declaration is a generic that we specify when we create a comparator.
The method itself takes two arguments: T
)
and returns:
-
A negative value if
$a < b$ -
Zero if
$a$ is equal to$b$ -
A positive value if
$a > b$
For example, in order to sort an array containing references to
instances of Team
by name, we would create a class that
implements Comparator<Team>
and implement the
compare()
method to compare two references to Team
s
passed in, and return an integer value based on the above rules.
Several completed comparator classes have been provided as examples. All
the comparator classes take two Team
arguments, and return an
integer based on the specified comparison. Refer to the provided
comparator classes for concrete examples.
-
Implement the
BY_PAYROLL_DESC
comparator in theMLBTeamUtils
class. Only one method,compare()
needs to be coded. -
Use the completed comparator classes provided with this lab an example on how to implement the
compare()
method -
Implement the
selectionSortTeams()
method inMLBTeamsUtils.java
source file -
Use the comparator class you just created to call
selectionSortTeams()
to sort an array ofTeam
s by payroll in descending order
The best way to sort is to leverage a sorting algorithm provided by a standard library. This eliminates the need to "reinvent" the wheel and avoids debugging, testing, etc. of our own code. Java provides several sorting methods in its standard developer kit (SDK). The one we will make use of is in the Arrays class. The method is able to sort arrays containing any type of object by making use of a provided comparator:
public static <T> void sort(List<T> list, Comparator<? super T> c)
where
-
list
a is aList
of objects (of typeT
) to be sorted -
Comparator<? super T> c
is the comparator class that is used to determine sort order of the object elements in the array. Note: the? super T
in the comparator angle brackets indicate that the type of class being compared must beT
, or any superclass (ancestor) of typeT
.
-
Examine the source files and observe how
Comparator
classes are defined and how theCollections.sort
method is called -
Implement two more comparators,
BY_STATE_DESC
which sorts based on team home state (descending), andBY_STATE_CITY_DESC
which sorts based first on state then by city (both descending) -
Use your method in the
main
method to re-sort the array and print out the results.
The Collections
class also offers a method to search an array. In
this exercise, we will focus on two strategies for searching--linear
search and binary search.
-
linearSearchMLB
- a linear search implementation (in theMLBTeamUtils
class) that does not require the array to be sorted. The method works by iterating through the array and calling your comparator class on the provided key (an object instance whose state matches the criteria that you are searching for). It returns the index of the first instance such that the comparator returns zero for (indicating equality between the objects). -
binarySearch
- a binary search implementation (in theCollections
class) that requires the array to be sorted according to the same comparator used to search.
Both methods require a comparator (as used in sorting) and a key upon which to search. A key is a "dummy" instance of the same type as the array that contains values of fields that you?re searching for.
-
Examine the
linearSearchMLB
method in theMLBTeamUtils
class and understand how it works -
Based on your observations add code to search the array for the team representing the Chicago Cubs:
-
Create a dummy
Team
key for the Cubs by instantiating a dummy team and using empty strings and zero values except for the team name (which should be"Cubs"
) -
Sort the array by team name using the appropriate comparator
-
Call the
binarySearch
method using your key and the appropriate comparator to find theTeam
representing the Chicago Cubs -
Print the team to the standard output
-
-
Run the provided JUnit test suite to ensure your code is correct. Fix any errors before you submit.
-
Discuss with your partner: why did the searches for a California (CA) team differ?
-
Hand in your completed files:
RunMLBTeams.java
MLBTeamUtils.java
-
Even if you worked with a partner, you both should turn in all files.
Selection sort is a quadratic sorting algorithm, thus doubling the input
size (