Archive note: Recovered from the Wayback Machine. 10 historical images referenced by the original page were not captured; their positions are marked below.

首先是关于搜索的算法讨论:

此处我们采用的算法设计手法称作”自顶而下设计”。我们现在需要找出一个列表中的最小的两个值的索引,我们至少有以下三种方法解决:

  • 查找,移除,查找。找出最小元素索引,然后移除之,然后再找新的列表最小元素索引。
  • 排序,表示最小元素,获取索引。对列表排序然后获取最小的两个数,然后找出他们在原始列表的索引。
  • 扫描列表。逐个检查列表每个元素,记录下当前已经找到的最小的两个元素,当找到更小的时候更新索引。

*首先是第一种的实现代码如下:*

[Historical image unavailable in the recovered snapshot: 032914_0729_Python11.png].

*然后第二种方法:排序,标示最小元素,获取索引。*

主要的算法步骤如下:

[Historical image unavailable in the recovered snapshot: 032914_0729_Python21.png].

代码如下:

[Historical image unavailable in the recovered snapshot: 032914_0729_Python31.png].

下面是第三种方法:

算法的具体步骤:

[Historical image unavailable in the recovered snapshot: 032914_0729_Python41.png].

实现的代码如下:

[Historical image unavailable in the recovered snapshot: 032914_0729_Python51.png].

当然这三个算法都是很简单的,我们需要学习的不是实现算法的代码,而是这种”自顶而下设计”算法的方法。

下面就开始正式关于算法的一些内容:

**首先是线性搜索,**线性搜索分为基本线性搜索,for循环线性搜索,哨兵搜索三种搜索。下面是这三种搜索方法的实现方法代码:首先是第一种基本线性搜索的实现代码:

[Historical image unavailable in the recovered snapshot: 032914_0729_Python61.png].

然后是for循环线性搜索实现代码:

[Historical image unavailable in the recovered snapshot: 032914_0729_Python71.png].

这种算法会比第一种基本搜索快很多。

第三种:

[Historical image unavailable in the recovered snapshot: 032914_0729_Python81.png].

下面是对以上三种方法所用时间的测试:

测试的是一个含有一百万个数字的(1-1000000)列表L,分三种测试,当搜索的元素在列表首,列表中部,列表尾部时候的运行所需要的时间。

[TABLE]

所需要的时间如下:

[Historical image unavailable in the recovered snapshot: 032914_0729_Python91.png].

*然后是二分搜索。*

具体原理和意义就不说了(二分搜索,顾名思义)。下面是实现代码:

[TABLE]

下面是测试时间的代码:

Python Code

[TABLE]

由于要用到nose模块,无奈没找到支持2.X 的nose模块,所以在此处不再运行说下结果就是无论搜索的元素的位置在哪儿,搜索所需要的时间都是大概相同的,而且是很快的。

其实Python的标准库中bisect模块有一些内置的比二分搜索算法快得多的二分搜索函数。

  1. import bisect

  2. L = [1,3,3,6,8,12,15]

  3. x = 3

  4. x_insert_point = bisect.bisect_left(L,x)  #在L中查找x,x存在时返回x左侧的位置,x不存在返回应该插入的位置..这是3存在于列表中,返回左侧位置1

  5. print x_insert_point

  6. x_insert_point = bisect.bisect_right(L,x) #在L中查找x,x存在时返回x右侧的位置,x不存在返回应该插入的位置..这是3存在于列表中,返回右侧位置3

  7. print x_insert_point

  8. x_insort_left = bisect.insort_left(L,x) #将x插入到列表L中,x存在时插入在左侧

  9. print L

  10. x_insort_rigth = bisect.insort_right(L,x) #将x插入到列表L中,x存在时插入在右侧

  11. print L

有一个应用实例:如下:学生成绩分级

Python Code

[TABLE]

最后是关于排序的算法:有选择排序,插入排序,以及更加高效的合并排序。

下面是选择排序的代码:选择排序就是将列表一分为二,前面的一部分含有目前已经排好序的值,后面的那部分则含有尚未排序的值,即是选择排序就是不断的从未排序区域中挑选出下一个最小值,并将其放到已经排好序的区域的末尾,由于我们是按照顺序挑选各个元素的,因此此算法是有效的。具体过程就是:首先我们找出最下的元素,并将其放到开始的位置,然后我们找出第二小的元素,将其放到第二个位置上。

Python Code

[TABLE]

测试代码如下:

Python Code

[TABLE]

下面是插入排序的:插入排序和选择排序类似,但是,该算法是将在未排序区域的中的直接拿出一个值并将其插入到已经排好序的区域中的适当位置中。

试下代码如下:

Python Code

[TABLE]

下面是关于以上两个算法的时间性能测试:代码为

Python Code

[TABLE]

从结果可以看出的一点是,插入排序要稍微更快一些,原因很简单,选择排序每次都要找出最小值,扫描所有的未排序区域。但是list.sort()实在是太快了。

下面说一下更高效的合并排序:获取两个已经排序的列表,然后将他们合并成一个。

下面是合并排序的代码:

Python Code

[TABLE]

下面是合并排序函数:

Python Code

[TABLE]

一个简单的测试:

Python Code

[TABLE]

结果:

[Historical image unavailable in the recovered snapshot: 032914_0729_Python101.png].

至此,所有的基础知识扫盲算是告一段落。

计划以下博文:

《Python图像处理基础》

《Python测试基础》

《Python面向对象编程基础》