Previously Searching Linear (Sequential): O(n) Binary: O(log n)

Slides:



Advertisements
Similar presentations
Introduction to Algorithms Quicksort
Advertisements

Algorithms Analysis Lecture 6 Quicksort. Quick Sort Divide and Conquer.
Quick Sort, Shell Sort, Counting Sort, Radix Sort AND Bucket Sort
Sorting I / Slide 1 Mergesort Based on divide-and-conquer strategy * Divide the list into two smaller lists of about equal sizes * Sort each smaller list.
Efficient Sorts. Divide and Conquer Divide and Conquer : chop a problem into smaller problems, solve those – Ex: binary search.
Quicksort CS 3358 Data Structures. Sorting II/ Slide 2 Introduction Fastest known sorting algorithm in practice * Average case: O(N log N) * Worst case:
25 May Quick Sort (11.2) CSE 2011 Winter 2011.
Quicksort COMP171 Fall Sorting II/ Slide 2 Introduction * Fastest known sorting algorithm in practice * Average case: O(N log N) * Worst case: O(N.
Sorting Chapter Sorting Consider list x 1, x 2, x 3, … x n We seek to arrange the elements of the list in order –Ascending or descending Some O(n.
Quicksort Divide-and-Conquer. Quicksort Algorithm Given an array S of n elements (e.g., integers): If array only contains one element, return it. Else.
Fundamentals of Algorithms MCS - 2 Lecture # 16. Quick Sort.
Insertion sort, Merge sort COMP171 Fall Sorting I / Slide 2 Insertion sort 1) Initially p = 1 2) Let the first p elements be sorted. 3) Insert the.
Merge sort csc326 information structures Spring 2009.
Quicksort. 2 Introduction * Fastest known sorting algorithm in practice * Average case: O(N log N) * Worst case: O(N 2 ) n But, the worst case seldom.
Merge sort, Insertion sort
Quicksort.
Merge sort, Insertion sort. Sorting I / Slide 2 Sorting * Selection sort or bubble sort 1. Find the minimum value in the list 2. Swap it with the value.
Chapter 7 (Part 2) Sorting Algorithms Merge Sort.
Sorting II/ Slide 1 Lecture 24 May 15, 2011 l merge-sorting l quick-sorting.
CS 202, Spring 2003 Fundamental Structures of Computer Science II Bilkent University1 Sorting - 3 CS 202 – Fundamental Structures of Computer Science II.
Insertion sort, Merge sort COMP171 Fall Sorting I / Slide 2 Insertion sort 1) Initially p = 1 2) Let the first p elements be sorted. 3) Insert the.
Sorting (Part II: Divide and Conquer) CSE 373 Data Structures Lecture 14.
CSC – 332 Data Structures Sorting
Computer Science 101 Fast Searching and Sorting. Improving Efficiency We got a better best case by tweaking the selection sort and the bubble sort We.
C++ Programming: From Problem Analysis to Program Design, Second Edition Chapter 19: Searching and Sorting.
Merge sort, Insertion sort. Sorting I / Slide 2 Sorting * Selection sort (iterative, recursive?) * Bubble sort.
Java Methods Big-O Analysis of Algorithms Object-Oriented Programming
Review 1 Selection Sort Selection Sort Algorithm Time Complexity Best case Average case Worst case Examples.
1 Searching and Sorting Searching algorithms with simple arrays Sorting algorithms with simple arrays –Selection Sort –Insertion Sort –Bubble Sort –Quick.
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 122 – Data Structures Sorting.
PREVIOUS SORTING ALGORITHMS  BUBBLE SORT –Time Complexity: O(n 2 ) For each item, make (n –1) comparisons Gives: Comparisons = (n –1) + (n – 2)
Intro. to Data Structures Chapter 7 Sorting Veera Muangsin, Dept. of Computer Engineering, Chulalongkorn University 1 Chapter 7 Sorting Sort is.
Algorithm Design Techniques, Greedy Method – Knapsack Problem, Job Sequencing, Divide and Conquer Method – Quick Sort, Finding Maximum and Minimum, Dynamic.
Searching and Sorting Searching algorithms with simple arrays
Advanced Sorting.
Chapter 11 Sorting Acknowledgement: These slides are adapted from slides provided with Data Structures and Algorithms in C++, Goodrich, Tamassia and Mount.
Sorting Mr. Jacobs.
Fundamental Data Structures and Algorithms
Subject Name: Design and Analysis of Algorithm Subject Code: 10CS43
COMP 53 – Week Seven Big O Sorting.
Quicksort
Data Structures Using C++ 2E
Chapter 7 Sorting Spring 14
Teach A level Computing: Algorithms and Data Structures
Sorting Chapter 13 Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved
Quicksort and Mergesort
Chapter 4: Divide and Conquer
Advanced Sorting Methods: Shellsort
Quick Sort (11.2) CSE 2011 Winter November 2018.
Quicksort analysis Bubble sort
Mergesort Based on divide-and-conquer strategy
Data Structures Review Session
8/04/2009 Many thanks to David Sun for some of the included slides!
Lecture No 6 Advance Analysis of Institute of Southern Punjab Multan
Sub-Quadratic Sorting Algorithms
EE 312 Software Design and Implementation I
CS 3343: Analysis of Algorithms
Quicksort.
CSE 373 Data Structures and Algorithms
Ch. 2: Getting Started.
Algorithms: Design and Analysis
CSC 380: Design and Analysis of Algorithms
CSC 380: Design and Analysis of Algorithms
Merge Sort (11.1) CSE 2011 Winter April 2019.
Quicksort.
Design and Analysis of Algorithms
Divide and Conquer Merge sort and quick sort Binary search
Quicksort.
Advanced Sorting Methods: Shellsort
Presentation transcript:

