03 SortingAlgorithms (Updated)
03 SortingAlgorithms (Updated)
1
Types of Sorting Algorithms
• Non-recursive/Incremental comparison sorting
• Selection sort
• Bubble sort
• Insertion sort
• Recursive comparison sorting
• Merge sort
• Quick sort
• Heap sort
• Non-comparison linear sorting
• Count sort
• Radix sort
2
• Bucket sort
Selection Sort
• Idea:
• Find the smallest element in the array
• Exchange it with the element in the first position
• Find the second smallest element and exchange it with the
element in the second position
• Continue until the array is sorted
8 4 6 9 2 3 1 1 2 3 4 9 6 8
1 4 6 9 2 3 8 1 2 3 4 6 9 8
1 2 6 9 4 3 8 1 2 3 4 6 8 9
3
1 2 3 9 4 6 8 1 2 3 4 6 8 9
Selection Sort Analysis
Alg.: SELECTION-SORT(A) Cost Steps
n ← length[A] c1 1
for j ← 0 to n - 2 c2 n-1
smallest ← j c3 n-1
n2
for i ← j + 1 to n-1 c4 t j
j 0
t j
j 0
smallest ← i c6 n2
t
j 0
j
Disadvantage:
(n2) running time in all cases
5
n2 n2 n2
T (n) c1 c2 (n 1) c3 (n 1) c4 t j c5 t j c6 t j c7 (n 1)
j 0 j 0 j 0
Bubble Sort
Given a list of N elements, repeat the following steps N-1 times:
• For each pair of adjacent numbers, if number on the left is greater than the
number on the right, swap them.
• “Bubble” the largest value to the end using pair-wise comparisons and swapping.
12
6 12
6 22
14 14
22
8 8
17
22 17
22
6 12 14
8 14
8 17 22
6 12
8 8
12 14 17 22
6
6 8 12 14 17 22
Bubble Sort Analysis
BubbleSort(A) cost times
1. n = Length[A]; c1 1
2. for j = 0 to n-2 c2 n-1
n2
3. for i = 0 to n-j-2 c3 t
j 0 j
n2
4. if A[i] > A[i+1] c4 t
j 0 j
c5
n2
5. temp = A[i] t
j 0 j
6. A[i] = A[i+1] c6
n2
t
j 0 j
7. A[i+1] = temp c7
n2
t
j 0 j
8. return A; c8 1
tj: # of times the inner for loop statement is executed at iteration j 7
n2 n2 n2 n2 n2
T (n) c1 c 2 (n 1) c3 t j c 4 t j c5 t j c6 t j c7 t j c8
j 0 j 0 j 0 j 0 j 0
Best/Worst/Average Case Analysis
• Since we don’t know at which iteration the list is completely
sorted, the nested loop will execute completely. n(n 1)
j 0
n2
j
2
an 2 bn c a quadratic function of n
8
n2 n2 n2 n2 n2
T (n) c1 c2 (n 1) c3 t j c4 t j c5 t j c6 t j c7 t j c8
j 0 j 0 j 0 j 0 j 0
Bubble Sort Modified
BubbleSort(A)
1. n = Length[A];
2. for j = 0 to n-2
3. swap = 0;
4. for i = 0 to n-j-2
5. if A[i] > A[i+1]
6. temp = A[i]
7. A[i] = A[i+1]
8. A[i+1] = temp
swap = swap + 1;
9. if swap = 0
10. break;
9
11.return A;
Best Case Analysis (Modified)
• The array is already sorted
• Keep track of no. of swaps done in an iteration
• Can finish early if no swapping occurs
• tj = 1 n – 1 comparisons in a single iteration
= an + b = (n)
10
n2 n2 n2 n2 n2
T (n) c1 c2 (n 1) c3 t j c4 t j c5 t j c6 t j c7 t j c8
j 0 j 0 j 0 j 0 j 0
Worst Case Analysis (Modified)
• The array is in reverse sorted order n(n 1)
n2
j 0
j
• Always A[i] > A[i+1] 2
Advantages Disadvantages
Simple to code (n2) running time in worst & average case
Requires little memory (in-place) Nobody “EVER” uses bubble sort
(EXTREMELY INEFFICIENT)
11
n2 n2 n2 n2 n2
T (n) c1 c2 (n 1) c3 t j c4 t j c5 t j c6 t j c7 t j c8
j 0 j 0 j 0 j 0 j 0
Insertion Sort
• Idea: like sorting a hand of playing cards
• Start with empty left hand and cards face down on the table.
• Remove one card at a time from the table, and insert it into the
correct position in the left hand
• compare it with each card already in the hand, from right to left
• The cards held in the left hand are sorted
• these cards were originally the top cards of the pile on the table
12
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 2.78 7.42 0.56 1.12 1.17 0.32 6.21 4.42 3.14 7.71
13
Iteration 0: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 2.78 7.42 0.56 1.12 1.17 0.32 6.21 4.42 3.14 7.71
14
Iteration 1: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 2.78 0.56
7.42 7.42
0.56 1.12 1.17 0.32 6.21 4.42 3.14 7.71
15
Iteration 2: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 2.78 2.78
0.56 0.56 7.42 1.12 1.17 0.32 6.21 4.42 3.14 7.71
16
Iteration 2: step 1.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 2.78 2.78
0.56 0.56 7.42 1.12 1.17 0.32 6.21 4.42 3.14 7.71
17
Iteration 2: step 2.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 2.78 1.12
7.42 7.42
1.12 1.17 0.32 6.21 4.42 3.14 7.71
18
Iteration 3: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 1.12
2.78 2.78
1.12 7.42 1.17 0.32 6.21 4.42 3.14 7.71
19
Iteration 3: step 1.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 1.12
2.78 2.78
1.12 7.42 1.17 0.32 6.21 4.42 3.14 7.71
20
Iteration 3: step 2.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 1.12 2.78 1.17
7.42 7.42
1.17 0.32 6.21 4.42 3.14 7.71
21
Iteration 4: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 1.12 1.17
2.78 2.78
1.17 7.42 0.32 6.21 4.42 3.14 7.71
22
Iteration 4: step 1.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 1.12 1.17 2.78 7.42 0.32 6.21 4.42 3.14 7.71
23
Iteration 4: step 2.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 1.12 1.17 2.78 0.32
7.42 7.42
0.32 6.21 4.42 3.14 7.71
24
Iteration 5: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 1.12 1.17 0.32
2.78 2.78
0.32 7.42 6.21 4.42 3.14 7.71
25
Iteration 5: step 1.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 1.12 0.32
1.17 1.17
0.32 2.78 7.42 6.21 4.42 3.14 7.71
26
Iteration 5: step 2.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 0.32
1.12 1.12
0.32 1.17 2.78 7.42 6.21 4.42 3.14 7.71
27
Iteration 5: step 3.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 0.56
0.32 0.32 1.12 1.17 2.78 7.42 6.21 4.42 3.14 7.71
28
Iteration 5: step 4.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.56 0.56
0.32 0.32 1.12 1.17 2.78 7.42 6.21 4.42 3.14 7.71
29
Iteration 5: step 5.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 6.21
7.42 7.42
6.21 4.42 3.14 7.71
30
Iteration 6: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 6.21
7.42 7.42
6.21 4.42 3.14 7.71
31
Iteration 6: step 1.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 6.21 4.42
7.42 7.42
4.42 3.14 7.71
32
Iteration 7: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 4.42
6.21 6.21
4.42 7.42 3.14 7.71
33
Iteration 7: step 1.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 4.42
6.21 6.21
4.42 7.42 3.14 7.71
34
Iteration 7: step 2.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 4.42 6.21 3.14
7.42 7.42
3.14 7.71
35
Iteration 8: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 4.42 3.14
6.21 6.21
3.14 7.42 7.71
36
Iteration 8: step 1.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 3.14
4.42 4.42
3.14 6.21 7.42 7.71
37
Iteration 8: step 2.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 3.14
4.42 4.42
3.14 6.21 7.42 7.71
38
Iteration 8: step 3.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 3.14 4.42 6.21 7.42 7.71
39
Iteration 9: step 0.
Insertion Sort
InsertionSort(A, n)
1. for i = 1 to n-1
2. key = A[i]
3. j = i – 1
4. while (j >= 0) and (A[j] > key)
5. A[j+1] = A[j]
6. j = j – 1
7. A[j+1] = key
Array index 0 1 2 3 4 5 6 7 8 9
Value 0.32 0.56 1.12 1.17 2.78 3.14 4.42 6.21 7.42 7.71
40
= an + b = (n)
42
n 1 n 1 n 1
T (n) c1 (n 1) c 2 (n 1) c3 (n 1) c 4 t i c5 t i c6 t i c7 (n 1)
i 1 i 1 i 1
Worst Case Analysis
“while j >= 0 and A[j] > key”
• The array is in reverse sorted order
• The number of moves: 2*(n-1)+(1+2+...+n-1)= 2*(n-1)+ n*(n-1)/2
• The number of key comparisons: (1+2+...+n-1)= n*(n-1)/2
• Always A[j] > key in while loop test
• Have to compare key with all elements to the left of the j-th position
compare with i-1 elements tj = i n 1
n(n 1)
i 1
t i
2
n(n 1)
T (n) c1 (n 1) c 2 (n 1) c3 (n 1) (c 4 c5 c6 ) c7 (n 1)
2
an bn c
2
a quadratic function of n
T(n) = (n2) order of growth in n2
43
n 1 n 1 n 1
T (n) c1 (n 1) c 2 (n 1) c3 (n 1) c 4 t i c5 t i c6 t i c7 (n 1)
i 1 i 1 i 1
Insertion Sort Summary
• Running time not only depends on the size of the array but also
the contents of the array.
• Average-case: O(n2)
• We have to look at all possible initial data organizations.
• Advantages
• Good running time for “almost sorted” arrays (n)
• Disadvantages
• (n2) running time in worst and average case
• n2/2 comparisons and exchanges 44
Types of Sorting Algorithms
• Non-recursive/incremental comparison sorting
• Selection sort
• Bubble sort
• Insertion sort
• Recursive comparison sorting
• Merge sort
• Quick sort
• Heap sort
• Non-comparison linear sorting
• Count sort
• Radix sort
45
• Bucket sort
Recursive Comparison Sorting
There are many ways to design algorithms:
• More specifically:
• Divide the n element sequence to be sorted into two subsequences
of n/2 elements each.
• Conquer: Sort the two subsequences to produce the sorted answer.
• Combine: Merge the two sorted sub sequences to produce the
sorted answer.
47
sort merge(0, n/2, n-1) sort
Merge Sort Pseudocode
48
Merge Sort
Base Case: When the sequences to be sorted has length 1.
Unsorted
Sorted 66
12 108
14 56
34 14
56 89
66 12
89 108
34
Divide
Merge Divide
Merge
66
14 108
56 56
66 108
14 89
12 12
34 34
89
Divide
Merge Divide
Merge Divide
Merge Divide
BCase
Merge
66
66 108
108 56
14 14
56 89
12 12
89 34
Merge
Divide
BCase Divide
BCase
Merge Divide
BCase
Merge Divide
BCase
Merge
49
66 108 56 14 89 12
Merge Function
Given two sorted arrays, merge operation produces a sorted array
with all the elements of the two arrays
8 1 4 3 2
Divide the array in half and conquer
...
1 4 8 2 3
Merge the halves
tempArray: 1 2 3 4 8
copy
Original Array: 1 2 3 4 8
50
Merge Function Pseudocode
51
Merge Sort Analysis
• Advantage:
• Mergesort is an extremely fast algorithm.
• Disadvantage:
• Mergesort requires a second array as large as the original array.
54
Quick Sort
• Quick Sort: orders a list of values by partitioning the list around
one element called a pivot, then sorting each partition. It is based
on divide and conquer approach.
40 37 2
10 18 32 35
12 17 6
partition
6 40
10 12 2 17 18
32 35 37
quicksort quicksort
2 6 10 12 17 18 32 35 37 40
combine 56
2 6 10 12 17 18 32 35 37 40
Quick Sort Pseudocode
57
Partitioning Algorithm
Original input : S = {6, 1, 4, 9, 0, 3, 5, 2, 7, 8}
Pick the first element as pivot
8 1 4 9 0 3 5 2 7 6
pivot
Have two ‘iterators’ – i and j
• i starts at first element and moves forward
• j starts at last element and moves backwards
8 1 4 9 0 3 5 2 7 6
i j pivot
While (i < j)
• Move i to the right till we find a number greater than pivot
• Move j to the left till we find a number smaller than pivot
If (i<j) swap(S[i], S[j]) 58
• The effect is to push larger elements to the right and smaller elements to the left
Swap the pivot with S[i]
Partitioning Algorithm Illustrated
i j pivot
8 1 4 9 0 3 5 2 7 6
Move i j pivot
8 1 4 9 0 3 5 2 7 6
i j pivot
swap
2 1 4 9 0 3 5 8 7 6
i j pivot
move
2 1 4 9 0 3 5 8 7 6
i j pivot
swap
2 1 4 5 0 3 9 8 7 6
move j i pivot i and j
2 1 4 5 0 3 9 8 7 6 have crossed
Swap S[i]
2 1 4 5 0 3 6 8 7 9 59
with pivot
j i
pivot
Partitioning Pseudocode
PARTITION(A, p, r) What is the running time of
1. pivot = A[p]; partition()?
2. leftPointer = p + 1
3. rightPointer = r partition() runs in O(n) time
4. while (True)
5. while (A[leftPointer] < pivot)
6. leftPointer++;
7. while (A[rightPointer] >= pivot)
8. rightPointer--;
9. if leftPointer >= rightPointer
10. break;
11. else
12. A[leftPointer] A[rightPointer]
13. A[leftPointer] pivot 60
Partitioning Algorithm Illustrated
• choose pivot: 436924312189356
• search: 436924312189356
• swap: 433924312189656
• search: 433924312189656
• swap: 433124312989656
• search: 433124312989656
• swap: 433122314989656
• search: 4 3 3 1 2 2 3 1 4 9 8 9 6 5 6 (left > right)
• swap with pivot: 133122344989656
61
Quick Sort: Best Case Analysis
Assuming that keys are random, uniformly distributed.
The best case running time occurs when pivot is the median
• Partition splits array in two sub-arrays of size n/2 at each step
Partition Comparisons
n/2 n/2 n
O (n lg n)
64
Picking the Pivot
• How would you pick one?
65
Picking the Pivot (contd.)
• Strategy 2: Pick the pivot randomly
• Would usually work well, even for mostly sorted input
• Unless the random number generator is not quite random!
• Plus random number generation is an expensive operation
• Pivot
• = Median of S[left], S[right], and S[center]
• = median of 6, 8, and 0
• = S[left] = 6 67
Quick Sort: Final Comments
• What happens when the array contains many duplicate elements?
• Not stable
69
Heap Property
20
Larger than
its parent
15 8
4 10 7 9
Not a Heap
25
Not left-justified 10 12
9 5 11 7
70
1 6 3 8
Maintaining the Heap Property
Suppose a node is smaller than a child, violating heap property. To
maintain heap property, exchange the node with the larger child,
moving the node down the tree until it is not smaller than its children
Alg: MAX-HEAPIFY(A, i, n)
1. l ← LEFT(i)
2. r ← RIGHT(i)
3. if l ≤ n and A[l] > A[i]
4. then largest ←l
5. else largest ←i
6. if r ≤ n and A[r] > A[largest]
7. then largest ←r Complexity of MAX-HEAPIFY()?
8. if largest i
9. then exchange A[i] ↔ A[largest] O(lg n) where lg n is the
71
10. MAX-HEAPIFY(A, largest, n) height of the tree
Array Representation of Heaps
A heap can be stored as an array A.
• Root of tree is A[1] 1 2 3 4 5 6 7 8 9 10
26 24 20 18 17 19 13 12 14 11
• Left child of A[i] = A[2i]
Max-heap as an array
• Right child of A[i] = A[2i + 1]
• Parent of A[i] = A[i/2] 26
• Heapsize[A] ≤ length[A]
24 20
The elements in the subarray
A[(n/2+1) .. n] are leaves
18 17 19 13
Alg: BUILD-MAX-HEAP(A)
1. n = length[A]
2. for i ← n/2 downto 1
O(n)
3. do MAX-HEAPIFY(A, i, n) O(lgn)
1
4
Complexity of BUILD-MAX-HEAP? O(n lgn)
2 3
1 3 73
4 5 6 7
A: 4 1 3 2 16 9 10 14 8 7 2 16 9 10
8 9 10
14 8 7
Example: A: 4 1 3 2 16 9 10 14 8 7
4 4 4
2 3 2 3 2 3
1 3 1 3 1 3
4 5 6 7 4 5 6 7 4 5 6 7
8
2 9 10
16 9 10 8
2 9 10
16 9 10 8
14 9 10
16 9 10
14 8 7 14 8 7 2 8 7
i=2 i=1
1 1 1
4 4 16
2 3 2 3 2 3
1 10 16 10 14 10
4 5 6 7 4 5 6 7 4 5 6 7
8
14 9 10
16 9 3 8
14 9 10
7 9 3 8
8 9 10
7 9 3
2 8 7 2 8 1 2 4 1
74
Heap Sort
A given array which has been heapified does not mean it is sorted
25
22 17
14 21 9 11
The new root has lost heap property. Heapify the new root and
repeat this process until only one node remain. 75
Example: A=[7, 4, 3, 1, 2]
MAX-HEAPIFY(A, 1, 1) 76
Heap Sort Pseudocode
HEAPSORT(A)
1. BUILD-MAX-HEAP(A) O(n)
2. for i ← length[A] downto 2 n-1 times
3. do exchange A[1] ↔ A[i]
4. MAX-HEAPIFY(A, 1, i - 1) O(lgn)
78
Lower Bound For Comparison Sorting
Consider sorting three numbers a1, a2, a3.
There are 3! = 6 possible combinations:
(a1, a2, a3), (a1, a3, a2) , (a3, a2, a1) (a3, a1, a2), (a2, a1, a3) , (a2, a3, a1)
n lg n
80
• Corollary: Quick Sort, Heap Sort and Merge Sort are asymptotically
optimal comparison sorts. Can we do any better than (n lg n)?
Types of Sorting Algorithms
• Non-recursive/incremental comparison sorting
• Selection sort
• Bubble sort
• Insertion sort
• Recursive comparison sorting
• Merge sort
• Quick sort
• Heap sort
• Non-comparison linear sorting
• Count sort
• Radix sort
81
• Bucket sort
Counting Sort
• Assumptions:
• n integers which are in the range [0,k]
• k is in the order of n, that is, k=O(n).
• Idea:
• For each element x, find the number of elements ≤ x
• Place x into its correct position in the output array
82
https://www.cs.usfca.edu/~galles/visualization/CountingSort.html
Counting Sort
1 2 3 4 5 6 7 8
A 2 5 3 0 2 3 0 3 Input Array
0 1 2 3 4 5
C 2 0 2 3 0 1 Auxiliary Array
0 1 2 3 4 5
C 2 2 4 7 7 8
1 2 3 4 5 6 7 8
B 0 0 2 2 3 3 3 5 Output Array
0 1 2 3 4 5
83
C 0
2 2 2
1 3 7
4 4
6 7 7
5 8
Counting Sort
Counting-Sort(A, B, k)
for i = 1 to k
do C[i] = 0 (k)
for j = 1 to length[A]
do C[A[j]] = C[A[j]] + 1 (n)
// C[i] now contains the number of elements = i
for i = 2 to k
do C[i] = C[i] + C[i-1] (k)
// C[i] now contains the number of elements ≤ i
for j = length[A] downto 1
do B[C[A[j]]] = A[j]
C[A[j]] = C[A[j]] - 1 (n)
84
Running time is (n+k) (or (n) if k = O(n))!
Counting Sort
• Is counting sort stable
• The input order is maintained among items with equal keys
• Could we use counting sort to sort 32 bit integers? Why or why not?
• Answer: no, k too large (232 = 4,294,967,296)
85
Radix Sort
• Represents keys as d-digit numbers in some base-k
• key = x1x2...xd where 0≤xi≤k-1
• Example: key=15
• key10 = 15, d=2, k=10 where 0≤xi≤9
• key2 = 1111, d=4, k=2 where 0≤xi≤1
87
88
Bucket Sort
• Assumption:
• Input numbers are uniformly distributed in [0,1).
• Suppose input size is n.
• Idea:
• Divide [0,1) into n equal-sized buckets (k= (n))
• Distribute the n input values into the buckets
• Sort each bucket (insertion sort as default).
• Go through the buckets in order, listing elements in each one
.12 .17 .21 .23 .26 .39 .68 .72 .78 .94 /
Bucket Sort
BUCKET-SORT(A, n)
for i ← 0 to n-1
insert A[i] into list B[⌊n A[i]⌋] O(n)
for i ← 0 to n-1
sort list B[i] with insertion sort O(ni2)
concatenate the lists B[0], B[1], . . ., B[n - 1] in order O(n)
Counting Sort: Very useful when the keys have small range; stable;
memory space for counters and for 2n records.
Radix Sort: Appropriate for keys either rather short or with an
lexicographic collating sequence. 92