插入排序(Insertion Sort)
Date:2019-05-10 20:12:27
直接插入排序
1 void InsertionSort(int A[], int n) 2 { 3 for(int i=1; i<n; i++) 4 { 5 int temp = A[i], j=i; 6 while(j>0 && temp<A[j-1]) 7 { 8 A[j] = A[j-1]; 9 j--; 10 } 11 A[j] = temp; 12 } 13 }
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定性:不会出现相同元素相对位置发生变化
- 适用性:顺序存储和链式存储
折半插入排序(二分插入排序)
void BinaryInsert(int A[], int n) { int i,j,low,high,mid; for(int i=1; i<n; i++) { int temp = A[i]; low=0; high=i-1; while(low <= high) { mid = (low+high)/2; if(A[mid] > temp) high = mid-1; else low = mid+1; } for(int j=i-1; j>=high+1; j--) A[j+1] = A[j]; A[high+1] = temp; } }
- 减少了比较元素的次数,约为O(Nlog2N)
- 由于没有并未减少移动元素的次数,时间复杂度依旧为O(N^2)
- 排序具有稳定性
希尔排序(缩小增量排序)
基本思想:先将待排序表分割成若干子表(A【i, i+d, i+2*d, ..., i+k*d】),对子表分别进行插入排序,当整个表呈现基本有序时,再对全体记录进行一次插入排序;
1 void ShellSort(int A[], int n) 2 { //步长d1,d2,d3,...,dk,且d1>d2>d3>...>dk=1 3 for(int d=n/2; d>=1; d=d/2) 4 { //对于各个子表分别进行插入排序 5 for(int i=d; i<n; i++) 6 { 7 if(A[i] < A[i-d]) 8 { 9 int temp=A[i]; 10 for(int j=i-d; j>0&&temp<A[j]; j-=d) 11 A[j+d] = A[j]; 12 A[j+d] = temp; 13 } 14 } 15 } 16 }
- 空间复杂度:O(1)
- 时间复杂度:最坏O(N^2),约为O(N^1.3)(依赖于增量序列函数,Open Problem)
- 稳定性:非稳定算法
- 适用性:顺序存储