1.52k likes | 1.54k Views
Learn about the Quicksort algorithm invented by C.A.R. Hoare in 1960, its efficiency, implementation, partitioning methods, and performance analysis. Quicksort is widely used in computer science.
E N D
CO 303 Algorithm Analysis And DesignQuicksort Jigar Patel, Lecturer Computer Engg Dept, SVNIT E-mail: p.jigar@coed.svnit.ac.in
Notes on Quicksort • Quicksort was invented in 1960 by C. A. R. Hoare. • Quicksort is more widely used than any other sort. • Quicksort is well-studied, not difficult to implement, works well on a variety of data, and consumes fewer resources that other sorts in nearly all situations. • Quicksort is O(n*log n) time, and O(log n) additional space due to recursion.
Notes on Quicksort • Quicksort has withstood the test of time. It has been thoroughly analyzed. The analysis has been verified through extensive empirical experience. • Quicksort is not stable. • Quicksort performance can degenerate under special circumstances. It is possible modify the algorithm to handle these cases, but at the expense of making the algorithm more complicated. • Sedgewick states that “tuning Quicksort is the better mousetrap of computer science.” Many ideas have been tried, but it’s easy to be deceived because the algorithm is so balanced that a perceived improvement in one area can be more than offset by poor performance in another area.
Quicksort Algorithm • Quicksort is a divide-and-conquer method for sorting. It works by partitioning an array into parts, then sorting each part independently. • The crux of the problem is how to partition the array such that the following conditions are true: • There is some element, a[i], where a[i] is in its final position. • For all l < i, a[l] < a[i]. • For all i < r, a[i] < a[r].
Quicksort Algorithm (cont) • As is typical with a recursive program, once you figure out how to divide your problem into smaller subproblems, the implementation is amazingly simple. int partition(Item a[], int l, int r); void quicksort(Item a[], int l, int r) { int i; if (r <= l) return; i = partition(a, l, r); quicksort(a, l, i-1); quicksort(a, i+1, r); }
Q U I C K S O R T I S C O O L partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross
swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross Q U I C K S O R T I S C O O L
swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross Q U I C K S O R T I S C O O L
swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross Q U I C K S O R T I S C O O L
swap me swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross Q U I C K S O R T I S C O O L
partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C U I C K S O R T I S Q O O L
swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C U I C K S O R T I S Q O O L
swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C U I C K S O R T I S Q O O L
swap me swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C U I C K S O R T I S Q O O L
partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C I I C K S O R T U S Q O O L
partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C I I C K S O R T U S Q O O L
partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C I I C K S O R T U S Q O O L
partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C I I C K S O R T U S Q O O L
swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C I I C K S O R T U S Q O O L
swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C I I C K S O R T U S Q O O L
swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C I I C K S O R T U S Q O O L
swap me partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross C I I C K S O R T U S Q O O L
partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross swap with partitioning element pointers cross C I I C K S O R T U S Q O O L
partition element unpartitioned left partitioned right Partitioning in Quicksort • How do we partition the array efficiently? • choose partition element to be rightmost element • scan from left for larger element • scan from right for smaller element • exchange • repeat until pointers cross partition is complete C I I C K L O R T U S Q O O S
Partitioning in Quicksort int partition(Item a[], int l, int r) { int i = l-1, j = r; Item v = a[r]; for (;;) { while (less(a[++i], v)) ; while (less(v, a[--j])) if (j == l) break; if (i >= j) break; exch(a[i], a[j]); } exch(a[i], a[r]); return i;
Quicksort Demo • Quicksort illustrates the operation of the basic algorithm. When the array is partitioned, one element is in place on the diagonal, the left subarray has its upper corner at that element, and the right subarray has its lower corner at that element. The original file is divided into two smaller parts that are sorted independently. The left subarray is always sorted first, so the sorted result emerges as a line of black dots moving right and up the diagonal.
Quicksort Code Quicksort(A, p, r) { if (p < r) { q = Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } • Initial Call is Quicksort(A, 1, length[A])
Partition • Clearly, all the action takes place in the partition() function • Rearranges the subarray in place • End result: • Two subarrays • All values in first subarray all values in second • Returns the index of the “pivot” element separating the two subarrays • How do you suppose we implement this function?
Partition Code Partition(A, p, r) x A[r] i p – 1 for j p to r-1 do if A[j]≤ x then I i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8)TRUE { Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[1]≤4 ) => if(2<4) TRUE Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[1]≤4 ) => if(2<4)TRUE i = 0 + 1 = 1 Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[1]≤4 ) => if(2<4)TRUE i = 0 + 1 = 1 exchange A[1] A[1] Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[2]≤4 ) => if(8<4) FALSE Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[3]≤4 ) => if(7<4) FALSE Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[4]≤4 ) => if(1<4) TRUE Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[4]≤4 ) => if(1<4)TRUE i = 1 + 1 = 2 Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[4]≤4 ) => if(1<4)TRUE i = 1 + 1 = 2 exchange A[2] A[4] Quick SortA = {2, 8, 7, 1, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[4]≤4 ) => if(1<4)TRUE i = 1 + 1 = 2 exchange A[2] A[4] Quick SortA = {2, 1, 7, 8, 3, 5, 6, 4}
Quicksort(A, p, r) { if (p < r) { q Partition(A, p, r); Quicksort(A, p, q-1); Quicksort(A, q+1, r); } } Partition(A, p, r) x A[r] i p - 1 for j p to r-1 do if A[j]≤ x then i i+ 1 exchange A[i] A[j] exchange A[i+1] A[r] return i+1 Quicksort (A, 1, 8) { if(1<8) { q Partition(A,1,8) Partition(A,1,8) x = A[8] = 4 i = 1-1 = 0 for(j=1;j≤7; j++){ if(A[5]≤4 ) => if(3<4) TRUE Quick SortA = {2, 1, 7, 8, 3, 5, 6, 4}