插入排序

基本思想

每一步将一个待排序的数据插入到前面已经排好序的有序序列中,直到插完所有元素为止。

C++代码实现

//插入排序
void insertionSort(vector<int>& v)
{
	int tmp = 0;
	int i = 1, j = 0;		//从1开始比较是将第一个元素是有序的
	for (; i < v.size(); i++)
	{
		tmp = v[i];	//待排序元素
		j = i - 1;
		for (; j >= 0 && tmp < v[j]; j--)
		{
			//当前为排序元素比有序序列中的元素小,则有序序列元素后移一位
			v[j + 1] = v[j];
		}
		//当前为排序元素>= 有序序列元素或j < 0时,将未排序元素插入到该元素后面或有序序列头部
		v[j + 1] = tmp;
	}
}

排序过程

以[2, 2, 5, 1, 3] 为例,黑色加粗的2用来判断算法的稳定性。

第一轮排序,有序序列为[2], 无序序列为[2, 5, 1, 3]。
取无序序列中的第一个元素tmp = v[i] = 2(i = 1)与有序序列中的元素比较。
①j = 0, tmp >= v[j], 不执行循环体退出内层循环
j = -1 < 0, 将无序元素放入有序序列中第一个<= tmp 的元素后面,v[j + 1] = tmp。
第一轮排序结束,得到排序结果,有序序列更新为[2, 2],无序序列更新为[5, 1, 3]。这里可以发现黑色加粗的2依旧在未加粗的2前面。

第二轮排序,tmp = v[i] = 5(i = 2)
①tmp > v[j], 不执行循环体退出内层循环
将当前元素放入有序序列后面,即v[j + 1] = tmp。
第二轮排序结束,得到排序结果,有序序列更新为[2, 2, 5], 无序序列更新为[1, 3]

第三轮排序,tmp = v[i] = 1(i = 3)
①tmp < v[j] = 5, v[j] 后移一位, v[j + 1] = v[j], j-- = 1
②tmp < v[j] = 2, v[j] 后移一位, v[j + 1] = v[j], j-- = 0
③tmp < v[j] = 2, v[j] 后移一位, v[j + 1] = v[j], j-- = -1, 退出内层循环
将当前元素放到有序序列后面,即v[j + 1] = tmp。
第三轮排序结束,得到排序结果,有序序列更新为[1, 2, 2, 5], 无序序列更新为[3]

第四轮排序, tmp = v[i] = 3(i = 4)
①tmp < v[j] = 5, v[j] 后移一位, v[j + 1] = v[j], j-- = 2
②tmp > v[j] = 2, 退出内层循环
将当前元素放到有序序列后面,即v[j + 1] = tmp。
第四轮排序结束,有序序列更新为[1, 2, 2, 3, 5], 无序序列更新为[], 所以无序元素全部插入完毕,完成整体排序。

时间复杂度

可以发现在插入过程中的比较次数在区间[1, n - 1] 内,下面分析这两端的情况。

最好情况:
当待排序数组是有序时,是最优的情况。

只需当前数跟前一个数比较一下就可以了,这时整体排序一共需要比较n - 1次,最好时间复杂度为O(n)

最坏情况:
是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1,所以,插入排序最坏情况下的时间复杂度为O(n2)

综上插入排序的平均复杂度为O(n2)。

因而,插入排序不适合对于数据量比较大的排序应用。

但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。

空间复杂度

排序过程中我们只用到3个临时的变量,且不随数据规模n的变化而变化,所以整体空间复杂度为O(1)

算法稳定性

因为交换元素时,可以在相等的情况下做出不移动的限制,例上面黑色加粗的2和未加粗的2的相对位置并没有发生改变,所以归并排序是稳定的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值