排序算法的比较
一、简单排序(冒泡、插入)
1. 冒泡排序
void Bubble_sort ( ElementType A[ ] , int N)
{
for ( P = N - 1 ; P >= 0 ; P-- ) {
flag = 0 ;
for ( i = 0 ; i < P; i++ ) {
if ( A[ i] > A[ i + 1 ] ) {
Swap ( A[ i] , A[ i + 1 ] ) ;
flag = 1 ;
}
}
if ( flag == 0 ) break ;
}
}
2. 插入排序
void InsertionSort ( ElementType A[ ] , int N )
{
int P, i;
ElementType Tmp;
for ( P= 1 ; P< N; P++ ) {
Tmp = A[ P] ;
for ( i= P; i> 0 && A[ i- 1 ] > Tmp; i-- )
A[ i] = A[ i- 1 ] ;
A[ i] = Tmp;
}
}
二、希尔排序
void ShellSort ( ElementType A[ ] , int N )
{
int Si, D, P, i;
ElementType Tmp;
int Sedgewick[ ] = { 929 , 505 , 209 , 109 , 41 , 19 , 5 , 1 , 0 } ;
for ( Si= 0 ; Sedgewick[ Si] >= N; Si++ )
;
for ( D= Sedgewick[ Si] ; D> 0 ; D= Sedgewick[ ++ Si] )
for ( P= D; P< N; P++ ) {
Tmp = A[ P] ;
for ( i= P; i>= D && A[ i- D] > Tmp; i- = D )
A[ i] = A[ i- D] ;
A[ i] = Tmp;
}
}
三、堆排序
void Swap ( ElementType * a, ElementType * b )
{
ElementType t = * a; * a = * b; * b = t;
}
void PercDown ( ElementType A[ ] , int p, int N )
{
int Parent, Child;
ElementType X;
X = A[ p] ;
for ( Parent= p; ( Parent* 2 + 1 ) < N; Parent= Child ) {
Child = Parent * 2 + 1 ;
if ( ( Child!= N- 1 ) && ( A[ Child] < A[ Child+ 1 ] ) )
Child++ ;
if ( X >= A[ Child] ) break ;
else
A[ Parent] = A[ Child] ;
}
A[ Parent] = X;
}
void HeapSort ( ElementType A[ ] , int N )
{
int i;
for ( i= N/ 2 - 1 ; i>= 0 ; i-- )
PercDown ( A, i, N ) ;
for ( i= N- 1 ; i> 0 ; i-- ) {
Swap ( & A[ 0 ] , & A[ i] ) ;
PercDown ( A, 0 , i ) ;
}
}
四、归并排序
void Merge ( ElementType A[ ] , ElementType TmpA[ ] , int L, int R, int RightEnd )
{
int LeftEnd, NumElements, Tmp;
int i;
LeftEnd = R - 1 ;
Tmp = L;
NumElements = RightEnd - L + 1 ;
while ( L <= LeftEnd && R <= RightEnd ) {
if ( A[ L] <= A[ R] )
TmpA[ Tmp++ ] = A[ L++ ] ;
else
TmpA[ Tmp++ ] = A[ R++ ] ;
}
while ( L <= LeftEnd )
TmpA[ Tmp++ ] = A[ L++ ] ;
while ( R <= RightEnd )
TmpA[ Tmp++ ] = A[ R++ ] ;
for ( i = 0 ; i < NumElements; i++ , RightEnd -- )
A[ RightEnd] = TmpA[ RightEnd] ;
}
void Msort ( ElementType A[ ] , ElementType TmpA[ ] , int L, int RightEnd )
{
int Center;
if ( L < RightEnd ) {
Center = ( L+ RightEnd) / 2 ;
Msort ( A, TmpA, L, Center ) ;
Msort ( A, TmpA, Center+ 1 , RightEnd ) ;
Merge ( A, TmpA, L, Center+ 1 , RightEnd ) ;
}
}
void MergeSort ( ElementType A[ ] , int N )
{
ElementType * TmpA;
TmpA = ( ElementType * ) malloc ( N* sizeof ( ElementType) ) ;
if ( TmpA != NULL ) {
Msort ( A, TmpA, 0 , N- 1 ) ;
free ( TmpA ) ;
}
else printf ( "空间不足" ) ;
}
void Merge_pass ( ElementType A[ ] , ElementType TmpA[ ] , int N, int length )
{
int i, j;
for ( i= 0 ; i <= N- 2 * length; i + = 2 * length )
Merge ( A, TmpA, i, i+ length, i+ 2 * length- 1 ) ;
if ( i+ length < N )
Merge ( A, TmpA, i, i+ length, N- 1 ) ;
else
for ( j = i; j < N; j++ ) TmpA[ j] = A[ j] ;
}
void Merge_Sort ( ElementType A[ ] , int N )
{
int length;
ElementType * TmpA;
length = 1 ;
TmpA = malloc ( N * sizeof ( ElementType ) ) ;
if ( TmpA != NULL ) {
while ( length < N ) {
Merge_pass ( A, TmpA, N, length ) ;
length * = 2 ;
Merge_pass ( TmpA, A, N, length ) ;
length * = 2 ;
}
free ( TmpA ) ;
}
else printf ( "空间不足" ) ;
}
五、快速排序
#include <stdlib.h>
int compare ( const void * a, const void * b)
{
return ( * ( int * ) a - * ( int * ) b) ;
}
qsort ( A, N, sizeof ( int ) , compare) ;
struct Node {
int key1, key2;
} A[ MAXN] ;
int compare2keys ( const void * a, const void * b)
{
int k;
if ( ( ( const struct Node* ) a) -> key1 < ( ( const struct Node* ) b) -> key1 )
k = 1 ;
else if ( ( ( const struct Node* ) a) -> key1 > ( ( const struct Node* ) b) -> key1 )
k = - 1 ;
else {
if ( ( ( const struct Node* ) a) -> key2 < ( ( const struct Node* ) b) -> key2 )
k = - 1 ;
else
k = 1 ;
}
return k;
}
qsort ( A, N, sizeof ( struct Node) , compare2keys) ;
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] ) ;
Swap ( & A[ Center] , & A[ Right- 1 ] ) ;
return A[ Right- 1 ] ;
}
void Qsort ( ElementType A[ ] , int Left, int Right )
{
int Pivot, Cutoff, Low, High;
if ( Cutoff <= Right- Left ) {
Pivot = Median3 ( A, Left, Right ) ;
Low = Left; High = Right- 1 ;
while ( 1 ) {
while ( A[ ++ Low] < Pivot ) ;
while ( A[ -- High] > Pivot ) ;
if ( Low < High ) Swap ( & A[ Low] , & A[ High] ) ;
else break ;
}
Swap ( & A[ Low] , & A[ Right- 1 ] ) ;
Qsort ( A, Left, Low- 1 ) ;
Qsort ( A, Low+ 1 , Right ) ;
}
else InsertionSort ( A+ Left, Right- Left+ 1 ) ;
}
void QuickSort ( ElementType A[ ] , int N )
{
Qsort ( A, 0 , N- 1 ) ;
}
六、基数排序
#define MaxDigit 4
#define Radix 10
typedef struct Node * PtrToNode;
struct Node {
int key;
PtrToNode next;
} ;
struct HeadNode {
PtrToNode head, tail;
} ;
typedef struct HeadNode Bucket[ Radix] ;
int GetDigit ( int X, int D )
{
int d, i;
for ( i= 1 ; i<= D; i++ ) {
d = X % Radix;
X / = Radix;
}
return d;
}
void LSDRadixSort ( ElementType A[ ] , int N )
{
int D, Di, i;
Bucket B;
PtrToNode tmp, p, List = NULL ;
for ( i= 0 ; i< Radix; i++ )
B[ i] . head = B[ i] . tail = NULL ;
for ( i= 0 ; i< N; i++ ) {
tmp = ( PtrToNode) malloc ( sizeof ( struct Node) ) ;
tmp-> key = A[ i] ;
tmp-> next = List;
List = tmp;
}
for ( D= 1 ; D<= MaxDigit; D++ ) {
p = List;
while ( p) {
Di = GetDigit ( p-> key, D) ;
tmp = p; p = p-> next;
tmp-> next = NULL ;
if ( B[ Di] . head == NULL )
B[ Di] . head = B[ Di] . tail = tmp;
else {
B[ Di] . tail-> next = tmp;
B[ Di] . tail = tmp;
}
}
List = NULL ;
for ( Di= Radix- 1 ; Di>= 0 ; Di-- ) {
if ( B[ Di] . head) {
B[ Di] . tail-> next = List;
List = B[ Di] . head;
B[ Di] . head = B[ Di] . tail = NULL ;
}
}
}
for ( i= 0 ; i< N; i++ ) {
tmp = List;
List = List-> next;
A[ i] = tmp-> key;
free ( tmp) ;
}
}
#define MaxDigit 4
#define Radix 10
typedef struct Node * PtrToNode;
struct Node{
int key;
PtrToNode next;
} ;
struct HeadNode {
PtrToNode head, tail;
} ;
typedef struct HeadNode Bucket[ Radix] ;
int GetDigit ( int X, int D )
{
int d, i;
for ( i= 1 ; i<= D; i++ ) {
d = X% Radix;
X / = Radix;
}
return d;
}
void MSD ( ElementType A[ ] , int L, int R, int D )
{
int Di, i, j;
Bucket B;
PtrToNode tmp, p, List = NULL ;
if ( D== 0 ) return ;
for ( i= 0 ; i< Radix; i++ )
B[ i] . head = B[ i] . tail = NULL ;
for ( i= L; i<= R; i++ ) {
tmp = ( PtrToNode) malloc ( sizeof ( struct Node) ) ;
tmp-> key = A[ i] ;
tmp-> next = List;
List = tmp;
}
p = List;
while ( p) {
Di = GetDigit ( p-> key, D) ;
tmp = p; p = p-> next;
if ( B[ Di] . head == NULL ) B[ Di] . tail = tmp;
tmp-> next = B[ Di] . head;
B[ Di] . head = tmp;
}
i = j = L;
for ( Di= 0 ; Di< Radix; Di++ ) {
if ( B[ Di] . head) {
p = B[ Di] . head;
while ( p) {
tmp = p;
p = p-> next;
A[ j++ ] = tmp-> key;
free ( tmp) ;
}
MSD ( A, i, j- 1 , D- 1 ) ;
i = j;
}
}
}
void MSDRadixSort ( ElementType A[ ] , int N )
{
MSD ( A, 0 , N- 1 , MaxDigit) ;
}
七、排序算法的比较