算法思想:将第i个元素插入到前面i-1个已经排好序的记录中。
例如:
初始序列为:3 2 1 5 4 10 7 8 6 9共10个元素的序列,插入排序一般是从第二个元素开始的,所以总共会进行n-1轮
第一轮:将第2个元素2插入到{3}序列中并排序
2 3 1 5 4 10 7 8 6 9
第二轮:将第3个元素1插入到{2,3}序列中并排序
1 2 3 5 4 10 7 8 6 9
第三轮:将第4个元素5插入到{1,2,3}序列中并排序
1 2 3 5 4 10 7 8 6 9
第四轮:将第5个元素4插入到{1,2,3,5}序列中并排序
1 2 3 4 5 10 7 8 6 9
第五轮:将第6个元素10插入到{1,2,3,4,5}序列中并排序
1 2 3 4 5 10 7 8 6 9
第六轮:将第7个元素7插入到{1,2,3,4,5,10}序列中并排序
1 2 3 4 5 7 10 8 6 9
第七轮:将第8个元素8插入到{1,2,3,4,5,7,10}序列中并排序
1 2 3 4 5 7 8 10 6 9
第八轮:将第9个元素6插入到{1,2,3,4,5,7,8,10}序列中并排序
1 2 3 4 5 6 7 8 10 9
第九轮:将第10个元素9插入到{1,2,3,4,5,6,,7,8,10}序列中并排序得到最终序列
1 2 3 4 5 6 7 8 9 10
核心代码:
void insertSort(int a[],int n)
{
int i,j,temp;
for(i=1;i<n;i++)//从第二个元素开始,第一个元素本身就已经有序
{
temp=a[i];//temp用于临时保存带插入的元素a[i],每轮循环时都会更新
j=i-1;//从第i个元素之前的元素从后往前开始判断大小
while(j>=0&&a[j]>temp)//从0-j寻找可以插入的位置
{
a[j+1]=a[j];//将a[j]的值赋给a[j+1]
j=j-1;
}
a[j+1]=temp;// 将待插入的元素成功插入到序列中
}
}
算法分析:从空间上来看只需要一个辅助空间,空间复杂度为O(1),
对于插入排序而言,最好的情况是元素已经按照有序排列,只进行n-1次比较,移动元素的次数也达到最小值为2(n-1),即每一次只对带插入元素a[i]移动两次。
最坏情况是元素逆序排列,第i趟比较i次,此时比较次数为(n)(n-1)/2,第i趟移动i+2次,移动次数为(n+4)(n-1)/2;
,
时间复杂度为O(n^2);
同时,插入排序属于稳定排序算法。
C语言可执行代码:
#include<stdio.h>
void printArray(int a[],int n)
{
for(int i=0;i<n;i++)
printf("%-4d",a[i]);
printf("\n");
}
void insertSort(int a[],int n)
{
int i,j,temp;
for(i=1;i<n;i++)//从第二个元素开始,第一个元素本身就已经有序
{
temp=a[i];//用于临时保存带插入的记录,每轮循环时都会更新
j=i-1;//从第i个元素之前的元素从后往前开始判断大小
while(j>=0&&a[j]>temp)
{
a[j+1]=a[j];//将a[j+1]的值赋给a[j]
j=j-1;
}
a[j+1]=temp;// 将带插入的元素插入到序列中
printf("第%d轮排序后的结果:",i);
printArray(a,10);
}
}
int main(){
int a[10];
printf("please enter 10 numbers:\n");
for(int i=0;i<10;i++)
scanf("%d",&a[i]);
printf("the array before sort:\n");
printArray(a,10);
insertSort(a,10);
printf("the array after sort:\n");
printArray(a,10);
return 0;
}
运行结果: