一、简介
插入排序类似于我们玩扑克牌,如果想要让我们手中的牌有序,那么当我们从牌堆中抽出一张牌放入自己手中的牌组内时,需要把这张牌和手中最大的牌开始向前比较,直到找到一个大于前面的牌小于后面一张牌的情况下插入即可。
在网上看到此动图,特别能说明插入排序的思想,因此把它放在这里。
二、时间复杂度
- 逆序时间复杂度最坏,因为每次插入都需要移动数据,所以时间复杂度为 O(N^2)
- 有序最好,不需要移动数据,所以时间复杂度O(N)
三、实现
插入排序的实现我们可以先从单趟排序入手,假设我们需要插入的数字是end,则我们需要向前插入,此时我们需要一个循环从后向前来找到插入位置,找插入位置的同时把遍历过的结点向后移动,即我们插入位置的结点永远为空,方便我们进行插入。最后在从1到len进行循环即可完成插入排序。
步骤:
- 写一个外循环,从1到整个排序数组的最后一个len
- 定义end为我们排序的有序区间最后一个数,此时注意边界情况。
- 内循环是一个从i到1的一个循环,如果插入结点后的一个元素大于我们要插入的结点,则把此结点向后移动,如上图步骤2与步骤3.
- 找到插入结点后把end赋值给插入结点即可。
四、代码
#include <iostream>
#include <assert.h>
using namespace std;
void InsertSort(int* a,int len)
{
assert(a);
for (size_t i = 1; i < len; i++)
{
int end = a[i];
size_t j = i;
for (; j > 0 && a[j - 1] > end; --j)
{
//挑选插入位置
a[j] = a[j - 1];
}
//插牌的过程
a[j] = end;
}
}
int main()
{
int arr[] = { 5,4,8,6,1,5,4,3,1,0 };
int len = sizeof(arr) / sizeof(arr[0]);
InsertSort(arr, len);
for (size_t i = 0; i < len; i++)
cout << arr[i] << endl;
return 0;
}