插入排序是归并排序的基础,插入排序的模型可以类比打牌的时候,将牌插入到合适的位置这一过程,这个过程很自然。
说实在,学算法这么长的时间,对这些自然的过程反而很难用语言表述清楚,话不多说,代码如下:
def insert_sort(L):
i = 0
while i < len(L) - 1:
j = i+1
key = L[j]
while j >= 1 and L[j-1] > key:
L[j] = L[j-1]
j -= 1
L[j] = key
i += 1
return L
上述的代码是精简后的代码,对于我来说,这个代码虽然精简,但是有很多的步骤是合并的,导致这种代码我很少能在第一个版本里写出来(所谓的第一个版本就是按照自己的思路,白板写出来的代码),换句话说,这种精简的代码,对我来说是不自然的,我无法直接感知他的存在,阅读的时候,也不一定能够直接反应出这是插入排序,下面的代码通常是我的第一反应,代码如下:
def insert_sort(L):
i = 0
while True:
if i >= len(L) - 1:
break
j = i+1
key = L[j]
while True:
if j <= 0:
break
if L[j-1] <= key:
break
L[j] = L[j-1]
j -= 1
L[j] = key
i += 1
return L
是不是觉得有点奇怪,这两段代码是等价的,你只要对某些语句做个等价的变化就很容易的得到另外一套代码,之所以会这样,是因为我个人并不是编码的高手,我的第一反应是,我只能思考一步的动作,我很难将多个步骤合并成一步,当然,当我完成第一版本的时候,我可以通过重构来实现精简的版本。这时候你会问这两个版本那个版本才是更好的,通常意义上说,精简的版本是最好的,因为精简的版本把很多繁琐的步骤合并了,你可以通过读一句就能很好的明白代码在干什么,但是,我还是那句话,我不是编码的高手,对于我来说第二个版本才是我的第一反应,我能做的是,在完成第二个版本之后,通过重构的手段,精简成第一个版本。
每个人对编码的认识都是不同的,我相信,通过个人的这种编码习惯,你总可以找到一个适合自己的编码方式,而这种方式往往不具有通用性,它只适合你自己,因为每个人认识世界的方式都不一样,可能你我的方式比较low,但是那是我们能做的最好的程度。
之前,有人和我说多都源码,读源码你就能成为编码的高手,我一直问自己是不是真的!我的答案是,读源码是有好处的,不过更多的还是需要自己独立的思考,你要经常问自己,如果是我来做设计,我会怎么做?而不是简简单单的认为别人写的源码就是足够好的,因为,对于个人,我们的接受程度都是不同的,业务源码真的足够好,但是不一定适合你,因为那是别人认识世界的方式,对于你自己,你应该也有一套认识世界的方式,别人的方式或许比较通用,你的比较独特,不要否定自己的世界观,只能,适度的让他适应这个所谓的通用的世界观。
以后,我写的代码都是我的第一反应,因为我知道,这种方式是适合自己的,精简代码,只是另一种认识世界的方式。
另外,补充一点,我一直再说的是编码方式,而不是算法,对于特定的算法,其核心思想是一致的,也就是说,编码方式只是算法的显示表现方式,换句话说,如果算法的核心思想是有问题的,不论你采用何种编码方式,你的代码都是有问题的,算法和编码需要分开,算法的学习重要的是思想的体现,编码侧重的是实现的方面,这两个能力对于一个合格的程序员同等的重要!!!