算法基础(一)插入排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/firstchange/article/details/84582777

文章目录


算法导论在本章为我们展开了算法的画卷,介绍了几种基础的算法,并深化了其中的思想,让我们一起来看看。

插入排序

首先来看问题的描述:

在这里插入图片描述

我在代码大全里介绍过隐喻,现在在把它拿来再合适不过了。我们可以把插入排序看着是扑克牌,ok这样就好理解多了。

假设桌子上有几张牌{ 3, 9, 6, 10, K, J, 5}(我们忽略花色),现在我们要打牌,我们需要将牌进行排序,我们会这样做:

  1. 先抓一张3
  2. 再抓一张9,比较一下9 > 3,把牌插在3后面
  3. 再抓一张6,比较一下6 > 3且6 < 9,我们把牌插在3和9直接
  4. 重复执行

ok,我们就很容易地实现了一个插入排序的过程,其实很多算法就是在我们生活中,只是我们没有很好地去归纳。而且通过隐喻的方式去理解复杂,抽象的概念是非常有效的。我们再来理解一下书上的伪代码
在这里插入图片描述

第一行可以理解为牌堆里的牌,接下来把当前的牌存入临时变量中,i表示最后一张牌的顺序(一般打牌都是升序的)。那么while中的就相当于做比较的过程,思考究竟应该把牌插哪儿,假设我们很笨,一次只能看一张牌,我们从最后一张牌开始看。如果待插牌比较大,那就不要继续比较了,直接插在最后就行,如果待插牌比较小,我们就再往前进行比较,并且把相对大的牌往后移(这里和实际还是有些区别的,事实上我们插牌时并不会一个个后移)。按照这样依次抓牌,到最后我们手里的牌就是有序的了。

ok伪代码就如此搞定了,不难吧。

下面我们要用严格的数学来证明算法是正确的。
在这里插入图片描述

例子中是将序列{5, 2, 4, 6, 1, 3}进行排序。

证明的关键在于循环不等式:

  • 初始化:循环的第一次迭代之前,为真
  • 保持:如果循环的某次迭代之前为真,则下次迭代之前依然为真
  • 终止:在终止时,不等式为我们提供一个有用的性质,有助于证明算法是正确的

这类似于数学归纳法,为了证明某条性质成立,需要证明一个基本情况和一个归纳步。初始化为基本情况,保持则为归纳步。

ok,我们来看详细的证明过程:

在这里插入图片描述
如此插入排序算法的正确性就得以保证了。

小结

  • 通过隐喻来理解复杂抽象的概念是非常有效的
  • 算法的设计是需要通过严格的数学证明的

猜你喜欢

转载自blog.csdn.net/firstchange/article/details/84582777