目录
1.概念和逻辑
插入排序在日常生活中随处可见,大多数人从小也都会,比如打牌时摸牌来进行排序的过程就是插入排序,具体过程可看下图。

也就是第一个数不用排序,从第二个数开始就需要进行插入排序。将第二张与第一张进行比较,如果比第一张大,那么直接排在第一张后面,如果比第一个数小,那么第一个数就先后移动一位,再将第一个数放在第一位的位置。那么第三个数同理,先与第二个数(末尾数)进行比较,如果比它小,就需要把末位数进行向后移位,末尾数更新为前一个数,然后再与现在的末尾数进行比较,知道比它大或者末位向前到-1为止,当比它大时,就将这个数插入到此时末尾数的后一个。
2.代码
接下来我们看我的插入排序源码。
void InsertSort(int* a, int n) {
int i = 0;
for (i = 1;i < n;i++) {
int end = i - 1;
int tmp = a[i];
while (end >= 0) {
if (tmp < a[end]) {
a[end + 1] = a[end];
end--;
}
else
break;
}
a[end + 1] = tmp;
}
}
我们先来分析插入排序的一趟排序,源码和分析如下。
void InsertSort(int* a,int n) {
int end = 0;//a[end] == 9
int tmp = a[1];//8
while (end >= 0) {
if (tmp < a[end]) {
a[end + 1] = a[end];
end--;
}
else
break;
}
a[end + 1] = tmp;
}
int main() {
int a[] = { 9,8,7,6,5,4,3,2,1 };
InsertSort(a,sizeof(a)/sizeof(int));
PrintArray(a, sizeof(a) / sizeof(int));
return 0;
}
输出结果如下:

这就是单趟排序。
我们在对代码补充,使得插入排序完整的进行。
#include <stdio.h>
void InsertSort(int* a,int n) {
int i = 0;
for (i = 1;i < n;i++) {
int end = i - 1;
int tmp = a[i];
while (end >= 0) {
if (tmp < a[end]) {
a[end + 1] = a[end];
end--;
}
else
break;
}
a[end + 1] = tmp;
}
}
void PrintArray(int* a, int n) {
int i = 0;
for (i = 0;i < n;i++) {
printf("%d ",a[i]);
}
printf("\n");
}
int main() {
int a[] = { 9,8,7,6,5,4,3,2,1 };
InsertSort(a,sizeof(a)/sizeof(int));
PrintArray(a, sizeof(a) / sizeof(int));
return 0;
}
输出结果如下:

我们还可以对每一趟排序都进行打印来观察,只需在每次插入后打印数组即可。
输出结果如下,其过程附和文章开头的过程。

3.时间复杂度
最差时间复杂度为O(n^2),也就是当数组是逆序的时候,此时的运行次数是一个公差为1的等差数列。最佳时间复杂度为O(n),也就是当数组是顺序的时候,此时也需要遍历一遍数组。
1657

被折叠的 条评论
为什么被折叠?



