当待排序列中记录的排序是递增有序(也就是从小到大的有序记录,称正序)时,达到最小的比较次数:n-1,最小的移动次数:0;相反的是,当待排序列中记录的排序是非递增有序(比如从大到小的有序记录,称逆序)时,需要进行n-1趟排序,得到最大比较次数:(n+2)(n-1)/2,最大的移动次数:(n+4)(n-1)/2。还有平均比较次数为:(n+2)(n-1)/4,平均移动次数为:(n+6)(n-1)/6。所以直接插入排序算法的时间复杂度为O(
),整个算法只需要一个key的辅助变量,所以空间复杂度为O(1)。
相关算法如下:
#include <stdio.h>
/*void InsetSort(int arr[],int i) 这个为比较规范的代码格式,常规的看下面的
{
int key=arr[i];
int j=i-1;
while(i>=0&&arr[i]<arr[j])
{
arr[j]=arr[j+1];
j--;
}
arr[i]=key;
}
void InserttionSort(int arr[],int n)
{
int i;
for (i=1;i<n;i++){
InsetSort(arr,i);
}
}*/
void insetsort(int arr[],int n) //需要传入数组名和元素个数两个参数
{
int i,j,key; //定义i的意义为:将第i个位置的值插入到有序序列之中
for(i=1;i<n;i++) //因为数组中第一个元素,也就是下标为0的位置,默认为有序的,所以i开始值为1,i<n的原因为i只可能到达n-1的下标位置,没有下标为n的位置。
{
key=arr[i]; //因为快速排序总是比较后,把i前面的数移动到后面,准确来说就是把i-1位置的值赋值给 i,这样会导致i位置原来的值会被覆盖丢失,这个时候我们需要事先把i位置的数值保存到另外一个变量里面,这里将i的值先保存到key中
j=i-1; //因为需要反复和i-1位置的值进行比较,所以把i-1定义为一个变量j会更加更加清晰
while(j>=0&&arr[j]>arr[i]) //j为i-1的位置,肯定是不能小于0的,并且只有当arr[j]大于arr[i]时才会进入循环,因为如果小于的话,本身就是有序的
{
arr[j+1]=arr[j]; //将i-1位置的值覆盖到i的位置,实际的目的是把i前面位置的元素后移一个位置
j--; //因为一直是和i位置的值进行比较,所以i在第一轮循环中都是不变的,j第一次比较后,会移动到i-2的位置继续与i的值进行比较
}
arr[j+1]=key; //当退出上面的循环后,意味着i前面的值已经全部比i的值小了,所以此时确定i的位置就是j+1的位置,并将被覆盖的i最开始的值赋值给现在j+1的位置
}
}
int main()
{
int arr[5]={2,32,4,5,33};
int i; //定义循环变量i
insetsort(arr,5); //调用插入排序函数,并传入参数
// InserttionSort(arr,5);
for(int i=0;i<5;i++) //输出数组中的数值
{
printf("%d\n",arr[i]);
}
return 0;
}