10.5 Bubble Sort
Our next (but not our last) sorting algorithm, called a bubble sort, is an
example of a class of sorts known as exchange sorts. With the bubble sort,
the basic idea is to compare adjacent values and exchange them if they are
not in order.
Example 1
Suppose that we want to use a bubble sort to arrange the names
Phil Ivan Sara Jack Gina
in alphabetical order. We start by comparing Phil to Ivan. Since they are
not in order, we exchange them to give
Ivan Phil Sara Jack Gina
Next we compare Phil to Sara. Since they are in order, we leave them that
way giving
Ivan Phil Sara Jack Gina
Now, comparing Sara to Jack, we see that they must be exchanged. Doing
this gives
Ivan Phil Jack Sara Gina
We then compare Sara to Gina. Again, we must perform an exchange to
obtain
Ivan Phil Jack Gina Sara
The result of all this comparing and exchanging is that, after one pass, the
largest value (Sara, in our example) will be at the upper end of the list.
Like a bubble rising in a liquid, the largest value has risen to the top of the
list.
|
|
As with the selection sort shown in the previous section, we now repeat
the process used in the first pass on all but the last element. As we proceed,
the passes deal with shorter and shorter subsequences of the original list
until all values are in their correct positions.
Example 2 The following tables show the actions of a bubblesort in ordering the names
Phil Ivan Sara Jack Gina
The colons indicate the values currently being compared. The vertical bars
indicate the division points between the unsorted data and the sorted data.
Phil : Ivan Sara Jack Gina
Ivan Phil : Sara Jack Gina
First Pass Ivan Phil Sara : Jack Gina
Ivan Phil Jack Sara : Gina
Ivan Phil Jack Gina | Sara
Phil : Ivan Sara Jack | Gina
Ivan Phil : Sara Jack | Gina
Second Pass Ivan Phil Sara : Jack | Gina
Ivan Phil Jack | Sara Gina
Phil : Ivan Sara | Jack Gina
Third Pass Ivan Phil : Sara | Jack Gina
Ivan Phil | Sara Jack Gina
Phil : Ivan Sara | Jack Gina
Forth Pass Ivan Phil Sara Jack Gina
|
|
As we saw with selection sort, the number of passes needed to sort the
items is one less than the number of items. After all but one of the items
have been ordered, the remaining one must also be in its correct position.
To create a Java method for a bubble sort is fairly easy if we use some
of our previous techniques. To perform all the passes we need a loop like
that of the selection sort.
for (int top = list.length-1; top> 0; top--)
// compare adjacent values of the unsorted sublist
// from 0 to top, exchanging as necessary
Within each pass, the code for comparing and exchanging values in a
sublist is easily written.
for (int i = 0; i < top; i++)
if (list[i] .compareTo(list[i+1]) > 0)
{
temp = list [i];
list[i] = list[i+l];
list[i+l] = temp;
}
Combining these fragments of code and inserting them into a method
gives us a basic bubble sort. We can improve this sort's performance by
noting that, on each pass, we often do more than simply place the greatest
value at the upper end of a sublist; the comparisons and exchanges tend to
push all values toward their final positions in the list. It may happen that
this shuffling of values puts all the values in their final positions before all
passes have been completed. In such a situation, we should stop working
as soon as possible, avoiding any unnecessary passes. As it turns out, this
is not too difficult to do.
Before we incorporate this modification, we must first answer the following
question: how do we know if there is no more work to be done?
The answer is: if no exchanges are performed in an entire pass, then the
items must be fully sorted. The reasoning here is that, if no exchanges are
needed, then each value must be correctly ordered between its immediate
neighbours. It follows that the entire set of values must, therefore, be completely
ordered. Thus we need to perform another pass only if the previous
one carried out one or more exchanges.
To encode this idea in Java, the for statement that controls the number
of passes should now incorporate a test to see if another pass is necessary.
We do this with a boolean variable called sorted. Initially, sorted is
set to false; we do not start a pass unless sorted is false. Once we have
started a pass, we (optimistically) set sorted to true because no exchanges
have yet been performed during that pass. If any exchanges are required
during a pass, we reset sorted to false. Processing continues until sorted
remains true after a full pass or we have completed the maximum number
of passes.
Example 3
This method uses a bubble sort to place an array of strings in ascending
order. It uses a boolean flag, sorted, to make the bubble sort more efficient
.. by stopping the sort after a full pass in which there are no exchanges.
public static void bubbleSort (StringE] list)
{
boolean sorted = false;
for (int top = list.length-1; top> 0 && !sorted; top--)
{
sorted = true;
for (int i = 0; i < top; i++)
if (list [i] .compareTo (list [i +1]) > 0)
{
sorted = false;
String temp = list[i];
list[i] = list[i+1];
list[i+1] ~ temp;
}
}
}
|
|
Although bubble sort uses an interesting technique and has a cute
name, we do not recommend it. It is almost always slower than either of
the sorts that we have already examined because it usually involves far
more data movement than they require.
Exercise 10.5
- Make tables like those shown in Example 2 to show the comparisons
and exchanges that would take place in using a bubble sort to put
the following data in ascending order.
3 8 3 2 7 5
- What changes would have to be made to the bubbleSort method in
order to make it sort values in descending order?
- A modification of the bubble sort is the cocktail shaker sort in which,
on odd-numbered passes, large values are carried to the top of the
list while, on even-numbered passes, small values are carried to the
bottom of the list. Make tables like those shown in Example 2 to
show the first two passes of a cocktail-shaker sort on the following
data.
2 9 4 6 1 7
- Write a method shakerSort to implement the cocktail shaker sort algorithm
to arrange an array of double values in ascending order. Use
a boolean flag to stop processing once the items have been completely
sorted.
| |