1.顺序法定位插入——直接插入排序:
在数组中下标为0的不存数据,数据从下标1开始存储,要实现排序,首先我们要先找有序的部分(例如 3 4 5 9 7 11,在7之前的数都是(升序)有序的,所以我们找到了7这个数,将7存到下标为0的位置,即a[0]=7;将7之前的数依次比较,比a[0]中的值大就后移,不满足时将a[0]这个数插入到不满住条件的那个数之前。就成了:3 4 5 7 9 11)。
(1)先找到那个数,复制要插入的元素(2)记录后移,查找插入位置(3)插入数据
重复执行就可完成排序。
代码实现:
//时间复杂度:最好(O(n)) 最坏(O(n^2)) 平均(O(n^2))
//空间复杂度:借助哨兵(O(1))
void insert_sort(int *a,int len)
{
int i,j;
for(i=2;i<len;i++)
{
//如果这个数比前一个数小,就要交换
if(a[i]<a[i-1])
{
//把小的数存放再a[0]位置,作为哨兵
a[0]=a[i];
//将前面比这个数大的数后移
for(j=i-1;a[0]<a[j];j--)
{
a[j+1]=a[j];
}
a[j+1]=a[0];
}
}
}
2.二分法定位插入——折半插入排序:
与直接插入排序的步骤一致,只是将依次比较换成了更高效的二分查找。
代码实现:
void BinInsertSort(int *a,int len)
{
int i,j;
int left;
int right;
int mid;
for(i=2;i<len;i++)
{
if(a[i]<a[i-1])
{
a[0]=a[i];
left=1,right=i-1;
//查找要插入的位置
while(left<=right)
{
mid=(left+right)/2;
if(a[0]<a[mid])
{
right=mid-1;
}
else
{
left=mid+1;
}
}
for(j=i-1;j>right;j--)
{
a[j+1]=a[j];
}
a[j+1]=a[0];
}
}
3.缩小增量多遍插入——希尔排序:
就是将待排序序列分成若干份,进行多次直接插入排序;在序列基本有序的时候在全体进行一次增量为1的排序。
代码实现:
void shell_sort(int *a,int len)
{
int i,j,k,incre;
//incre为增量,可自行设置
for(incre=len/2;incre>0;incre/=2)
{
for(i=1+incre;i<len;i+=incre)
{
if(a[i]<a[i-1])
{
a[0]=a[i];
for(j=i-incre;a[0]<a[j];j-=incre)
{
a[j+incre]=a[j];
}
a[j+incre]=a[0];
}
}
}
}