- 插入排序:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的字表中的适当位置,直到全部记录插入完成为止。
代码如下:
void InsertSort(int array[] , int n){ //按递增有序进行排序
int i,j ;
int tmp ;
for(i=1;i<n;i++){
tmp=array[i];
j=i-1;
while(j>=0 && tmp<array[j]){ //从右往左在有序区中找到插入array[i]的位置
array[j+1]=array[j]; //讲关键字大于array[i]的记录后移
j--;
}
array[j+1]=tmp; //在j+1处插入array[i]
}
}
分析:
直接插入排序由两层循环构成。外循环表示要进行n-1趟排序,在每一趟排序中,仅当出入的记录array[i]>=array[i-1]时才无需进入内循环。当初始表按关键字递增有序的时候,则每一趟排序仅需进行一次关键字的比较,则有Cmin=o(n),Mmin=2( C指的是比较次数 M 指的是移动次数).反之当为反序时则有Cmax=o(n*n),Mmax=o(n*n)
改进:考虑到每一次插入都是在有序的情况下进行则可以通过二分查找进行查找要插入的位置,使得每一次关键字的比较次数减少了。
代码如下:
//二分插入排序
void InsertSort1(int array[] , int n){
int i,j,low,high,mid;
int tmp ;
for(i=1;i<n;i++){
tmp = array[i] ;
low=0;
high=i-1;
while(low<=high){
mid=(low+high)/2;
if(tmp<array[mid]){
high=mid-1;
}else
low =mid+1;
}
for(j=i-1;j>=high+1;j--)
array[j+1]=array[j];
array[high+1]=tmp;
}
}