Arrays and Sorting
Arrays and Sorting
Arrays
• Java arrays are objects
– must be accessed via handles
• Defining an array
Type [] name
• Where:
– Type specifies the•This
kinddeclares
of values the
the arrayonly
handle stores
– the brackets [ ] indicate
•Initialized
thistoisnull
an array
– name is the handle
•Stores an address
to access the array when arrays are
created
Definitions Using Array Literals
• Used when exact size and initial values of an
array are known in advance
– used to initialize the array handle
int [] count = { 0,0,0,0}
Visualize the results of the above command
return result;
}
Array Equality
• Java has an equals() method for classes
if (a1.equals(a2)) …
• If a1 and a2 are arrays, the equals() method
just looks at the addresses the handles point to
• They could be pointing to different addresses but the
contents of the array still be equal
– It is the contents that we really wish to compare
Array Equality
• We must write our own method to compare the arrays
– they both must have the same length
– then use a for( ) loop to compare element by element for
equality
if (list1.length==list2.length)
{
for (int i = 0; i < list1.length; i++)
if (list1[i] != list2[i])
return false;
return true;
}
Else As soon as one pair of elements is found
{
return false; not equal, the method returns false
}
Simple Sorting Algorithms
Review of Complexity
Most of the primary sorting algorithms run on different space and
time complexity.
● Bubble Sort = n²
● Selection Sort = n²
● Insertion Sort = n²
● Merge Sort = n log(n)
●Quick Sort = n log(n)
Bubble sort
• Compare each element (except the last one) with its
neighbor to the right
– If they are out of order, swap them
– This puts the largest element at the very end
– The last element is now in the correct and final place
• Compare each element (except the last two) with its
neighbor to the right
– If they are out of order, swap them
– This puts the second largest element next to last
– The last two elements are now in their correct and final places
• Compare each element (except the last three) with its
neighbor to the right
– Continue as above until you have no unsorted elements on the left
21
Example of bubble sort
7 2 8 5 4 2 7 5 4 8 2 5 4 7 8 2 4 5 7 8
2 7 8 5 4 2 7 5 4 8 2 5 4 7 8 2 4 5 7 8
2 7 8 5 4 2 5 7 4 8 2 4 5 7 8 (done)
2 7 5 8 4 2 5 4 7 8
2 7 5 4 8
22
Practice bubble sort
23
Practice bubble sort
24
Code for bubble sort
• public static void bubbleSort(int[] a) {
int outer, inner;
for (outer = a.length - 1; outer > 0; outer--) { // counting down
for (inner = 0; inner < outer; inner++) { // bubbling up
if (a[inner] > a[inner + 1]) { // if out of order...
int temp = a[inner]; // ...then swap
a[inner] = a[inner + 1];
a[inner + 1] = temp;
}
}
}
}
25
Analysis of bubble sort
• for (outer = a.length - 1; outer > 0; outer--) {
for (inner = 0; inner < outer; inner++) {
if (a[inner] > a[inner + 1]) {
// code for swap omitted
}
}
}
• Let n = a.length = size of the array
• The outer loop is executed n-1 times (call it n, that’s close enough)
• Each time the outer loop is executed, the inner loop is executed
– Inner loop executes n-1 times at first, linearly dropping to just
once
– On average, inner loop executes about n/2 times for each
execution of the outer loop
– In the inner loop, the comparison is always done (constant time),
the swap might be done (also constant time)
• Result is n * n/2 * k, that is, O(n2/2 + k) = O(n2)
26
Loop invariants
• You run a loop in order to change things
• Oddly enough, what is usually most important in
understanding a loop is finding an invariant: that is, a
condition that doesn’t change
• In bubble sort, we put the largest elements at the end, and
once we put them there, we don’t move them again
– The variable outer starts at the last index in the array and decreases
to 0
– Our invariant is: Every element to the right of outer is in the correct
place
– That is, for all j > outer, if i < j, then a[i] <= a[j]
– When this is combined with outer == 0, we know that all elements of
the array are in the correct place
27
Bubble Sort
• Bubble Sort = N2
Selection sort
• Given an array of length n,
– Search elements 0 through n-1 and select the smallest
• Swap it with the element in location 0
– Search elements 1 through n-1 and select the smallest
• Swap it with the element in location 1
– Search elements 2 through n-1 and select the smallest
• Swap it with the element in location 2
– Search elements 3 through n-1 and select the smallest
• Swap it with the element in location 3
– Continue in this fashion until there’s nothing left to search
29
Example and analysis of selection sort
• The selection sort might swap an
7 2 8 5 4 array element with itself--this is
harmless, and not worth checking
2 7 8 5 4 for
• Analysis:
2 4 8 5 7 – The outer loop executes n-1 times
– The inner loop executes about n/2
2 4 5 8 7 times on average (from n to 2 times)
– Work done in the inner loop is
constant (swap two array elements)
2 4 5 7 8
– Time required is roughly (n-1)*(n/2)
– You should recognize this as O(n2)
30
Practice selection sort
31
Code for selection sort
public static void selectionSort(int[] a) {
int outer, inner, min;
for (outer = 0; outer < a.length - 1; outer++) { // outer counts up
min = outer;
for (inner = outer + 1; inner < a.length; inner++) {
if (a[inner] < a[min]) {
min = inner;
}
// Invariant: for all i, if outer <= i <= inner, then a[min] <= a[i]
}
// a[min] is least among a[outer]..a[a.length - 1]
int temp = a[outer];
a[outer] = a[min];
a[min] = temp;
// Invariant: for all i <= outer, if i < j then a[i] <= a[j]
}
}
32
Invariants for selection sort
• For the inner loop:
– This loop searches through the array, incrementing inner from
its initial value of outer+1 up to a.length-1
– As the loop proceeds, min is set to the index of the smallest
number found so far
– Our invariant is:
for all i such that outer <= i <= inner, a[min] <= a[i]
• For the outer (enclosing) loop:
– The loop counts up from outer = 0
– Each time through the loop, the minimum remaining value is
put in a[outer]
– Our invariant is:
for all i <= outer, if i < j then a[i] <= a[j]
33
Selection Sort
Selection Sort
• Selection Sort = N2
Insertion Sort
Insertion Sort
Insertion sort
• The outer loop of insertion sort is:
for (outer = 1; outer < a.length; outer++) {...}
• The invariant is that all the elements to the left of outer
are sorted with respect to one another
– For all i < outer, j < outer, if i < j then a[i] <= a[j]
– This does not mean they are all in their final correct place; the
remaining array elements may need to be inserted
– When we increase outer, a[outer-1] becomes to its left; we must
keep the invariant true by inserting a[outer-1] into its proper
place
– This means:
• Finding the element’s proper place
• Making room for the inserted element (by shifting over other
elements)
• Inserting the element
38
insertion sort
One step of insertion sort
sorted next to be inserted
3 4 7 12 14 14 20 21 33 38 10 55 9 23 28 16
temp
less than 10
10
3 4 7 10 12 14 14 20 21 33 38 55 9 23 28 16
sorted
40
Practice selection sort
42, 20, 17, 13, 28, 14, 23, 15
Practice selection sort
Analysis of insertion sort
• We run once through the outer loop, inserting
each of n elements; this is a factor of n
• On average, there are n/2 elements already
sorted
– The inner loop looks at (and moves) half of these
– This gives a second factor of n/4
• Hence, the time required for an insertion sort of
an array of n elements is proportional to n2/4
• Discarding constants, we find that insertion sort is
O(n2)
43
Summary
• Bubble sort, selection sort, and insertion sort are all O(n2)
• As we will see later, we can do much better than this with
somewhat more complicated sorting algorithms
• Within O(n2),
– Bubble sort is very slow, and should probably never be used for
anything
– Selection sort is intermediate in speed
– Insertion sort is usually the fastest of the three--in fact, for small
arrays (say, 10 or 15 elements), insertion sort is faster than more
complicated sorting algorithms
• Selection sort and insertion sort are “good enough” for small
arrays
44