一.插入排序
(一).基本思想
把待排序的的几个值按照顺序逐个插入到一个已经排好序的有序序列中,直到所有值插入完成,得到一个新的有序序列.
(二).举例
(三).动图演示
1.全过程动图演示
2.一趟过程演示:
数组中有4,2,6,5,0
假设前四个元素已经排好序2,4,5,6,现在要把数组中的最后一个元素0插入进去
(四).代码实现
以升序为例:
注意:写插入排序时应该充分考虑到边界条件(for循环结束条件)和极端情况
思路:
1.先写一趟的排序过程(假设前end个元素已经排好序了,把第end+1个元素插入进去)
2.再给外面加个for循环,即可实现多趟插入排序,进而完成整个排序
void PrintArray(int* a, int n)
//打印函数,用来打印数组中的元素,验证程序运行结果是否正确
{
for (int i = 0; i < n; ++i)
{
printf("%d ", a[i]);
}
printf("\n");
}
void InsertSort(int* a, int n)
{
for (int i = 0; i < n - 1; ++i)
//为什么i<n-1而不是i<n,因为end+1才是待排序的那个元素
//end+1 < n 等价于 end < n-1
{
//[0,end]有序,把end+1位置的值插入,保持有序
int end = i;
int tmp = a[end + 1];
while (end >= 0)
{
if (tmp < a[end])//升序
{
a[end + 1] = a[end];
--end;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
void TestInsertSort()//测试插入排序
{
int a[] = { 9,2,1,4,7,5,3,8,6 };
InsertSort(a, sizeof(a) / sizeof(int));
PrintArray(a, sizeof(a) / sizeof(int));
}
int main()
{
TestInsertSort();
return 0;
}
(五).复杂度分析
时间复杂度为O(N^2)
最优:O(N) 按顺序排或者接近有序 1,2,3,4,5,6,8,7,9
最坏;O(N^2) 完全逆序 9,8,7,6,5,4,3,2,1
显然我们可以看出,插入排序在数组接近有序时,效率非常高,为O(N)
这样,就引出了下节我们要讨论的希尔排序.