Sorting
CSE 225 Data Structures and Algorithms
Sorting
Outline
We are going to look at three simple sorting techniques:
Bubble Sort, Selection Sort and Insertion Sort.
We will write code for Bubble Sort, Selection Sort and
Insertion Sort. We will analyze the running time for
each of the above.
2
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
3
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
4
Code for Bubble Sort
void bubbleSort(int a[], int size) {
int outer, inner;
for (outer = size - 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;
}
}
}
}
5
Analysis of Bubble Sort
for (outer = size - 1; outer > 0; outer--) {
for (inner = 0; inner < outer; inner++) {
if (a[inner] > a[inner + 1]) {
// code for swap omitted
} } }
Let n = 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, that is, O(n2/2) = O(n2)
6
Another sort: 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
7
Example and analysis of Selection Sort
7 2 8 5 4
The Selection Sort might swap an
array element with itself--this is
2 7 8 5 4
harmless, and not worth checking 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
2 4 5 7 8 (swap two array elements)
Time required is roughly (n-1)*(n/2)
You should recognize this as O(n2)
8
Code for Selection Sort
void selectionSort(int a[], int size) {
int outer, inner, min;
for (outer = 0; outer < size - 1; outer++) { // outer counts down
min = outer;
for (inner = outer + 1; inner < size; inner++) {
if (a[inner] < a[min]) {
min = inner;
}
}
// a[min] is least among a[outer]..a[size - 1]
int temp = a[outer];
a[outer] = a[min];
a[min] = temp;
}
}
9
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 20
12 14 14 21 21 38
20 33 33 10
38 55 9 23 28 16
sorted
10
Code for Insertion Sort
void insertionSort(int a[], int size) {
int inner, outer;
for (outer = 1; outer < size; outer++) {
int temp = a[outer];
inner = outer;
while (inner > 0 && a[inner - 1] >= temp) {
a[inner] = a[inner - 1];
inner--;
}
a[inner] = temp;
}
}
11
Insertion Sort – Analysis
Running time depends on not only the size of the array
but also the contents of the array.
Best-case: O(n)
Array is already sorted in ascending order.
Inner loop will not be executed.
Worst-case: O(n2)
Array is in reverse order:
Inner loop is executed i-1 times, for i = 2,3, …, n
Average-case: O(n2)
We have to look at all possible initial data organizations.
So, Insertion Sort is O(n2)
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
13
Divide and Conquer
Recursive in structure
Divide the problem into sub-problems that are similar
to the original but smaller in size
Conquer the sub-problems by solving them recursively.
If they are small enough, just solve them in a
straightforward manner.
Combine the solutions to create a solution to the
original problem
An Example: Merge Sort
Sorting Problem: Sort a sequence of n elements into
non-decreasing order.
Divide: Divide the n-element sequence to be
sorted into two subsequences of n/2 elements each
Conquer: Sort the two subsequences recursively
using merge sort.
Combine: Merge the two sorted subsequences to
produce the sorted answer.
Merge Sort – Example
Original Sequence Sorted Sequence
18 26 32 6 43 15 9 1 1 6 9 15 18 26 32 43
18 26 32 6 43 15 9 1 6 18 26 32 1 9 15 43
43
18 26 32 6 43 15 9 1 18 26 6 32 15 43 1 9
18 26 32 6 43 15 9 1 18 26 32 6 43 15 9 1
18 26 32 6 43 15 9 1
Merge-Sort (A, p, r)
INPUT: a sequence of n numbers stored in array A
OUTPUT: an ordered sequence of n numbers
MergeSort (A, p, r) // sort A[p..r] by divide & conquer
1 if p < r
2 then q (p+r)/2
3 MergeSort (A, p, q)
4 MergeSort (A, q+1, r)
5 Merge (A, p, q, r) // merges A[p..q] with A[q+1..r]
Initial Call: MergeSort(A, 1, n)
Procedure Merge
Merge(A, p, q, r)
1 Copy two sorted sub arrays of A into L and R
2 i1
3 j1 Input: Array containing
4 for k p to r sorted subarrays A[p..q] and
5 do if L[i] R[j] A[q+1..r].
6 then A[k] L[i]
Output: Merged sorted
7 ii+1
subarray in A[p..r].
8 else A[k] R[j]
9 jj+1
Merging two sorted arrays
20 12
13 11
7 9
2 1
Merging two sorted arrays
20 12
13 11
7 9
2 1
1
Merging two sorted arrays
20 12 20 12
13 11 13 11
7 9 7 9
2 1 2
1
Merging two sorted arrays
20 12 20 12
13 11 13 11
7 9 7 9
2 1 2
1 2
Merging two sorted arrays
20 12 20 12 20 12
13 11 13 11 13 11
7 9 7 9 7 9
2 1 2
1 2
Merging two sorted arrays
20 12 20 12 20 12
13 11 13 11 13 11
7 9 7 9 7 9
2 1 2
1 2 7
Merging two sorted arrays
20 12 20 12 20 12 20 12
13 11 13 11 13 11 13 11
7 9 7 9 7 9 9
2 1 2
1 2 7
Merging two sorted arrays
20 12 20 12 20 12 20 12
13 11 13 11 13 11 13 11
7 9 7 9 7 9 9
2 1 2
1 2 7 9
Merging two sorted arrays
20 12 20 12 20 12 20 12 20 12
13 11 13 11 13 11 13 11 13 11
7 9 7 9 7 9 9
2 1 2
1 2 7 9
Merging two sorted arrays
20 12 20 12 20 12 20 12 20 12
13 11 13 11 13 11 13 11 13 11
7 9 7 9 7 9 9
2 1 2
1 2 7 9 11
Merging two sorted arrays
20 12 20 12 20 12 20 12 20 12 20 12
13 11 13 11 13 11 13 11 13 11 13
7 9 7 9 7 9 9
2 1 2
1 2 7 9 11
Merging two sorted arrays
20 12 20 12 20 12 20 12 20 12 20 12
13 11 13 11 13 11 13 11 13 11 13
7 9 7 9 7 9 9
2 1 2
1 2 7 9 11 12
Merging two sorted arrays
20 12 20 12 20 12 20 12 20 12 20 12
13 11 13 11 13 11 13 11 13 11 13
7 9 7 9 7 9 9
2 1 2
1 2 7 9 11 12
Time = (n) to merge a total of n elements
(linear time).