排序算法___插入原则___直接插入排序

一、基本操作

将一个记录插入到已排好序的有序表中,从而得到一个新的、记录数增1的有序表。这就是我们理解的一趟直接插入排序过程。

二、流程

  1. 明确一趟直接插入排序过程如何实现。
  2. 整个排序过程进行n-1趟插入。
  3. 时间复杂度是O(n^2),空间复杂度是O(1),因为比较始终发生在两个相邻元素之间,没有发生跳跃交换,所以是稳定的排序算法。

三、算法描述

图1 《数据结构·严蔚敏》第265页

四、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;
}

猜你喜欢

转载自blog.csdn.net/qq_41822235/article/details/86548285