1 / 21

§5 Heapsort

§5 Heapsort. Algorithm 1: { BuildHeap( H ); for ( i=0; i<N; i++ ) TmpH[ i ] = DeleteMin( H ); for ( i=0; i<N; i++ ) H[ i ] = TmpH[ i ]; }. /* O( N ) */. /* O( log N ) */. /* O( 1 ) */. T ( N ) = O ( N log N ).  The space requirement is doubled. 1/21.

cael
Download Presentation

§5 Heapsort

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. §5 Heapsort Algorithm 1: { BuildHeap( H ); for ( i=0; i<N; i++ ) TmpH[ i ] = DeleteMin( H ); for ( i=0; i<N; i++ ) H[ i ] = TmpH[ i ]; } /* O( N ) */ /* O( log N ) */ /* O( 1 ) */ T( N ) = O ( N log N)  The space requirement is doubled. 1/21

  2. §5 Heapsort b A [0] [1] d a [2] c [3] Algorithm 2: void Heapsort( ElementType A[ ], int N ) { int i; for ( i = N / 2; i >= 0; i - - ) /* BuildHeap */ PercDown( A, i, N ); for ( i = N - 1; i > 0; i - - ) { Swap( &A[ 0 ], &A[ i ] ); /* DeleteMax */ PercDown( A, 0, i ); } } c d b a b a b a b c c d b Heapsort data start from position 0. 【Theorem】The average number of comparisons used to heapsort a random permutation of N distinct items is 2N log N O(N log log N) . Note: Although Heapsort gives the best average time, in practice it is slower than a version of Shellsort that uses Sedgewick’s increment sequence. 2/21

  3. 1 13 24 26 2 15 27 38 §6 Mergesort 1. Merge two sorted lists Lpos Lpos Rpos Rpos 1 2 Tpos Tpos Tpos T( N ) = O ( ) where N is the total number of elements. N 3/21

  4. §6 Mergesort 2. Mergesort void MSort( ElementType A[ ], ElementType TmpArray[ ], int Left, int Right ) { int Center; if ( Left < Right ) { /* if there are elements to be sorted */ Center = ( Left + Right ) / 2; MSort( A, TmpArray, Left, Center ); /* T( N / 2 ) */ MSort( A, TmpArray, Center + 1, Right ); /* T( N / 2 ) */ Merge( A, TmpArray, Left, Center + 1, Right ); /* O( N ) */ } } void Mergesort( ElementType A[ ], int N ) { ElementType *TmpArray; /* need O(N) extra space */ TmpArray = malloc( N * sizeof( ElementType ) ); if ( TmpArray != NULL ) { MSort( A, TmpArray, 0, N - 1 ); free( TmpArray ); } else FatalError( "No space for tmp array!!!" ); } If a TmpArray is declared locally for each call of Merge, then S(N) = O( ) N log N 4/21

  5. §6 Mergesort /* Lpos = start of left half, Rpos = start of right half */ void Merge( ElementType A[ ], ElementType TmpArray[ ], int Lpos, int Rpos, int RightEnd ) { int i, LeftEnd, NumElements, TmpPos; LeftEnd = Rpos - 1; TmpPos = Lpos; NumElements = RightEnd - Lpos + 1; while( Lpos <= LeftEnd && Rpos <= RightEnd ) /* main loop */ if ( A[ Lpos ] <= A[ Rpos ] ) TmpArray[ TmpPos++ ] = A[ Lpos++ ]; else TmpArray[ TmpPos++ ] = A[ Rpos++ ]; while( Lpos <= LeftEnd ) /* Copy rest of first half */ TmpArray[ TmpPos++ ] = A[ Lpos++ ]; while( Rpos <= RightEnd ) /* Copy rest of second half */ TmpArray[ TmpPos++ ] = A[ Rpos++ ]; for( i = 0; i < NumElements; i++, RightEnd - - ) /* Copy TmpArray back */ A[ RightEnd ] = TmpArray[ RightEnd ]; } 5/21

  6. §6 Mergesort …… …… A 0 1 2 3 n4 n3 n2 n1 …… …… …… …… …… …… …… …… 3. Analysis Note: Mergesort requires linear extra memory, and copying an array is slow. It is hardly ever used for internal sorting, but is quite useful for external sorting. T( 1) = 1 T( N ) = 2T ( N / 2) + O( N ) Home work: p.229 6.14 Mergesort without recursion = 2kT ( N / 2k) + k * O( N ) = N * T ( 1) + log N * O( N ) = O( N + N log N ) Iterative version : 6/21

  7. 13 43 31 57 26 0 81 92 75 65 0 13 26 31 43 57 75 81 92 65 §7 Quicksort -- the fastest known sorting algorithm in practice 1. The Algorithm void Quicksort ( ElementType A[ ], int N ) { if ( N < 2 ) return; pivot = pick any element in A[ ]; Partition S = { A[ ] \ pivot } into two disjoint sets: A1={ aS | a  pivot } and A2={ aS | a  pivot }; A = Quicksort ( A1, N1)  { pivot }  Quicksort ( A2, N2); }   The best case T(N) = O( ) N log N 13 81 92 43 65 31 57 26 75 0 The pivot is placed at the right place once and for all. 0 13 26 31 43 57 65 75 81 92 7/21

  8. §7 Quicksort 2. Picking the Pivot  A Wrong Way: Pivot = A[ 0 ] The worst case: A[ ] is presorted – quicksort will take O( N2 ) time to do nothing  A Safe Maneuver: Pivot = random select from A[ ]  random number generation is expensive  Median-of-Three Partitioning: Pivot = median ( left, center, right ) Eliminates the bad case for sorted input and actually reduces the running time by about 5%. 8/21

  9. §7 Quicksort 8 1 4 9 0 3 5 2 7 6 2 8 5 9 6 9 3. Partitioning Strategy < > > < < > < < < < > i i i i i i j j i j j Not too difficult if we carefully implement it… Uh-oh, there will be many dummy swaps… But hey! At least the sequence will be partitioned into two equal-sized subsequences. No swap… but then T( N ) = … Then T( N ) = O( N2 ). So we’d better stop both i and j and take some extra swaps. What will happen to the sequence: 1, 1, 1, …, 1 ? Good point! How about the other option – that neither i nor j stops? What if there is a key == pivot? How about stop i and j both and then swap? 9/21

  10. §7 Quicksort 4. Small Arrays Problem: Quicksort is slower than insertion sort for small N (  20 ). Solution: Cutoff when N gets small ( e.g. N = 10 ) and use other efficient algorithms (such as insertion sort). 5. Implementation void Quicksort( ElementType A[ ], int N ) { Qsort( A, 0, N - 1 ); /* A: the array */ /* 0: Left index */ /* N – 1: Right index */ } 10/21

  11. §7 Quicksort /* Return median of Left, Center, and Right */ /* Order these and hide the pivot */ ElementType Median3( ElementType A[ ], int Left, int Right ) { int Center = ( Left + Right ) / 2; if ( A[ Left ] > A[ Center ] ) Swap( &A[ Left ], &A[ Center ] ); if ( A[ Left ] > A[ Right ] ) Swap( &A[ Left ], &A[ Right ] ); if ( A[ Center ] > A[ Right ] ) Swap( &A[ Center ], &A[ Right ] ); /* Invariant: A[ Left ] <= A[ Center ] <= A[ Right ] */ Swap( &A[ Center ], &A[ Right - 1 ] ); /* Hide pivot */ /* only need to sort A[ Left + 1 ] … A[ Right – 2 ] */ return A[ Right - 1 ]; /* Return pivot */ } 11/21

  12. §7 Quicksort void Qsort( ElementType A[ ], int Left, int Right ) { int i, j; ElementType Pivot; if ( Left + Cutoff <= Right ) { /* if the sequence is not too short */ Pivot = Median3( A, Left, Right ); /* select pivot */ i = Left; j = Right – 1; /* why not set Left+1 and Right-2? */ for( ; ; ) { while ( A[ + +i ] < Pivot ) { } /* scan from left */ while ( A[ – –j ] > Pivot ) { } /* scan from right */ if ( i < j ) Swap( &A[ i ], &A[ j ] ); /* adjust partition */ else break; /* partition done */ } Swap( &A[ i ], &A[ Right - 1 ] ); /* restore pivot */ Qsort( A, Left, i - 1 ); /* recursively sort left part */ Qsort( A, i + 1, Right ); /* recursively sort right part */ } /* end if - the sequence is long */ else/* do an insertion sort on the short subarray */ InsertionSort( A + Left, Right - Left + 1 ); } 12/21

  13. §7 Quicksort Assume the average value of T( i ) for any i is 6. Analysis T( N ) = T( i ) + T( N – i – 1 ) + c N Home work: p.230 6.20 More analysis on Quicksort  The Worst Case: T( N ) = T( N – 1 ) + c N T( N ) = O( N2 )  The Best Case: [ ... ... ]  [ ... ... ] T( N ) = 2T( N / 2 ) + c N Read Figure 6.16 on p.214 for the 5th algorithm on solving this problem. T( N ) = O( N log N )  The Average Case: T( N ) = O( N log N ) 〖Example〗Given a list of N elements and an integer k. Find the kth largest element. 13/21

  14. §7 Quicksort Laboratory Project 4 Quicksort Due: Thursday, November 30th, 2006 at 10:00pm Detailed requirements can be downloaded from http://10.71.45.99/list.asp?boardid=47 Courseware Download Don’t forget to sign you names and duties at the end of your report. 14/21

  15. list list [0] [0] [1] [1] [2] [2] [3] [3] [4] [4] [5] [5] key key d d b b f f c c a a e e table table 4 0 1 1 3 2 0 3 5 4 5 2 table 4 1 3 0 5 2 §8 Sorting Large Structures Problem: Swapping large structures can be very much expensive. Solution: Add a pointer field to the structure and swap pointers instead – indirect sorting. Physically rearrange the structures at last if it is really necessary. 〖Example〗Table Sort The sorted list is list [ table[0] ], list [ table[1] ], ……, list [ table[n1] ] Note: Every permutation is made up of disjoint cycles. temp = d current = 0 3 4 2 5 a c d e f next = 4 2 5 3 0 2 3 4 5 In the worst case there are ? cycles and requires ? record moves.  N / 2  3N / 2 T = O( m N ) where m is the size of a structure. 15/21

  16. Proof: K0 K1 T F K1 K2 K0 K2 T T F F stop [0,1,2] stop [1,0,2] K1 K2 K0 K2 T T F F stop [1,2,0] stop [0,2,1] stop [2,0,1] stop [2,1,0] Decision tree for insertion sort on R0, R1, and R2 §9 A General Lower Bound for Sorting 【Theorem】Any algorithm that sorts by comparisons only must have a worst case computing time of ( N log N ). When sorting N distinct elements, there are N! different possible results. Thus any decision tree must have at least N! leaves. If the height of the tree isk, thenN!  2k1(# of leaves in a complete binary tree)  k log(N!) + 1 SinceN!  (N/2)N/2and log2N!  (N/2)log2(N/2) =  ( N log2N ) Therefore T(N) = k c  N log2N . 16/21

  17. 0 1 88 100 count §10 Bucket Sort and Radix Sort Bucket Sort 〖Example〗 Suppose that we have N students, each has a grade record in the range 0 to 100 (thus there are M= 101 possible distinct grades). How to sort them according to their grades in linear time? Algorithm { initialize count[ ]; while (read in a student’s record) insert to list count[stdnt.grade]; for (i=0; i<M; i++) { if (count[i]) output list count[i]; } } What if M >> N ? T(N, M) = O( M+N ) 17/21

  18. §10 Bucket Sort and Radix Sort Bucket 0 1 2 3 4 5 6 7 8 9 Pass 1 0 1 512 343 64 125 216 27 8 729 Pass 2 Pass 3 〖Example〗 Given N = 10 integers in the range 0 to 999 ( M= 1000 ) Is it possible to sort them in linear time? What if we sort according to the Most Significant Digit first? Radix Sort Input: 64, 8, 216, 512, 27, 729, 0, 1, 343, 125 Sort according to the Least Significant Digit first. T=O(P(N+B)) where P is the number of passes, N is the number of elements to sort, and B is the number of buckets. 0 512 125 343 64 1 216 27 8 729 0 125 216 343 512 729 1 8 27 64 Output: 0, 1, 8, 27, 64, 125, 216, 343, 512, 729 18/21

  19. §10 Bucket Sort and Radix Sort  A list of records R0, ..., Rn1 is lexically sorted with respect to the keys K 0, K 1, ..., K r1 iff That is, Ki 0 = Ki+10, ... , Ki l = Ki+1l, Ki l+1 < Ki+1l+1 for some l < r 1. K 0 [Suit]  <  <  <  K 1 [Face value] Sorting result : 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 < J < Q < K < A 2 ... A 2 ... A 2 ... A 2 ... A Suppose that the record Ri has r keys.  Ki j ::= the j-th key of record Ri  Ki 0 ::= the most significant key of record Ri  Ki r1 ::= the least significant key of record Ri 〖Example〗 A deck of cards sorted on 2 keys 19/21

  20. §10 Bucket Sort and Radix Sort 5  4  A       3     5  4  A   3   MSD ( Most Significant Digit ) Sort  Sort on K0: for example, create 4 buckets for the suits  Sort each bucket independently (using any sorting technique)     20/21

  21. §10 Bucket Sort and Radix Sort 2  2    ... 4   5       3  3      2  2   4    5  3  3  A  A    A  A   LSD ( Least Significant Digit ) Sort  Sort on K1: for example, create 13 buckets for the face values Home work: p.231 6.32 An application of Bucket Sort [ Think: why is it faster than O(N log N)? ]  Reform them into a single pile  Create 4 buckets and resort Question: Is LSD always faster than MSD? 21/21

More Related