插入排序
一、定义:将数组分成左右2个部分,左边的是有序的,右边的是无序的,按正序或反序,逐个把右边无序的插入到左边有序的,最终完成排序。
实现:
1.移动法
先把数组第0个元素看作是有序的,第1个元素之后是无序的,把第1个元素取出来保存,并与第0个元素进行比较,如果第0个元素大(或小),移动第0个元素到第1个元素位置(把第0个元素的值赋值给第1个元素),然后把保存的原第1个元素的值,赋值给第0个元素,实现插入,第0、1元素有序;然后把第2个元素取出来保存,并与其之前的有序元素从右向左,逐个比较,移动、插入,移动的条件是大(或小),插入的条件是不再大(或小)或者第0个元素也已经移动;第3、4...以此类推。
c语言代码:
1 /*插入排序*/ 2 #include <stdio.h> 3 void InsertSort(int *arr, int n) 4 { 5 int i; 6 for(i=1; i<n; ++i){/*第0个元素有序,从第1个元素向右无序*/ 7 int j=i-1,key=arr[i];/*保存第i个元素,左边的元素i-1*/ 8 while(j>=0 && key<arr[j]){/*保存的元素key与之前的元素从右向左逐个比较*/ 9 arr[j+1]=arr[j];/*移动(向后赋值)*/ 10 j--; 11 } 12 arr[j+1]=key;/*j--退出,恢复正确值j+1*/ 13 } 14 } 15 int main() 16 { 17 int i, arr[5]={9,8,1,4,3}; 18 InsertSort(arr,5); 19 for(i=0; i<5; ++i) 20 printf("%d ",arr[i]); 21 printf("\n"); 22 return 0; 23 }
2.交换法
先把数组第0个元素看作是有序的,第1个元素之后是无序的,把第1个元素,与第0个元素进行比较,如果第0个元素大(或小),交换,实现插入,第0、1元素有序;然后,第2个元素,与其之前的有序元素从右向左,逐个比较,交换,实现原来第2个元素的插入、有序;第3、4...以此类推。
c语言代码:
1 /*插入排序*/ 2 #include <stdio.h> 3 4 void Swap(int *a, int *b); 5 void InsertSort(int *arr, int n); 6 7 int main() 8 { 9 int i, arr[5]={9,8,1,4,3}; 10 InsertSort(arr,5); 11 for(i=0; i<5; ++i) 12 printf("%d ",arr[i]); 13 printf("\n"); 14 return 0; 15 } 16 17 void Swap(int *a, int *b) 18 { 19 int t = *a; 20 *a = *b; 21 *b = t; 22 } 23 24 void InsertSort(int *arr, int n) 25 { 26 int i; 27 for(i=1; i<n; ++i){/*第0个元素有序,从第1个元素向右无序*/ 28 int j=i;/*从第i个元素开始*/ 29 while(j>0 && arr[j-1]>arr[j]){/*与之前的元素从右向左逐个比较*/ 30 Swap(&arr[j-1],&arr[j]);/*交换,把原第i个元素的值向左推进*/ 31 j--; 32 } 33 } 34 }
二、插入排序的最好情况时间复杂度是O(N),最坏情况时间复杂度是O(N2),插入算法是稳定的;逆序对数即交换次数,如果序列基本有序,插入排序简单且高效,提高算法效率,每次不止消掉一个逆序对,即每次交换间隔较远的两个元素;
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; /* 放进合适的位置 */ } }
三、希尔排序,是不稳定的,
增量序列,Dk间隔有序的序列,在进行Dk-1间隔排序后,Dk间隔依然是有序的
void ShellSort( ElementType A[], int N ) { /* 希尔排序 - 用Sedgewick增量序列 */ 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++ ) ; /* 初始的增量Sedgewick[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; } }