COMP 250 Lecture 13 mergesort, quicksort Oct. 6, 2017 1
Time complexity π π 2 π πππ 2 π π π β’ convert to binary β’ List operations: β’ insertion/selection/ findMax, remove bubble sort β’ grade school addition β’ grade school β’ binary search or subtraction multiplication β’ β¦.. β’ β¦β¦ β’ β¦β¦ 2
Computers perform ~10 9 operations per second. 2 10 β 10 3 2 20 β 10 6 2 30 β 10 9
Computers perform ~10 9 operations per second. π 2 πππ 2 π π 2 10 β 10 3 10 10 6 2 20 β 10 6 20 10 12 minutesβ¦hours 2 30 β 10 9 30 10 18 centuries second
Better sorting algorithms ? π( π 2 ) π π < ? < 5
Mergesort Given a list, partition it into two halves (1 st & 2 nd ). Sort each half (recursively). Merge the two halves. This turns out to be much faster than the other list sorting algorithms we have seen. 6
8 1 8 1 10 3 10 2 mergesort 3 6 3 3 11 8 11 4 6 10 6 5 1 11 1 6 partition merge 7 7 2 7 16 8 4 16 2 10 2 5 mergesort 5 11 7 5 4 13 13 4 13 16 13 16 7
mergesort(list){ if list.length == 1 return list else{ mid = (list.size - 1) / 2 list1 = list. getElements (0,mid) list2 = list. getElements (mid+1, list.size-1) list1 = mergesort(list1) list2 = mergesort(list2) return merge( list1, list2 ) } } 8
mergesort(list){ if list.length == 1 return list else{ mid = (list.size - 1) / 2 list1 = list.getElements(0,mid) list2 = list.getElements(mid+1, list.size-1) list1 = mergesort(list1) list2 = mergesort(list2) return merge( list1, list2 ) } } 9
mergesort(list){ if list.length == 1 return list else{ mid = (list.size - 1) / 2 list1 = list.getElements(0,mid) list2 = list.getElements(mid+1, list.size-1) list1 = mergesort(list1) list2 = mergesort(list2) return merge( list1, list2 ) } } 10
1 8 8 1 3 10 10 2 mergesort 6 3 3 3 8 11 11 4 10 6 6 5 11 1 1 6 partition merge 7 7 2 7 16 8 4 16 2 10 5 2 mergesort 5 11 7 5 4 13 13 4 13 16 16 13 11
head1 1 3 6 8 10 11 merge 2 head2 4 5 7 13 16 12
1 1 3 head1 6 8 10 11 merge 2 head2 4 5 7 13 16 13
1 1 3 head1 2 6 8 10 11 merge 2 4 head2 5 7 13 16 14
1 1 3 2 6 head1 3 8 10 11 merge 2 4 head2 5 7 13 16 15
1 1 3 2 6 head1 3 8 4 10 11 merge 2 4 5 head2 7 13 16 16
1 1 3 2 6 head1 3 8 4 10 5 11 merge 2 4 5 7 head2 13 16 17
1 1 3 2 6 3 8 head1 4 10 5 11 6 merge 2 4 5 7 head2 13 16 18
1 1 3 2 6 3 8 head1 4 10 5 11 6 merge 7 2 4 5 7 13 head2 16 19
1 1 3 2 β¦.and so on until 6 3 one list is empty. 8 4 10 5 11 6 merge 7 2 8 4 10 5 11 7 13 head2 16 20
1 1 3 2 Then, copy the 6 3 remaining 8 4 elements. 10 5 11 6 merge 7 2 8 4 10 5 11 7 13 13 16 16 21
merge( list1, list2){ initialize list to be empty while (list1 is not empty) & (list2 is not empty){ if (list1.first < list2.first) list.addlast( list1.removeFirst(list1) ) else list.addlast( list2.removeFirst(list2) ) } while list1 is not empty list.addlast( list1.removeFirst(list1) ) while list2 is not empty list.addlast( list2.removeFirst(list2) ) return list } 22
merge( list1, list2){ initialize list to be empty while (list1 is not empty) & (list2 is not empty){ if (list1.first < list2.first) list.addlast( list1.removeFirst(list1) ) else list.addlast( list2.removeFirst(list2) ) } while list1 is not empty list.addlast( list1.removeFirst(list1) ) while list2 is not empty list.addlast( list2.removeFirst(list2) ) return list } 23
8 mergesort(list){ 10 if list.length == 1 3 return list 11 else{ 6 mid = (list.size - 1) / 2 1 list1 = list.getElements(0,mid) list2 = list.getElements(mid+1, list.size-1) 7 list1 = mergesort(list1) 16 list2 = mergesort(list2) 2 return merge( list1, list2 ) 5 } 4 } 13
8 8 10 10 3 list1 3 11 11 6 6 1 1 7 7 16 16 2 2 list2 5 5 4 4 13 13
8 8 8 10 list1 10 10 3 3 3 11 11 11 6 list2 6 6 1 1 1 7 7 16 16 2 2 5 5 4 4 13 13
8 list1 8 10 8 8 10 3 list2 10 10 3 3 3 11 11 11 6 6 6 1 1 1 7 7 16 16 2 2 5 5 4 4 13 13
8 8 8 list1 8 10 10 10 8 8 10 3 list2 10 10 3 3 3 11 11 11 6 6 6 1 1 1 7 7 16 16 2 2 5 5 4 4 13 13 28
8 8 8 8 10 3 10 10 8 8 10 8 list1 3 10 10 3 10 3 3 11 11 11 6 list2 6 6 1 1 1 7 7 16 16 2 2 5 5 4 4 13 13
8 8 8 8 10 3 10 10 8 8 10 8 list1 3 10 10 3 10 3 3 11 11 6 11 1 11 11 6 11 6 6 6 6 list2 6 1 1 11 1 1 7 7 16 16 2 2 5 5 4 4 13 13
8 8 8 8 10 3 10 10 1 8 8 10 8 3 3 10 10 3 10 6 3 list1 3 11 11 6 11 8 1 11 11 6 11 6 6 10 6 6 6 1 11 1 11 1 1 7 7 16 16 2 2 list2 5 5 4 4 13 13
8 8 8 8 10 3 10 10 1 8 8 10 8 3 3 10 10 3 10 6 3 list1 3 11 11 6 11 8 1 11 11 6 11 6 6 10 6 6 6 1 11 1 11 1 1 7 7 7 7 7 7 2 2 16 16 16 16 16 16 4 7 2 2 2 2 list2 5 16 5 5 5 7 5 5 4 4 4 4 4 13 4 13 5 4 13 5 16 13 13 13 32
8 8 8 8 10 3 10 10 1 8 8 10 1 8 3 3 10 10 3 2 10 6 3 3 3 11 11 6 11 8 1 11 11 4 6 11 6 6 10 6 6 6 5 1 11 1 11 1 1 6 7 7 7 7 7 7 7 2 2 16 16 16 8 16 16 16 4 7 2 2 10 2 2 5 16 5 11 5 5 7 5 5 4 4 13 4 4 4 13 4 13 5 16 4 13 5 16 13 13 13 33
Q: How many operations are required to mergesort a list of size π ? π π A: π( π πππ 2 π ) This will become more clear a few lectures from now when we discuss recurrences. πππ 2 π πππ 2 π 34
π πππ 2 π is much closer to π than to π 2 π 2 πππ 2 π π π πππ π π 2 10 β 10 3 ππ π 10 10 6 2 20 β 10 6 ~ππ π 20 10 12 2 30 β 10 9 ~ππ ππ 30 10 18
Computers perform ~10 9 operations per second. π 2 πππ 2 π π π πππ π π 2 10 β 10 3 ππ π 10 10 6 2 20 β 10 6 ~ππ π 20 10 12 2 30 β 10 9 ~ππ ππ 30 10 18 milliseconds minutes hours centuries
π( π 2 ) π π < π( π πππ 2 π) βͺ mergesort bubble sort quicksort selection sort insertion sort 37
Quicksort quicksort(list){ if list.length <= 1 return list else{ pivot = list.removeFirst() // or some other element list1 = list.getElementsLessThan(pivot) list2 = list.getElementsGreaterOrEqual(pivot) list1 = quicksort(list1) list2 = quicksort(list2) } return concatenate( list1, e, list2 ) } 38
Quicksort quicksort(list){ if list.length <= 1 return list else{ pivot = list.removeFirst() // or some other element list1 = list.getElementsLessThan(pivot) list2 = list.getElementsGreaterOrEqual(pivot) list1 = quicksort(list1) list2 = quicksort(list2) } return concatenate( list1, e, list2 ) } 39
1 3 pivot 1 8 2 6 2 quicksort 10 3 1 3 3 4 7 4 11 5 2 5 6 6 5 6 partition 1 7 4 7 concatenate 7 8 16 10 10 10 quicksort 2 11 11 11 5 13 16 13 4 16 13 16 13 40
Quicksort can be done βin placeβ quicksort( low, high ){ if low > high return else{ pivot = ___; // select index in {low, β¦, high} partitionIndex = makePartition (low, high, pivot) quicksort(low, partitionIndex - 1) quicksort(partionIndex + 1, high) } } Quicksort partitioning can be done βin placeβ using a clever swapping and scanning technique. (See web for details, if interested.) 41
pivot 3 1 8 6 2 10 quicksort 1 3 3 7 4 11 2 5 6 partition 5 6 1 4 7 7 8 8 16 10 10 2 11 11 5 quicksort 16 13 4 13 16 13 42
Mergesort vs. Quicksort β’ Mergesort typically uses an extra list. More space can hurt performance for big lists. β’ We will discuss worst case performance of quicksort later in the course. β’ See stackoverflow if you want opinions on which is better. 43
Recommend
More recommend