插入排序更加类似于我们平时玩扑克,每次将新拿到的牌,插入到手中已有的牌之中,那么插入排序应该分为两个过程
1:拿牌,2:选择位置将牌插入。
int insert_sort (int *ar ,int length)
{
int i;
int j;
int key; \\将手中摸到的牌记录为关键字key
for(j=1;j<=length;j++) \\外部循环就类似于摸牌的过程
{
key=ar[j];
i=j-1; \\记录手里最后一张牌;因为每次摸牌前,都保证了手里的牌是有序的,通过比较最后一张牌,判断是否插入
while(i>=0&&key<ar[i]) \\后一张牌小于前一张牌,将牌插入
{
ar[i+1]=ar[i]; \\判断牌插入的位置
ar[i]=key;
i--;
}
}
}
上述代码就基本 上实现了 插入排序的过程
当最好情况下,数组有序排列,我们只需要摸牌,不需要插入(比较也只需比较一次),时间复杂度为O(n),而当全部逆序排列时,每次插入比较都需比较J次,时间复杂度为O(n^2);
但对于上述插入排序,我们有些地方 仍然可以改进,在插入位置的选择,因为手中的牌在每次循环,始终保证有序,所以我们可以通过折半查找,来减少比较的次数。
改进后 就是折半插入排序
int binary_insert_sort(int *ar,int high) //high表示数组的长度
{
int i;
int j;
int key;
int position;
for(j=2;j<=high;j++)
{
key=ar[j];
i=j-1;
if(key<ar[i])
{
position=binarySearch(ar,1,i,key);
while(i>=Position)
{
ar[i+1]=ar[i];
i--;
}
ar[position]=key;
}
}
}
int binarySearch(int *ar,int lwo,int high,int key)
{
int mid;
mid=(low+high)/2
while(low<=high)
{
if(key>ar[mid]);
low=mid+1;
else
high=mid-1;
}
return high;
}<span style="font-size:18px;">
</span>
通过折半插入排序,改变了排序过程中,进行比较的次数,但移动的次数没变,时间复杂度仍为O(n^2)。
插入排序和折半插入排序的时间复杂度为O(n^2),适用于数据量不大的排序表。基于这两天1956年D.L.shell 提出了希尔排序