0% found this document useful (0 votes)
15 views82 pages

Chapter 7 - Sorting

Chapter 7 discusses sorting, a fundamental data-processing application that arranges items in a specific order based on designated sort keys. It covers types of sorting such as internal and external sorts, sort stability, and sort efficiency, along with examples of algorithms like selection sort and heap sort. The chapter provides detailed steps and complexities associated with these sorting methods.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views82 pages

Chapter 7 - Sorting

Chapter 7 discusses sorting, a fundamental data-processing application that arranges items in a specific order based on designated sort keys. It covers types of sorting such as internal and external sorts, sort stability, and sort efficiency, along with examples of algorithms like selection sort and heap sort. The chapter provides detailed steps and complexities associated with these sorting methods.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 82

Chapter 7

Sorting
Sorting
One of the most common data-processing applications

The process of arranging a collection of items/records in a specific order

The items/records consist of one or more fields or members

One of these fields is designated as the "sort key" in which the records are ordered

Sort order: Data may be sorted in either ascending sequence or descending


sequence
Sorting

Input Output

A sequence of numbers A permutation of the sequence of


a1, a2, a3, a4, ... , an Sorting numbers
b1, b2, b3, b4, ... , bn

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

212 green 212 green 212 blue

876 white 212 yellow 212 green

212 yellow 212 blue 212 yellow

119 purple 365 blue 365 blue

212 blue 876 white 876 white

Unsorted data Stable sort Unstable sort


Sorting
Sort efficiency

● A measure of the relative efficiency of a sort


● Usually an estimate of the number of comparisons and moves required to
order an unordered list

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

algorithms ● Merge Sort

● Heap Sort
Selection sort
Among the most intuitive of all sorting algorithms

Basic idea

● Given a list of data to be sorted,


○ Select the smallest item and place it in a sorted list
○ Repeat until all of the data are sorted
Straight selection sort
The list at any moment is divided into two sublists, sorted and unsorted, which are
divided by an imaginary wall

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]

Heap in its array form


45 8 23 19
(First element = Largest element)
Heap sort
Heap sort is among the fastest sorting algorithms.

Used with very large arrays

Steps:

1. Convert the array into a max heap


2. Find the largest element of the list (i.e., the root of the heap) and then place it
at the end of the list. Decrement the heap size by 1 and readjust the heap
3. Repeat Step 2 until the unsorted list is empty
Heap sort
Example:

Sort the following data using heap sort:

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

[3] [4] [5]


Heap sort
Convert the array into a max heap
8
8 32 45 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

[3] [4] [5]


Heap sort
Convert the array into a max heap
8
8 32 45 78 23 56

[0]

32 45

[1] [2] Heap property is not satisfied

78 23 56

[3] [4] [5]


Heap sort
Convert the array into a max heap
8
8 32 56 78 23 45

[0]

32 56

[1] [2] Heap property is not satisfied. Therefore, swap them

78 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
8
8 32 56 78 23 45

[0]

32 56

[1] [2]

78 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
8
8 32 56 78 23 45

[0]

32 56

[1] [2]

78 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
8
8 32 56 78 23 45

[0]

32 56

[1] [2] Swap the root with the largest child

78 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
8
8 78 56 32 23 45

[0]

78 56

[1] [2] Swap the root with the largest child

32 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
8
8 78 56 32 23 45

[0]

78 56

[1] [2]

32 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
8
8 78 56 32 23 45

[0]

78 56

[1] [2] Swap the root with the largest child

32 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
78
78 8 56 32 23 45

[0]

8 56

[1] [2] Swap the root with the largest child

32 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
78
78 8 56 32 23 45

[0]

8 56

[1] [2] Swap the root with the largest child

32 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
78
78 32 56 8 23 45

[0]

32 56

[1] [2] Swap the root with the largest child

8 23 45

[3] [4] [5]


Heap sort
Convert the array into a max heap
78
78 32 56 8 23 45

[0]

32 56

[1] [2]

8 23 45

[3] [4] [5]


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.

78

[0]

32 56

[1] [2]

8 23 45

[3] [4] [5]


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.

78

[0]

32 56

[1] [2]

8 23 45

[3] [4] [5]


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 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:

1. n = length of a 8. if r < n and a[largest] < a[ r ]:


2. largest = i 9. largest = r
3. l=2*i+1 10. endif
4. r=2*i+2 11. if largest != i:
5. if l < n and a[ i ] < a[ l ] 12. swap a[ i ] and a[ largest ]
6. largest = l 13. heapify(a, n, largest)
7. endif 14. endif
Heap sort
Algorithm: build_heap( a )
Input: An array a

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:

The list is divided into two parts: sorted and unsorted

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

Worst case time complexity: O(n2)


Best case time complexity: O(n)
Merge sort
Merge sort uses divide-and-conquer strategy

