Chapter 7
Chapter 7
Sorting
Sorting
Sorting
Applications of sorting:
searching - searching
- list verification
Given a list of records (R0, R1,…., Rn-1),
h d R h k l K
- each record, Ri, has a key value Ki - ordering relation (<) on the keys
• Sorting is to find a permutationSorting is to find a permutation σ such thatσ such that Kσ(i-1) <= Kσ(i) , 0 < i <= n-1
> d d i (R R R )
-> produce ordering (Rσ(0), Rσ(1),…., Rσ(n-1))
Structure of records
typedef struct element{
typedef struct element{
int key;
/* th fi ld */
/* other field */
} element;
element list[MAX_SIZE];
Characteristics of sorting
• Internal sort: the list is small enough to sort g entirely in main memory
- bubble sort, insertion sort, quick sort, , , q , heap sort, merge sort
• External sort: too much information to fit into main memoryy
- the file must be brought into the main memory in pieces until the entire file is y p sorted
Insertion Sort
• For i=2 to n,
for the sequence of already ordered records, R1 R2 Ri 1 insert Ri so that the resulting
R1, R2,…., Ri-1, insert Ri so that the resulting sequence is also ordered
- n = 5, input sequence (3, 2, 5, 4, 1)
i [1] [2] [3] [4] [5]
i [1] [2] [3] [4] [5]
- 2
3 2
2 3
5 5
4 4
1 1 3
4 5
2 2 1
3 3 2
5 4 3
4 5 4
1 1 5
Insertion Sort
void insertion_sort(element a[ ], int n) { /* sort a[1:n] into nondecreasing order */
int i, j; element temp;, j; p;
for (i = 2; i <=n; i++) { temp = a[i];
temp a[i];
for (j = i - 1; j >= 1 && temp.key < a[j].key; j--) a[j + 1] = a[j];
a[j 1] a[j];
a[j + 1] = temp;
}}
}
time complexity worst case: O(1+2+ +n-1) = O(n2)
time complexity worst case: O(1+2+…+n-1) = O(n )
Example
- Worst case behavior of insertion sort n = 5 input sequence: (5 4 3 2 1) n = 5, input sequence: (5, 4, 3, 2, 1)
• Good to use when only a few records are out of
• Good to use when only a few records are out of order
ex) n = 5 input sequence: (2 3 4 5 1) ex) n = 5, input sequence: (2, 3, 4, 5, 1)
• Also good for small lists
• Also good for small lists
Divide and Conquer
• Three steps in Divide and Conquer methodp q
Divide the problem into a number of Divide the problem into a number of
subprolems
C th b bl If it i t till
Conquer the subproblems. If it is not still difficult, then solve them recursively
Combine the solutions to the subproblems into the solution for the original problem
Quick Sort
• divide and conquer
• use recursion
• Best average time - O(n·logBest, average time O(n log22n)n)
• Worst time: O(n2)
D ’t d dditi l
• Don’t need additional space
X
pivot elements
smaller than pivot
elements larger than pivot
Quick Sort
the first element the first element
0 1 n-1
greater than pivot smaller than pivot
X : pivot swap
X’ X
new pivot
X’ X
··
· X
sorted X
sorted
Quick Sort
void quicksort(element a[ ], int left, int right) { int pivot i j;
int pivot, i, j;
element temp;
if (left < right) {
i = left; j = right + 1;
pivot = a[left].key;
d { do {
:
} while (i < j);
swap(a[left], a[j], temp);
i k t( l ft j 1) quicksort(a, left, j-1);
quicksort(a, j+1, right);
}}
}
Quick Sort
do { do
i++;
while (a[i].key < pivot);
do jj--;
while (a[j].key > pivot);
if (i < j) if (i < j)
swap(a[i], a[j], temp);
} while (i < j);
} while (i < j);
Example of Quick Sort
input file: 10 records
- (26,5,37,1,61,11,59,15,48,19)
pivot pivot
26 5 37 1 61 11 59 15 48 19
i j
26 5 19 1 61 11 59 15 48 37
i j
26 5 19 1 15 11 59 61 48 37 26 5 19 1 15 11 59 61 48 37
i j
Example of Quick Sort
26 5 19 1 15 11 59 61 48 37
i j
11 5 19 1 15 26 59 61 48 37
··
·
Example of Quick Sort
input file: 10 records
- (26,5,37,1,61,11,59,15,48,19)
R1 26 11
R2 5 5
R3 37 19
R4 1 1
R5 61 15
R6 11 26
R7 59 59
R8 15 61
R9 48 48
R10 19 37
left 1 1
right 10
5 11
1 1
5 5 5
19 11 11
1 19 19
15 15 15
26 26 26
59 59 59
61 61 61
48 48 48
37 37 37
1 1 4
5 2 5 1
1 1
5 5 5
11 11 11
15 15 15
19 19 19
26 26 26
59 48 37
61 37 48
48 59 59
37 61 61
7 7 10
10 8 10 1
1
5 5
11 11
15 15
19 19
26 26
37 37
48 48
59 59
61 61
10 10
Quick Sort
time complexity
- average case: O(n·logaverage case: O(n log22n)n) split into “equal size”
T(n): average time to sort n records T( ) < + 2 T( /2)
T(n) <= c·n + 2·T(n/2)
<= c·n + 2(c·n/2 + 2·T(n/4))
<= 2·c·n + 4·T(n/4)
< 2 c n + 4 T(n/4)
···
<= log2n·c·n + n·T(1)
= O(n·log2n)
t O( 2) How can we select pivots?
- worst case: O(n ) How can we select pivots?
Merge Sort
• Use divide and conquer methodq
• Need additional space for the merge step
• Need additional space for the merge step
Divide Combine
divide combine
divide combine
divide combine
divide divide
Program 7.11: recursive merge sort
int rmerge(element list[ ], int lower, int upper){
i t iddl int middle;
if (lower >= upper) return lower;
else {
middle =(lower+upper)/2;
return listmerge(list, rmerge(list, lower,g ( , g ( , ,
middle), rmerge(list, middle+1, upper);
}}
} /* rmerge returns an integer that points to the start of the list */
to the start of the list */
Merging two ordered lists
2 5 7 8 1 3 4 6 1
2 5 7 8 3 4 6 1 2
5 7 8 3 4 6 1 2 3
5 7 8 4 6 1 2 3 4
5 7 8 6 1 2 3 4 5
7 8 6 1 2 3 4 5 6
7 8 1 2 3 4 5 6 7 8
7 8 1 2 3 4 5 6 7 8
Merge Sort
Need additional space for the merge step
• Need additional space for the merge step
• Complexity: O(nlogn)
• If linked list is used for merging, ed st s used o e g g,
then actual moving need not occur
Heap Sort
utilize the max heap structure
- implement max heap by using array
time complexity
O( )
- average case : O(n·log2n) - worst case : O(n·log2n)
Heap Sort
• Construct a max heap with n records
7 12 dj t t k bi t T
- program 7.12 adjust takes a binary tree T whose left and right subtrees satisfy the heap
t b t h t t d dj t T
property but whose root may not and adjusts T so that the entire binary tree satisfies the heap
t property
• Exchange the first record in the heap with theExchange the first record in the heap with the last record
• Decrement the heap size and readjust the heap
• Decrement the heap size and readjust the heap
• Repeat n-1 passes
program 7.12
• adjust the binary tree to establish the heapj y p - time: O(d) where d: depth of tree
5 61 61
48 61 48 5 48 19
1
15 19 15 1 19 15 1 5
Example of Heap sorting process
- input list
(26 5 77 1 61 11 59 15 48 19) (26,5,77,1,61,11,59,15,48,19)
[1]
26 [1]
[1] 26
[2]
[3]
5 77
1 [2]
[3]
5 77 [4]
[2]
[4] [5]
[6] [7]
1 61 11 [4]
[5]
[6]
1 61 11 59
[4] [5]
[8] [9] [10]
59 15 [7]
[8]
array interpreted as a binary tree
48
15 19 48
19 [9]
[10]
array interpreted as a binary tree
Heap Sort
77 77
61 59
48 19 11 26
1
15 5
Initial max heap construction
Heap Sort
77 77
61 59
77 [1]
1
48 19 11 26
15 5
61 59 [2]
[3]
1
15 5
48 19 11 [4]
[5]
61 [6]
11 26 15 [6]
[7]
[8] 5
48 59
15 1 [8]
[9]
[10] 5
5
15 19 11 26
[10] 5 1
5 77
Heap Sort
59
48 36
15 19 11 1
5 61 77
5 61 77
48
19
48
26
15 5 11 1
77 61
59
Heap Sort
26
19
26
11
15
19
5 1
11
15 5 1 48
77 61
59
48
77 61
59
Heap Sort
void heapsort(element a[], int n) { i t i j
int i, j;
element temp;
for (i = n / 2; i > 0; i--)
/* initial heap construction */
adjust(a, i, n);
for (i = n - 1; i > 0; i--) { /* heap adjust */( ; ; ) { p j SWAP(a[1], a[i+1], temp);
adjust(a 1 i);
adjust(a, 1, i);
} }}
Complexity of heap sort
• for the first for loop : O(n)p ( )
• for the second for loop : O(n·log2n)
Worst and average time complexity:
O( l )
O(n·log2n)