没有幻灯片标题 - Zhejiang University

Download Report

Transcript 没有幻灯片标题 - Zhejiang University

§5 Heapsort
Algorithm 1:
{
BuildHeap( H );
/* O( N ) */
for ( i=0; i<N; i++ )
TmpH[ i ] = DeleteMin( H );
/* O( log N ) */
for ( i=0; i<N; i++ )
H[ i ] = TmpH[ i ]; /* O( 1 ) */
}
T ( N ) = O ( N log N )
 The space requirement is doubled.
1/21
§5 Heapsort
Algorithm 2:
A [0]
[1] b
d
ac
[3] b
d
c
d
b
ac
ac [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 );
}
}
Heapsort data start
【Theorem】The average
from number
position of
0. 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
§6 Mergesort
1. Merge two sorted lists
Lpos Lpos
1
Rpos Rpos
13 24 26
1
2
15 27 38
2
Tpos Tpos Tpos
T ( N ) = O ( N ) where N is the total number of
elements.
3/21
2. Mergesort
§6 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 */
If a TmpArray
is declared
TmpArray = malloc( N * sizeof( ElementType ) );
for
if ( TmpArraylocally
!= NULL
) { each call of Merge,
then
S(N) =0,O(
MSort( A,
TmpArray,
N - 1N);log N )
free( TmpArray );
}
else FatalError( "No space for tmp array!!!" );
}
4/21
§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 Mergesort
3. Analysis
T( 1 ) = 1
T ( N ) = 2T ( N / 2 ) + O( N )
= 2k T ( N / 2k ) + k * O( N )
= N * T ( 1 ) + log N * O( N )
= O( N + N log N )
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
6.14 sorting.
Home work:
p.229
Iterative version :
Mergesort without
…… …… n4 n3 n2
1
2
3
A 0
recursion
…… ……
…… ……
…… …… …… ……
6/21
n1
§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
13 43
31 57 26
65
0 pivot is
The
81
92 75
placed at
the right place65once
0 13 26 31 43 57
75
and for all.
81 92
0 13 26 31 43 57 65 75 81 92
7/21
§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
§7 Quicksort
3. Partitioning Strategy
>
<
<
>
<
<
<
>
<
<
>
28
1
4
59
0
3
695
82
7
i
i
i
i
i
ji
j
ij
j
Not
too
difficult
if
we
carefully
2=).
What
will
happen
to
No
swap…
but
then
T(
N
)
Then
T(
N
)
=
O(
N
Good
point!
How
about
stop
i
and
j…
both
Uh-oh, there will
be
many
dummy
What
if
there
is
a swaps…
implement
it…
the
sequence:
SoHow
we’d
better
stop
both
iwill
andbe
about
the
other
option
–j
and
then
swap?
But hey!
At least
the
sequence
==
1,neither
1,some
1,key
…,
1 ?pivot?
and
take
extra
swaps.
that
i
nor
j stops?
partitioned into two equal-sized
subsequences.
9/21
96
§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
§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
§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
6. Analysis
T( N ) = T( i ) + T( N – i – 1 ) + c N
§7 Quicksort
 The Worst Case:
T( N ) = T( N – 1 ) Home
+cN
work:
T( N ) = O( N2 )
 The Best Case: [ ...p.230
... ]  [ ...6.20
... ]
on
T( N ) = 2T( NMore
/ 2 ) + c analysis
N
T( N
) = O( N log N )
Read Figure 6.16 on p.214
Quicksort
 The Average Case:
th
for the 5 algorithm
N 1

1  on
T
(
j
)
thisi problem.


Assume the average value of T( isolving
) for any
is
N  j 0

2 
T(N )  
N

T ( j )   cN

j 0

N 1
T( N ) = O( N log N )
〖Example〗Given a list of N elements and an integer k.
Find the kth largest element.
13/21
§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
§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 [0] [1] [2] [3] [4] [5]
key d b f c a e
table 40 1 32 03 54 52
list [ table[0] ], list [ table[1] ], ……, list [ table[n1] ]
Note: Every permutation is made up of disjoint cycles.
list [0] [1] [2] [3] [4] [5]
a b cf d
key d
c ae ef
table 04 1 32 03 54 25
temp = d
4
5
current = 302
5
2
next = 43
In the worst case there are  N?/ 2 cycles and requires  3N
? / 2
record moves.
T = O( m N ) where m is the size of a structure.
15/21
§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 ).
Proof:
T
When sorting N distinct
F
elements, there are N! different
possible results.
K 0  K2
Thus any decision tree must
T
F
have at least N! leaves.
stop
K1  K2
[1,0,2]
If the height of the tree
K0  K1
K1  K2
T
stop
F
K 0  K2
[0,1,2]
T
F
T
F
stop
stop
stop
stop
[0,2,1]
[2,0,1]
[1,2,0]
[2,1,0]
Decision tree for insertion sort on R0, R1, and R2
is k, then N!  2k1 (# of
leaves in a complete
binary tree)
 k  log(N!) + 1
Since N!  (N/2)N/2 and log2 N!  (N/2)log2(N/2) =  ( N log2 N )
Therefore T(N) = k  c  N log2 N .
16/21
§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?
0
1
88
count
What if
M >> N ?
100
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];
}
}
T(N, M) = O( M+N )
17/21
§10 Bucket Sort and Radix Sort
〖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.
Bucket
0
1
2
3
Pass 1
0
1
Pass 2
0
1
8
512 125
216 27
729
125 216 343
Pass 3
0
1
8
27
64
512 343
4
5
6
64
125 216
343
64
512
7
8
9
27
8
729
729
Output: 0, 1, 8, 27, 64, 125, 216, 343, 512, 729
18/21
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.
§10 Bucket Sort and Radix Sort
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
 A list of records R0, ..., Rn1 is lexically sorted with respect
to the keys K 0, K 1, ..., K r1 iff
( K i0 , K i1 ,, K ir 1 )  ( K i01 , K i11 ,, K ir11 ), 0  i  n  1.
That is, Ki 0 = Ki+1 0, ... , Ki l = Ki+1 l, Ki l+1 < Ki+1 l+1 for
some l < r  1.
〖Example〗 A deck of cards sorted on 2 keys
K 0 [Suit]
 <  <  < 
K 1 [Face value]
Sorting result :
19/21
2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 < J < Q < K < A
2 ... A 2 ... A 2 ... A 2 ... A
§10 Bucket Sort and Radix Sort
 MSD ( Most Significant Digit ) Sort
 Sort on K 0: for example, create 4 buckets for the suits

4




4

A


5

3


 Sort each bucket independently (using any sorting
technique)

20/21
A



5


3

 LSD ( Least Significant Digit ) Sort
§10 Bucket Sort and Radix Sort
 Sort on K 1: for example, create 13 buckets for the face
values
5

5

4

A

... 
A




Home
 work: p.231 6.32
 Sort
An application of Bucket
4


3


3


2

2


[ Think: why is it faster than O(N log N)? ]
2
 

2


21/21
3


Question:
Is LSD always faster than MSD?

3

 Create 4 buckets and resort
A

A

 Reform them into a single pile