Previously Searching Linear (Sequential): O(n) Binary: O(log n) Hash: O(1) Must generate a (hopefully) unique integer from the key (hash function) Collisions (Separate chaining, linear probing, quadratic probing) Must worry about table size Sorting Bubble: Awful: O(n2) Selection: Awful: O(n2) Insertion: Awful: O(n2)

The Lecture Portion for Today Sorting Shell sort Merge sort Quick sort

Timeline Sexagesimal number system (3100 BC) Pi (2000 BC) Pythagorean theorem, quadratic equations (600 BC) Recursion ((see Panini) 500 BC) Euclid’s algorithm (300 BC) Logarithms (400 CE) Modern algebra (750 CE) Newton & Leibniz independently develop Calculus (1760 CE) George Boole -The Mathematical Analysis of Logic (1847), and An Investigation of the Laws of Thought (1854) Shell sort (1959) Hibbard’s Increments (1963) Quicksort (1962) Binary Heaps (1964) TimSort – Tim Peters (2002)

Shellsort What’s the concept? Increment sequence Shell’s sequence {1, 2, 4, 8, …} O(N2) Hibbard’s sequence {1, 3, 7, 15, …} O(N3/2)

Shell Sort Strategy: set a gap (initially let gap = n/2), insertion sort elements separated by a distance of gap, reduce the gap by increments after each iteration until it is = 1, and continue.

Shell Sort A i i i i i i i i i i i i 10 24 41 31 3 41 25 27 31 44 27 Example: an array of int, length n = 9 gap = n/2 = 4 gap = max(1, (int) gap /2) = 2 1 0 1 2 3 4 5 6 7 8 10 24 41 31 3 41 25 27 31 44 27 44 A 3 3 10 25 27 24 27 41 25 44 47 47 24 31 44 27 10 47 41 3 25 i i i i i i i i i i i i for i in range(start+gap,len(alist),gap): currentvalue = alist[i] position = i while position>=gap and alist[position-gap]>currentvalue: alist[position]=alist[position-gap] position = position-gap alist[position]=currentvalue

def shellSort(alist): sublistcount = len(alist)//2 while sublistcount > 0: for startposition in range(sublistcount): gapInsertionSort(alist,startposition,sublistcount) sublistcount = sublistcount // 2 def gapInsertionSort(alist,start,gap): for i in range(start+gap,len(alist),gap): currentvalue = alist[i] position = i while position>=gap and alist[position-gap]>currentvalue: alist[position]=alist[position-gap] position = position-gap alist[position]=currentvalue

Why is Shell Sort better than Insertion Sort? Every pass makes the list “more sorted” The more sorted a list is, the less work has to be done in subsequent passes. Another way to look at it: By swapping items that are far apart, we can “fix” several out of order elements all at once.

Mergesort Based on divide-and-conquer strategy Divide the list into two smaller lists of about equal sizes Sort each smaller list recursively Merge the two sorted lists to get one sorted list How do we divide the list? How much time needed? How do we merge the two sorted lists? How much time needed?

In order to analyze the mergeSort function, consider the two distinct processes that make up its implementation. First, the list is split into halves. We already computed (in a binary search) that we can divide a list in half logn times where n is the length of the list. Not using the slice operator here. The second process is the merge. Each item in the list will eventually be processed and placed on the sorted list. So the merge operation which results in a list of size n, requires n operations. The result of this analysis is that logn splits, each of which costs n for a total of nlogn operations. A merge sort is an O(nlogn) algorithm.

Mergesort Divide-and-conquer strategy recursively mergesort the first half and the second half merge the two sorted halves together

http://www.sorting-algorithms.com/merge-sort

How to merge? Input: two sorted arrays A and B Output: an output sorted array C Three counters: Actr, Bctr, and Cctr initially set to the beginning of their respective arrays (1)   The smaller of A[Actr] and B[Bctr] is copied to the next entry in C, and the appropriate counters are advanced (2)   When either input list is exhausted, the remainder of the other list is copied to C

Example: Merge

Example: Merge... Running time analysis: Space requirement: Clearly, merge takes O(m1 + m2) where m1 and m2 are the sizes of the two sublists. Space requirement: merging two sorted lists requires linear extra memory additional work to copy to the temporary array and back

def mergeSort(alist): if len(alist)>1: mid = len(alist)//2 lefthalf = alist[:mid] righthalf = alist[mid:] mergeSort(lefthalf) mergeSort(righthalf) i,j,k = 0,0,0 while i<len(lefthalf) and j<len(righthalf): if lefthalf[i]<righthalf[j]: alist[k]=lefthalf[i] i=i+1 else: alist[k]=righthalf[j] j=j+1 k=k+1 while i<len(lefthalf): i, k = i+1, k=k+1 while j<len(righthalf): j, k = j+1, k=k+1

Analysis of mergesort Let T(N) denote the worst-case running time of mergesort to sort N numbers. Assume that N is a power of 2. Divide step: O(1) time Conquer step: 2 T(N/2) time Combine step: O(N) time Recurrence equation: T(1) = 1 T(N) = 2T(N/2) + N

Solving the Recurrence Relation Covered in Discrete Mathematics Other important recurrence relations T(n) = T(n – 1) + 1 O(n) T(n) = T(n/2) + 1 O(log n) T(n) = T(n – 1) + n O(n2)

Quicksort Fastest known sorting algorithm in practice for many data types Average case: O(N log N) Worst case: O(N2) But, the worst case seldom happens. Another divide-and-conquer recursive algorithm like mergesort

Quicksort Divide step: Conquer step: recursively sort S1 and S2 Pick any element (pivot) v in S Partition S – {v} into two disjoint groups S1 = {x  S – {v} | x  v} S2 = {x  S – {v} | x  v} Conquer step: recursively sort S1 and S2 Combine step: combine the sorted S1, followed by v, followed by the sorted S2 v v S1 S2

Example: Quicksort

Example: Quicksort...

Pseudocode def quicksort(alist) if length(alist) > 1 pivot := select any element of alist left := first index of alist right := last index of alist while left ≤ right while alist[left] < pivot left := left + 1 while alist[right] > pivot right := right - 1 if left ≤ right swap alist[left] with alist[right] left := left + 1 right := right - 1 quicksort(alist from first index to right) quicksort(alist from left to last index)

Partitioning Partitioning Key step of quicksort algorithm Goal: given the picked pivot, partition the remaining elements into two smaller sets Many ways to implement We will learn an easy and efficient partitioning strategy here. How to pick an effective pivot will be discussed later

