前言:
插入排序的基本思想:在一个已排好序的序列子集的基础上,每一步将下一个待排序的数字有序插入到已排好序的序列子集中,直到将所有待排数据全部插入为止。
例如,打扑克牌时的抓牌就是插入排序的一个很好栗子,每抓一张牌,插入到合适位置,直到抓完牌为止,即可得到一个有序序列。
插入类排序分为三种:直接插入排序,折半插入排序,希尔排序。今天我们先介绍直接插入排序。
算法步骤:
其基本操作是将第i个数字插入到前面i-1个已排好序的序列中。
具体过程为:
将第i个数字的关键字Ki,顺次与前面的数字K(i-1),K(i-2),K(i-3)…K1进行比较,然后按照升序或者降序插入到合适的位置。
完整的插入排序是从i=2开始的,也就是说将第一个数字视为已排好序的单元素子集合,然后将第二个数字插入到单元素子集合中。i从2循环到n,即可实现完整的直接插入排序。
举个实例更为清晰:
如待排序序列为:77 19 80 79 20 11(升序)
A.{19 77} 80 79 20 11 //因为77>19,所以将19插入到77前面
B.{19 77 80} 79 20 11 //将80插入到77的后面
C.{19 77 79 80} 20 11 //依次将79与19,77,80比较,80>79,插到80的前面
D.{19 20 77 79 80} 11//因为19<20,77>20,将20插入到 77前面
E.{11 19 20 77 79 80}//19>11,将11插入到19前面
最终,插入排序完成,实现了有序。
代码实现:
void InsSort(int *array,int length)
{
int i,x,j;
for(i=2;i<=length;i++)
{
x=array[i];//x保存待插入的位置
j=i-1;
while(x<array[j])//寻找插入位置(从后往前查找),并且不断移动
{array[j+1]=array[j];
j--;
}
array[j+1]=x;//找到,插入其中
}
}
主程序:
int main()
{ int a[10]={48,62,35,77,55,15,35,98,6,12};
int i;
printf("待排序数组为:");
for(i=0;i<10;i++)
{ printf("%d ",a[i]);
}
printf("\n");
printf("排序后数组为:");
InsSort(a,10);
for(i=0;i<10;i++)
{ printf("%d ",a[i]);
}
return 0;
}
运行结果:
总结:
时间复杂度T(n)=O(n^2);
空间复杂度S(n)=O(1);
直接插入排序算法简单,比较适用于待排序记录数目较少且基本有序的情况。因为比较和移动的次数是比较耗费时间的。所以,当待排序序列数目比较大时,其性能就不好。