2021-05-26 数据结构排序专题【3】

逆向思考:插入以及谢尔排序

3.插入排序

前面学过的冒泡排序以及选择排序,都是按照惯性思维,从左边到右边逐个比较,交换,通过n-1趟的比较,不断在左边规模逐渐变小的列表中把最大的揪出来然后扔到右边去。

那么换个思路,从后面到前面排,要怎么排?

换个思维,从最小规模开始,单位为1的子列

然后从右边不断向左边插入符合规则的新项:

>第一趟,子列表仅包含一个数据项,将第二个数据项作为“新项”插入,子列表长度扩充为2

>第二趟,将第3个数据项跟前2个数据项对比,向右移动比自身大的数据项,空出位置来,直到遇到比自己小的数

>经过n-1趟对比和插入,子列表扩展到全表

代码实现:

ps:current_value变量在这里是用来存储的空间

移动操作的赋值只有一次,是交换操作的1/3,所以插入排序的性能会比冒泡和选择好一些

4.谢尔排序

承接上文,插入排序的性能优于冒泡和选择排序,因为粗略的来看,我们可以看到对比复杂度没有变的情况下,插入排序将交换操作减小到了一次。

那么更深入一点,我们能否优化插入排序?

我们可以看到,某一次排序最完美的情况对比时间复杂度是0(n),也就是列表已经排好序,从而可知,一个列表越接近有序,插入排序的对比次数就越少。

从这里切入,谢尔排序就是将一个庞大的列表间隔分割成几个子列表,再对每个子列表执行插入排序

得到所有子列表排序结果后,再对整个大数列进行最后一次插入排序(这时候无序程度已经大大减小)

代码实现:


几个小bug:

1.

>对int对象”遍历”,要加range转化成列表才能遍历

你可能感兴趣的:(2021-05-26 数据结构排序专题【3】)