Let’s make the first value the pivot (safe if the numbers are truly random)

Swap elements that are on the “wrong” side of the pivot

When leftmark and rightmark cross … When leftmark and rightmark cross …. Swap the pivot with the value at rightmark http://www.sorting-algorithms.com/quick-sort

Quick Sort def quickSort(alist): quickSortHelper(alist,0,len(alist)-1) def quickSortHelper(alist,first,last): if first<last: splitpoint = partition(alist,first,last) #code on next slide quickSortHelper(alist,first,splitpoint-1) quickSortHelper(alist,splitpoint+1,last)

def partition(alist,first,last): pivotvalue = alist[first] leftmark = first+1 rightmark = last done = False while not done: while leftmark <= rightmark and alist[leftmark] <= pivotvalue: leftmark = leftmark + 1 while alist[rightmark] >= pivotvalue and rightmark >= leftmark: rightmark = rightmark -1 if rightmark < leftmark: done = True else: temp = alist[leftmark] alist[leftmark] = alist[rightmark] alist[rightmark] = temp temp = alist[first] alist[first] = alist[rightmark] return rightmark

Picking the Pivot Use the first element as pivot If the input is random, ok If the input is presorted (or in reverse order) All the elements go into S2 (or S1) This happens consistently throughout the recursive calls Results in O(n2) behavior (Analyze this case later) Choose the pivot randomly Generally safe Random number generation can be expensive

Picking the Pivot Use the median of the array Partitioning always cuts the array into roughly half An optimal quicksort (O(N log N)) However, hard to find the exact median e.g., sort an array to pick the value in the middle

Pivot: median of three We will use median of three Take the median of three elements The element at first The element at last The element at the middle index (first + last)//2

Worst-Case Analysis What will be the worst case? The pivot is the smallest element, all the time Partition is always unbalanced

Best-case Analysis What will be the best case? Partition is perfectly balanced. Pivot is always in the middle (median of the array)

Average-Case Analysis Assume Each of the sizes for S1 is equally likely This assumption is valid for our pivoting (median-of-three) and partitioning strategy On average, the running time is O(N log N)

Quicksort Faster than Mergesort Both quicksort and mergesort take O(N log N) in the average case. Why is quicksort often faster than mergesort? The inner loops consists of an increment/decrement (by 1, which is fast), a test and a jump. There is no extra juggling of memory as in mergesort. When might mergesort be faster than quicksort? For lists with many duplicate elements For partially sorted lists In programming languages where comparison is expensive (comparing objects in Java is expensive) Mergesort will use less comparisons than quicksort

Quicksort has a reputation as the fastest sort Quicksort has a reputation as the fastest sort. Optimized variants of quicksort are common features of many languages and libraries. One often contrasts quicksort with merge sort, because both sorts have an average time of O(n log n). "On average, mergesort does fewer comparisons than quicksort, so it may be better when complicated comparison routines are used. Mergesort also takes advantage of pre-existing order, so it would be favored for using sort() to merge several sorted arrays. On the other hand, quicksort is often faster for small arrays, and on arrays of a few distinct values, repeated many times." — http://perldoc.perl.org/sort.html

Quicksort is a conquer-then-divide algorithm, which does most of the work during the partitioning and the recursive calls. Merge sort is a divide-then-conquer algorithm. The partitioning happens in a trivial way, by splitting the input array in half. Most of the work happens during the recursive calls and the merge phase. With quicksort, every element in the first partition is less than or equal to every element in the second partition. Therefore, the merge phase of quicksort is trivial! Quicksort and merge sort at the opposite ends of the divide-and-conquer algorithm spectrum.

What does Python use when you call the built-in sort? Timsort http://svn.python.org/projects/python/trunk/Objects/listsort.txt Worst case: O(n log n) Modified version of mergesort Uses insertion sort for small list segments In a nutshell, the main routine marches over the array once, left to right, alternately identifying the next run, then merging it into the previous runs "intelligently". Everything else is complication for speed, and some hard-won measure of memory efficiency.

Is N Log N the best we can do? For comparison-based sorting, yes.