一、基本操作
将一个记录插入到已排好序的有序表中,从而得到一个新的、记录数增1的有序表。这就是我们理解的一趟直接插入排序过程。
二、流程
- 明确一趟直接插入排序过程如何实现。
- 整个排序过程进行n-1趟插入。
- 时间复杂度是O(n^2),空间复杂度是O(1),因为比较始终发生在两个相邻元素之间,没有发生跳跃交换,所以是稳定的排序算法。
三、算法描述
四、C语言实现
原则上是函数实现的功能尽可能单一。所以我把比较关键字值的过程封装成一个函数,进行传入参数的合法性检查的过程封装成一个接口,较为复杂的是插入排序的主体部分。
int comp(int e1, int e2) //如果e1 < e2,返回非零;否则返回0
{
return e1 < e2;
}
void insertSort_call(int *arr, int n, int(*comp)(int e1, int e2)) //根据法则comp进行直接插入排序
{
for (int i = 1; i < n; ++i) //i最主要的功能是控制趟数同时又被作为下标使用,根据实际情况从1开始
{
if (comp(arr[i], arr[i - 1])) //arr[i]<arr[i-1]
{
int sentry = arr[i]; //设置哨兵值
int j;
for (j = i - 1; j > -1 && comp(sentry, arr[j]); --j)//控制下标防止访问越界
arr[j + 1] = arr[j]; //每次后移一个元素
arr[j + 1] = sentry;
}
}
}
void insertSort(int* arr, int n) //API,呈现给用户的接口,只做参数合法性检查。
{
assert(arr != NULL && n > 0);
insertSort_call(arr, n, comp);
}
测试用例:
void printArray(int *arr, int n) //打印输出数组的函数
{
assert(NULL != arr && n > 0);
for (int i = 0; i < n; ++i)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = { 98,87,76,65,54,43,32,21 };
int n = sizeof(arr) / sizeof(arr[0]);
insertSort(arr, n);
printArray(arr, n);
return 0;
}