直接插入排序即是在要排序的数组中,假设前n-1(n>=2)个数已经是排好序的,现在要把第n个数插入到前n个已经排好序的数组中,使得这n个数也变成有序的,如此反复循环,使得要排序的数组中的最后一个元素也排好序。
我们可以先假设第一个数是排好序的,然后第二个数和第一个数进行比较,如果第二个数比第一个数大,那么说明前两个数排好序,无需做调整,如果第二个数比第一个数小,那么就把第一个数向后移,将第二个数放在第一个数的位置上,抽象出来就是用a[i]和a[i-1]进行比较,如果a[i]>a[i-1],那么就说明前i个数是已经排好序的,如果a[i]<a[i-1],就让j=i-1,temp=a[i],然后一边将数据a[j]向后移动,一边向前搜索,直到找到a[j]<a[i]时停止,并将temp放到a[j+1]处即可。此算法是稳定。
代码如下
#include <stdio.h>
#define MAXSIZE 100
void print(int *p, int len)
{
int i;
for(i = 0;i < len;i++)
printf("%d ", p[i]);
printf("\n");
}
void Insert_sort(int *p, int len)
{
int i, j;
for(i = 1;i <= (len - 1);i++) //等待插入排序元素的下标
{
int new = p[i];
for(j = (i - 1);j >= 0;j--) //从等待排序的前一个元素,依次向前遍历
{
if(p[j] > new) //如果已经排序的元素比待排序的元素大,则将已经排序的元素依次向后移动,直至待排序的元素
p[j + 1] = p[j];
else
break; //直到比待排序元素小退出循环
}
p[j + 1] = new; //将待排序的元素插入到比之小的元素后面
}
}
int main()
{
int len = 0;
char string[100];
char *str = string;
int a[MAXSIZE] = {0};
printf("请输入要排序的数字\n");
gets(string);
while(*str != '\0')
{
while((*str != ' ') && (*str != '\0')) //例如输入"0 12 32 4",依次识别四个数
{
a[len] = *str - '0'; //将字符串里面的字符型数字转换成整形
str++;
}
len++;
while(*str == ' ')
str++;
}
print(a, len);
Insert_sort(a, len);
print(a, len);
return 0;
}
时间复杂度:
考虑最坏的情况,即待排序序列中各数据元素为逆序状态,在每一趟中,当前待插入元素与前面已经排好序的有序序列的每一个元素都要进行一次比较,同时做一次数据移动。所以总比较次数为1+2+.....+n=n(n-1)/2次。此时,移动次数是n(n-1)/2。所以时间复杂度为O(n²)。