前提
void X_Sort ( ElementType A[], int N )
大多数情况下,为简单起见,讨论从小大的整数排序
N是正整数
只讨论基于比较的排序(> = < 有定义)
只讨论内部排序
稳定性:任意两个相等的数据,排序前后的相对位置不发生改变
1.冒泡排序
(从小到大排序)
物理意义:大泡泡往下沉,小泡泡往上冒
每次比较相邻两个泡泡,符合条件,交换位置,每一轮比较完,最大的泡泡沉到最底下。
最好情况:顺序T = O( N )
最坏情况:逆序T = O( N^2 )
稳定
1 #include <stdio.h> 2 3 typedef int ElementType; 4 5 void BubbleSort(ElementType A[], int N) 6 { 7 for(int P = N-1; P >= 0; P--) { 8 int flag = 0; 9 for(int i = 0; i < P; i++) { 10 if( A[i] > A[i+1] ) { 11 ElementType temp = A[i]; //swap A[i] A[i+1] 12 A[i] = A[i+1]; 13 A[i+1] = temp; 14 flag = 1; 15 } 16 } 17 if(flag == 0) 18 break; 19 } 20 } 21 22 int main() 23 { 24 int a[] = {34,8,64,51,32,21}; 25 BubbleSort(a,6); 26 for(int i = 0; i < 6; i++) 27 printf("%d ",a[i]); 28 29 return 0; 30 }
BubbleSort
2.插入排序
(从小到大排序)
和打扑克摸牌差不多,每次摸牌从最后往前依次进行比较,需插入的牌小,往前比较,找到合适位置插入。
最好情况:顺序T = O( N )
最坏情况:逆序T = O( N^2 )
1 #include <stdio.h> 2 3 typedef int ElementType; 4 5 void InsertionSort(ElementType A[], int N) 6 { 7 int i; 8 for (int P = 1; P < N; P++ ) { 9 ElementType temp = A[P]; //取出未排序序列中的第一个元素 10 for (i = P; i > 0 && A[i-1] > temp; i-- ) 11 A[i] = A[i-1]; //依次与已排序序列中元素比较并右移 12 A[i] = temp; 13 } 14 } 15 16 int main() 17 { 18 int a[] = {34,8,64,51,32,21}; 19 InsertionSort(a,6); 20 for(int i = 0; i < 6; i++) 21 printf("%d ",a[i]); 22 return 0; 23 }
InsertionSort
3.希尔排序
每5 3 1间隔数进行插入排序。
5 3 1成为增量序列。
定义增量序列DM > DM-1 > … > D1 = 1
对每个Dk 进行“Dk-间隔”排序( k = M, M-1, … 1 )
“Dk-间隔”有序的序列,在执行“Dk-1-间隔”排序后,仍然是“Dk-间隔”有序的
原始希尔排序DM = [N / 2]向下取整 , Dk = [D(k+1) / 2]向下取整
最坏情况: T =Ο( N^2 )
增量元素不互质,则小增量可能根本不起作用。
更多增量序列
Hibbard 增量序列
Dk = 2^k – 1 — 相邻元素互质
最坏情况: T = O ( N^ 3/2 )
猜想:Tavg = O ( N^ 5/4 )
Sedgewick增量序列
{1, 5, 19, 41, 109, … }
9*4^i – 9*2^i + 1 或4^i – 3*2^i + 1
猜想:Tavg = O ( N^ 7/6 ),Tworst = O ( N^ 4/3 )
1 #include <stdio.h> 2 3 typedef int ElementType; 4 5 /* 原始希尔排序 */ 6 void Shell_Sort(ElementType A[], int N) 7 { 8 int i; 9 for(int D = N/2; D > 0; D/=2) { 10 for(int P = D; P < N; P++) { 11 ElementType temp = A[P]; 12 for(i = P; i >= D && A[i-D]>temp; i-=D) 13 A[i] = A[i-D]; 14 A[i] = temp; 15 } 16 } 17 } 18 19 /* 希尔排序 - 用Sedgewick增量序列 */ 20 void ShellSort(ElementType A[], int N) 21 { 22 int Si, i; 23 /* 这里只列出一小部分增量 */ 24 int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0}; 25 26 for ( Si = 0; Sedgewick[Si] >= N; Si++ ) 27 ; /* 初始的增量Sedgewick[Si]不能超过待排序列长度 */ 28 29 for (int D = Sedgewick[Si]; D > 0; D = Sedgewick[++Si]) 30 for (int P = D; P < N; P++ ) { //插入排序 31 ElementType temp = A[P]; 32 for(i = P; i >= D && A[i-D]>temp; i-=D) 33 A[i] = A[i-D]; 34 A[i] = temp; 35 } 36 } 37 38 int main() 39 { 40 int a[] = {34,8,64,51,32,21}; 41 Shell_Sort(a,6); 42 ShellSort(a,6); 43 for(int i = 0; i < 6; i++) 44 printf("%d ",a[i]); 45 return 0; 46 }
ShellSort