八大排序算法—《直接插入排序》

八大排序之直接插入排序

什么是直接插入排序?

  直接插入排序是一种比较排序。
  在生活中也经常用到这种排序。
  比如在各类扑克游戏中,
  整理手牌的过程就是一种直接插入排序的体现。

直接插入排序原理

  1. 通过构建有序序列,将新的数据插入到已经有序的数据当中去。
  2. 首先将序列中搞得第一个元素看做是已经有序的序列。
  3. 取出下一个元素,与已经有序序列中从最后一个数据向前逐次进行比较,如果有序序列中的元素大于该元素,将这个元素(有序序列)向后移位一格。
  4. 重复步骤3,直到找到已排序序列中的某个元素小于等于该元素时,将其插入到该元素后一个位置。
  5. 重复3,4,直到整个数组有序。
图解:

用{11,7,9,13,22,5,2,17}来举例理解:
图1
第一趟排序 将第一个元素 11 看做是有序的序列,7作为下一个元素小于11,所以11向后移位,7填入11前的空位。
图2
第二趟,{7,11}已经是排序过的有序数组了,9作为下一个元素小于11,故11再向后移位,空出自己的位置。之后9与7作比较,元素9大于元素7,9小于已排序序列中的元素,将其填入该元素后,填入11后移之后的留下的空位。
图3
第三趟,{7,9,11}作为有序数组,下一个元素13大于11,位置不变。
图4
第四趟,同理,元素22大于有序数组中最大的值13,位置不变。
图5
第五趟,{7,9,11,13,22}为有序序列,5小于22,22后移。5小于13,13后移。5小于11,11后移。5小于9,9后移。5小于7,7后移。5填入7的位置。
图6
第六趟,{5,7,9,11,13,22}有序序列,同理2移动到5的位置,5,7,9,11,13,22依次后移一位。
图7
第七趟,{2,5,7,9,11,13,22}有序序列,17小于22,22后移,17大于13,填入13后的空位。排序完成。

算法复杂度

  • 直接插入排序在排列接近有序的数组时,时间复杂度可以达到O(N),比较次数大概为n-1次,移动数据次数也为n-1。
  • 但直接插入排序如果遇到接近逆序的数组时,时间复杂度为O(NN),此时比较次数约为n(n-1)/2,移动次数也接近n*n/2。
  • 所以,直接插入排序算法的复杂度是O(N^2)。是复杂度较高的排序算法。

代码实现

拿第一趟排序分析:
图
首先定义end为有序序列中最后一个元素,通过外层for循环的循环变量i来控制end,7要被替换为11,所以事先保存该元素(未排序序列中的第一个元素)定义x来保存该元素。替换后end–,扫描(有序序列中)end的前一个元素,当end扫描到有序序列中第一个元素时,end–为-1,此时在循环跳出,将保存的x赋值给end+1处。

代码如下:
void InsertSort(int* a, int n)
{
	assert(a);
	for (int i = 0; i < n - 1; i++)
	{
		int end = i;  // 使用i来控制end
		int x = a[end + 1]; // 提前保存要替换掉的元素
		while (end >= 0) // 当end-- 减到-1时跳出循环
		{
			if (a[end] > x)
			{
				a[end + 1] = a[end];
				--end;
			}
			else
			{
				break; // 如果该元素大于end,则证明不需要移动,直接跳出循环。
			}
			a[end + 1] = x;
		}
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值