Chapter 7 - Sorting
Chapter 7 - Sorting
Sorting
Sorting
One of the most common data-processing applications
One of these fields is designated as the "sort key" in which the records are ordered
Input Output
Example: 2 5 6 1 12 10 Example: 1 2 5 6 10 12
Sorting
Types
1. Internal sort
○ All of the data are held in primary memory during the sorting process
○ Examples: Insertion, selection, heap, bubble, quick, shell sort
2. External sort
○ Uses primary memory for the data currently being sorted and secondary
storage for any data that does not fit in primary memory
○ Examples: merge sort
Sorting
Sort stability
Indicates that data with equal keys maintain their relative input order in the output
365 blue 119 purple 119 purple
Passes
During the sort process, the data are traversed many times. Each traversal of the
data is referred to as a sort pass
● Selection Sort
● Insertion Sort
Sorting ● Quick Sort
● Heap Sort
Selection sort
Among the most intuitive of all sorting algorithms
Basic idea
Steps:
1. Select the smallest element from the unsorted sublist and exchange it with the
element at the beginning of the unsorted data
2. Repeat Step 1 until there is no element in the unsorted sublist
Each time we move one element from the unsorted sublist to the sorted sublist, we
say that we have completed one sort pass. Therefore, a list of n elements need n-1
passes to completely rearrange the data
Straight selection sort
Straight selection sort
Algorithm: selectionSort ( a )
Input: An unordered array a
Steps:
1. n = length of a
2. for (i = 0; i < n - 1; i++)
3. min_index = i
4. for ( j = i + 1; j < n; j++) # Find minimum
5. if ( a[ j ] < a[ min_index] )
8. end for
6. min_index = j
9. Swap a[min_index] and a[ i ]
7. endif
10. end for
Straight selection sort
Algorithm: selectionSort ( a )
Input: An unordered array a
Steps:
Complexity of selection sort = O(n2)
1. n = length of a
2. for (i = 0; i < n - 1; i++)
3. min_index = i
4. for ( j = i + 1; j < n; j++) # Find minimum
5. if ( a[ j ] < a[ min_index] )
8. end for
6. min_index = j
9. Swap a[min_index] and a[ i ]
7. endif
10. end for
Heap sort
Recall: Heap is a nearly complete binary tree in which the root contains the largest
(or smallest) element in the tree. It is completely filled on all levels except possibly
the lowest, which is filled from the left up to a point.
78
78 56 32 45 8 23 19
56 32
[0] [1] [2] [3] [4] [5] [6]
Steps:
8 32 45 78 23 56
Heap sort
Convert the array into a max heap
8
8 32 45 78 23 56
[0]
32 45
[1] [2]
78 23 56
[0]
Starting from the index, i, of the node just
32 45 above the leaf level, check if the tree starting
at i is a max-heap. If not, fix it (by reheap down)
[1] [2]
78 23 56
[0]
32 45
78 23 56
[0]
32 56
78 23 45
[0]
32 56
[1] [2]
78 23 45
[0]
32 56
[1] [2]
78 23 45
[0]
32 56
78 23 45
[0]
78 56
32 23 45
[0]
78 56
[1] [2]
32 23 45
[0]
78 56
32 23 45
[0]
8 56
32 23 45
[0]
8 56
32 23 45
[0]
32 56
8 23 45
[0]
32 56
[1] [2]
8 23 45
78
[0]
32 56
[1] [2]
8 23 45
78
[0]
32 56
[1] [2]
8 23 45
45
[0]
32 56
[1] [2]
8 23 78
[3] [4]
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
56
[0]
32 45
[1] [2]
8 23 78
[3] [4]
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
56
[0]
32 45
[1] [2]
8 23 78
[3] [4]
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
56
[0]
32 45
[1] [2]
8 23 78
[3] [4]
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
23
[0]
32 45
[1] [2]
8 56 78
[3] [4]
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
45
[0]
32 23
[1] [2]
8 56 78
[3] [4]
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
45
[0]
32 23
[1] [2]
8 56 78
[3]
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
45
[0]
32 23
[1] [2]
8 56 78
[3]
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
[0]
32 23
[1] [2]
45 56 78
[3]
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
32
[0]
8 23
[1] [2]
45 56 78
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
32
[0]
8 23
[1] [2]
45 56 78
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
32
[0]
8 23
[1] [2]
45 56 78
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
23
[0]
8 32
[1] [2]
45 56 78
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
23
[0]
8 32
[1]
45 56 78
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
23
[0]
8 32
[1]
45 56 78
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
[0]
23 32
[1]
45 56 78
Swap the root of the heap with the
element at the end of the list. Decrement
Heap sort the heap size by 1 and readjust the heap.
[0]
23 32
45 56 78
Heap sort
Algorithm: heapSort ( a )
Input: An unordered array a
Steps:
1. n = length of a
2. build_heap( a ) # Complexity: ? ; Nb execution: ?
3. for (i = n - 1; i > 0; i--)
4. Swap arr[i] and arr[0]
5. heapify(a, i, 0) # Complexity: ? ; Nb execution: ?
6. end for
Heap sort
Algorithm: Heapify(a, n, i)
Input: An array a of size n, and the root index i
Steps:
Steps:
1. n = size of a
2. for i from n - 1 to 0
3. heapify(a, n, i)
Heap sort
Algorithm: heapSort ( a )
Input: An unordered array a
Steps:
1. n = length of a
2. build_heap( a ) # Complexity: O(n) ; Nb execution: 1
3. for (i = n - 1; i > 0; i--)
4. Swap arr[i] and arr[0]
5. heapify(a, i, 0) # Complexity: O(log n) ; Nb execution: n - 1
6. end for
Complexity of heap sort = O(n + n log n) = O(n log n)
Insertion Sort
One of the most common sorting techniques used by card players. As they pick up
each card, they insert it into the proper sequence in their hand.
Main idea:
In each pass of an insertion sort, the first element of the unsorted sublist is inserted
into its correct location in the sorted sublist
Insertion sort
Example
Insertion sort
Algorithm: InsertionSort(a)
Input: An unsorted list, a
Output: The list a after sorting
6. while i ≥ 0 and a[i] > key
1. n ← length[a] 7. a[i +1] ← a[i]
2. for j ← 1 to n - 1 8. i←i−1
3. key ← a[ j] 9. end while
4. # Put a[ j] into the sorted sequence 10. a[i + 1] ← key
a[0 . . j − 1] 11. end for
5. i←j−1
Insertion sort
Algorithm: InsertionSort(a)
Input: An unsorted list, a
Output: The list a after sorting
6. while i ≥ 0 and a[i] > key
1. n ← length[a] 7. a[i +1] ← a[i]
2. for j ← 1 to n - 1 8. i←i−1
3. key ← a[ j] 9. end while
4. # Put a[ j] into the sorted sequence 10. a[i + 1] ← key
a[0 . . j − 1] 11. end for
5. i←j−1
Steps:
1. Divide: partition the list into two roughly equal parts, S1 and S2, called the left
and the right sublists
2. Conquer: recursively sort S1 and S2
3. Combine: merge the sorted sublists.
Merge Sort
Example
Merge sort
Merging two sorted lists into one
7 14 3 12
3 7 12 14
Steps:
k i j Comparison a
k i j Comparison a
k i j Comparison a
k i j Comparison a
Steps:
1. Divide: Select any element from the list. Call it the pivot. Then partition the list
into two non-empty sublists such that all the elements in the left sublist are less
than or equal to the pivot and those of the right sublist are greater than or
equal to the pivot
2. Conquer: Recursively sort the two sublists
3. Combine: Since the subarrays are sorted in place, no work is needed to
combine them: the entire list is now sorted.
Quick sort
A pivot can be picked in different ways:
Steps:
Partition: Starting with i = 0 , j = 10, find the index i of the element larger than pivot
and the index j of the element smaller than the pivot. Then exchange them if i < j
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] i j
26 5 37 1 61 11 59 15 48 19 2 9
Partition: Starting with i = 0 , j = 10, find the index i of the element larger than pivot
and the index j of the element smaller than the pivot. Then exchange them if i < j
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] i j
26 5 37 1 61 11 59 15 48 19 2 9
26 5 19 1 61 11 59 15 48 37 4 7
Partition: Starting with i = 0 , j = 10, find the index i of the element larger than pivot
and the index j of the element smaller than the pivot. Then exchange them if i < j
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] i j
26 5 37 1 61 11 59 15 48 19 2 9
26 5 19 1 61 11 59 15 48 37 4 7
26 5 19 1 15 11 59 61 48 37 6 5 i>j
Quick sort example
Input: 26 5 37 1 61 11 59 15 48 19
Partition: Starting with i = 0 , j = 10, find the index i of the element larger than pivot
and the index j of the element smaller than the pivot. Then exchange them if i < j
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] i j
26 5 37 1 61 11 59 15 48 19 2 9
26 5 19 1 61 11 59 15 48 37 4 7
26 5 19 1 15 11 59 61 48 37 6 5 i>j
11 5 19 1 15 26 59 61 48 37 0 9
Quick sort example
Similarly, partitioning the sublists recursively, we obtain the following result:
low high
11 5 19 1 15 26 59 61 48 37 0 9
1 5 11 19 15 26 59 61 48 37 0 4
Quick sort example
Similarly, partitioning the sublists recursively, we obtain the following result:
low high
11 5 19 1 15 26 59 61 48 37 0 9
1 5 11 19 15 26 59 61 48 37 0 4
1 5 11 19 15 26 59 61 48 37 0 1
Quick sort example
Similarly, partitioning the sublists recursively, we obtain the following result:
low high
11 5 19 1 15 26 59 61 48 37 0 9
1 5 11 19 15 26 59 61 48 37 0 4
1 5 11 19 15 26 59 61 48 37 0 1
1 5 11 15 19 26 59 61 48 37 3 4
Quick sort example
Similarly, partitioning the sublists recursively, we obtain the following result:
low high
11 5 19 1 15 26 59 61 48 37 0 9
1 5 11 19 15 26 59 61 48 37 0 4
1 5 11 19 15 26 59 61 48 37 0 1
1 5 11 15 19 26 59 61 48 37 3 4
1 5 11 15 19 26 48 37 59 61 6 9
1 5 11 15 19 26 37 48 59 61 6 7
1 5 11 15 19 26 37 48 59 61 9 9
1 5 11 15 19 26 37 48 59 61
Quick sort performance
Best case, i.e. when the partition() always picks the middle element as pivot:
O(n log2n)
Worst-case, i.e., when the list already is ordered but in reverse order:
O(n2)
Average case:
O(n log2n)
Quick sort
Differences from merge sort
In merge sort, the divide step does hardly anything, and all the real work happens
in the combine step whereas in quick sort, the real work happens in the divide step.
Algorithm Stable ?
Selection sort No
Heap sort No
Quick sort No