● The original problem is partitioned into simpler sub-problems, each sub


problem is considered independently.
● Subdivision continues until sub problems obtained are simple.

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

Input sorted lists

7 14 3 12

3 7 12 14

Merged sorted list


Algorithm: merge(L, R)
Input: Two sorted lists, L and R
Output: Merged sorted list, a

Steps:

1. i=j=k=0 8. else 14. Copy the remaining


2. n1 = length of L 9. a[k] = R[ j] elements of L to a, if
3. n2 = length of R 10. j++ there are any
4. while (i < n1 and j < n2) 11. end if 15. Copy the remaining
5. if (L[i] ≤ R[ j]) 12. k++ elements of R to a, if
6. a[k] = L[i] 13. end while there are any
7. i++
merge(L, R)
Example: Input sorted lists L= 7 14 R= 3 12

k i j Comparison a

0 0 0 L[0] ≤ R[0] False 3


merge(L, R)
Example: Input sorted lists L= 7 14 R= 3 12

k i j Comparison a

0 0 0 L[0] ≤ R[0] False 3

1 0 1 L[0] ≤ R[1] True 3 7


merge(L, R)
Example: Input sorted lists L= 7 14 R= 3 12

k i j Comparison a

0 0 0 L[0] ≤ R[0] False 3

1 0 1 L[0] ≤ R[1] True 3 7

2 1 1 L[1] ≤ R[1] False 3 7 12


merge(L, R)
Example: Input sorted lists L= 7 14 R= 3 12

k i j Comparison a

0 0 0 L[0] ≤ R[0] False 3

1 0 1 L[0] ≤ R[1] True 3 7

2 1 1 L[1] ≤ R[1] False 3 7 12

3 2 1 - (Copy the remaining data) 3 7 12 14


Algorithm: mergeSort(a)
Complexity of merge sort = O(n log n)
Input: An unsorted list, a
Output: The sorted list, a
5. # Divide Complexity = ?
Steps: 6. mid = ⌊n/2⌋
7. Copy a[0] to a[mid] to L
1. n = length of a 8. Copy a[mid+1] to a[n-1] to R
2. if n == 1 9. # Recur Complexity = ?
3. return a 10. L = mergeSort(L)
4. end if 11. R = mergeSort(R)
12. #Conquer Complexity = ?
13. merge(L, R)
Algorithm: mergeSort(a)
Complexity of merge sort = O(n log n)
Input: An unsorted list, a
Output: The sorted list, a
5. # Divide Complexity = O(1)
Steps: 6. mid = ⌊n/2⌋
7. Copy a[0] to a[mid] to L
1. n = length of a 8. Copy a[mid+1] to a[n-1] to R
2. if n == 1 9. # Recur Complexity = O(n.logn)
3. return a 10. L = mergeSort(L)
4. end if 11. R = mergeSort(R)
12. #Conquer Complexity = O(n)
13. merge(L, R)
Quick Sort
Like merge sort, quick sort also uses divide-and-conquer paradigm

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:

● Always pick first element as pivot


● Always pick last element as pivot
● Pick a random element as pivot
● Pick median as pivot
Quick sort
Algorithm: QuickSort(a, low, high)
Input: An unsorted list a[low … high]
Output: The list a after sorting

Steps:

1. If low < high then # If there are more than 1 element


2. pivot ≔ Partition (a, low, high)
3. Quick Sort (a, low, pivot - 1)
4. Quick Sort (a, pivot + 1, high)
5. end if
Quick sort
Algorithm: Partition(a, low, high)
Input: An unsorted list, a, whose elements 4. while i < j do
from index low to index high are to be 5. Repeat j ← j-1 until a[ j] < pi
partitioned 6. Repeat i ← i+1 until a[i] > pi
Output: The index of the pivot that partitions a 7. if i < j
into two sublists 8. exchange a[i] ↔ a[ j]
9. end if
Steps:
10. end while
1. pi ← a[low] # Pivot = First element 11. exchange a[low] ↔ a[ j]
2. i ← low 12. return j # j = position of pivot
3. j ← high + 1
Quick sort example
Input: 26 5 37 1 61 11 59 15 48 19

Pivot = The first element in the list 26

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

Exchange a[2] and a[9]


Quick sort example
Input: 26 5 37 1 61 11 59 15 48 19

Pivot = The first element in the list 26

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

Exchange a[4] and a[7]


Quick sort example
Input: 26 5 37 1 61 11 59 15 48 19

Pivot = The first element in the list 26

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

Pivot = The first element in the list 26

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 Exchange a[0] and a[5]


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
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.

Quicksort works in place.

In practice, quicksort outperforms merge sort, and it significantly outperforms


selection sort and insertion sort.
Stability

Algorithm Stable ?

Selection sort No

Insertion sort Yes

Heap sort No

Merge sort Yes

Quick sort No

You might also like