1、基本思想
(1)想象 3的前面是一个空的有序数组
(2)先将3 放入这个有序数组,然后从第2个元素开始,逐个和有序数组中的元素 排序
横向:插入新的元素后,有序数组的自我调整
纵向:有序数组调整完毕,有序数组多一位成员
(3)直到end到达第 size-1 位
size:数组元素的个数
2、代码实现
(1)单次有序数组的调整过程
假设 以end = 2的调整为例
int end = 2;
int val = a[end + 1]; //事先记录下每次要插入的数,要插入的数是有序数组的后一位
while (end >= 0)
{
if (a[end]>val)
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = val; //end = -1时,会跳出循环,说明有序数组中的所有元素都比val要小
(2)直接插入排序
我们每次将上述过程放在一个for循环中,使用for循环的 局部变量 i 来重置end
void InsertSort(int* a,int size)
{
//注意end最多到达 尾元素的前一位
for (size_t i = 0; i < size-1; i++)
{
int end = i; //重置end的值
int val = a[end + 1]; //事先记录下每次要插入的数
while (end >= 0)
{
if (a[end] > val)
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = val; //end = -1时,会跳出循环,说明有序数组中的所有元素都比val要小
}
}
3、代码测试
int main() {
int arr[] = { 3,5,2,6,1,7,4,8 };
InsertSort(arr, sizeof(arr) / sizeof(arr[0]));
for (size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
4、时间复杂度
最坏的情况是逆序,也就是每次都要将插入的元素移到 第一个位置
移动的次数为 1 + 2 + 3 + ... + N-1 = N(N-1)/2
所以时间复杂度为:O(N^2)