《算法导论》阅读笔记——插入排序

今天读了《算法导论》,趁晚上有些许空闲时间做一下读书笔记。

插入排序

        排序问题是算法题中非常重要又基础的部分,完成排序有许多算法,冒泡排序,桶排序,插入排序,快速排序等等。以下我写一些我对插入排序的一些理解和提供伪代码。

插入排序思想

        对于少量元素的排序,插入排序是一个有效的算法,插入排序的工作方式,像许多人排序一手扑克牌。开始时,我们的左手为空并且桌子上的牌面向下。然后,我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较,拿在左手上的牌总是排序好的,原来这些牌时桌子上牌堆中顶部的牌。

插入排序伪代码

INSERTION-SORT(A)
1 for j = 2 to A.length
2     key = A[j]
3     //Insert A[j] into the sorted sequence A[1...j-1].
4     i = j -1
5     while i > 0 and A[i] > key
6         A[i+1] = A[j]
7         i = i -1
8     A[i + 1] = key 

        在上面的伪代码中,我们并没有完全依照“从桌子上拿牌放到左手上进行排序”的步骤,而是“所有未排序的牌都在手上”。其中,A表示输入数组,在初始时,A中的所有元素均未排序。A.length表示A的长度,key表示本次循环中选中需要插入排序的元素。

        在第2行代码,我们将 A[j] 中的元素放入到 key 中。因为 A 数组是一个变化的数组,在不断插入排序的过程中,数组的每一个元素都有可能发生改变,一旦我们没有存放当前元素,在下面的步骤中,我们移动元素时可能就会将当前元素覆盖掉,我们就丢失了当前元素是什么了。

        在第4行代码,我们将 i = j - 1,目的是让当前需要排序的元素与之前已经排序好的元素进行对比,即 key (= A[j] )与 A[i] 进行比较大小,然后按照升序降序的需要来完成特定的插入操作。

        在5~7行代码,我们先来看 while 循环的条件,while 循环中有 2 个条件,一个是 i > 0 ,另一个是  A[i] > key ,并且为与关系。A[i]>key 很好理解,因为我们是升序,所以当前一个元素比我当前元素要大,那么我就要把我的元素插入到前面去,那为什么需要 i > 0呢?因为我们是将当前元素与前面元素进行对比,但我们的循环并不能一直往前走,当一直比较到第一个元素(即目前已排序好的序列中的最小元素)时,就无法再往前比较了。A[i+1] = A[j] ,当确认我的当前元素比前一个元素小时,那么就需要把前一个元素往后移,这样我的当前元素才能插入。 i = i -1,下一次循环对比更前面一个元素。

        在第8行代码,A[i+1] = key 在空出来的位置中放入当前元素。 

        如果还是不太理解的话,可以看一下下面这副图片,用图片的方式形式化地表现了插入排序的过程。

 

 分析算法

        我们在考察一个算法的优劣程度时,有一个重要的度量——计算时间。我们往往集中于只求最坏情况运行时间,即对规模为n的任何输入,算法的最长运行时间。

        在上面的插入排序算法的伪代码中,我们很容易看出,算法包含了两个循环,第一个 for 循环一共需要循环 n-1 次(循环从 j=2 开始),但这个 for 循环中还包含了一个 while 循环,当输入情况是最坏情况(即反序)时,我们每次 while 都需要将当前位置的元素调到最前面。此时,我们可以列出最坏情况下的运行时间:

T(n)=c_{1}n+c_{2}(n-1)+c_{3}(n-1)+c_{5}(\frac{n(n+1)}{2}-1)+c_{6}(\frac{n(n-1)}{2})+c_{7}(\frac{n(n-1)}{2})+c_{8}(n-1)

        显然,它是一个 n 的二次函数,在这里的系数c是指计算机在做每一步指令时所需要花费的时间,我们一般把它看成一个常数。

        增长量级

        我们很多时候在分析算法的时间复杂度时,一般只分析最坏情况下的运行时间,除此之外,我们一般指用一种更简化的抽象,即我们真正感兴趣的运行时间的增长率或增长量级。所以我们只考虑公式中最重要的项,在上述公式中,最重要的项就是指数最大的项,因为当 n 十分巨大时,相比于指数最大的项,其它项对于时间消耗的影响就没有那么大了。其中,该项的系数对时间消耗的影响也很小,也可以省略。所以,我们记插入排序具有最坏运行时间 \theta(n^{2})

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苏三有春

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值