用 Python 学习算法:初级排序算法
2017-12-01 19:55
423 查看
摘要:
1. 使用 Python 实现初级排序算法:选择排序,插入排序,冒泡排序,希尔排序
2. 简单分析比较四种排序算法的性能
如需下载本文中的代码,关注公众号后,回复“初级排序” 即可获得下载链接~。
这一组数据,一般情况下都是指数组,Python 中则指列表。需要注意的是,我们没有限定数组内部具体每个元素是什么类型。常见的也就是:整数,实数,字符串等等,当然我们也可以自己定义数据类型,自定义的数据类型需要满足一个条件,那就是元素之间可以比较大小。
我参考学习的主要是《算法》这本书,其中就提及我们使用的数据类型需要通过 Comparable 接口实现 less() 方法。没看懂这句话?并没有没什么影响。这句话的意思就是说,我们使用的数据类型必须能比较大小。感觉在 Java 中实现起来有点小麻烦,但是在 Python 中则相对比较简单,我们需要定义重载运算符
下面我们介绍三种排序算法:选择排序 、插入排序 和 冒泡排序,并做简单的分析。使用的数据为整数或者实数列表。
这里有一点需要注意,在 Python 中交换两个变量的值,并不需要中间再定义一个临时变量
这里需要注意的是 len() 函数的用法,如果 datalist 是一个列表,则不用操心。但是如果 datalist 是我们自定义的数据类型,就得注意在类中加入
找到数组中最小的那个元素
将这个最小的元素与第一个元素互换位置
在剩下的元素中找到一个最小的元素
将这个最小的元素与第二个元素互换位置
依次类推,直到最后
下面给出相应的 Python 代码:
代码看上去很简单,并不复杂,主要是因为这个算法本身就比较简单。
我们从第 2 个元素开始(其索引为 1,因为从零开始索引),对比第 2 个元素与第 1 个元素,如果第 2 个元素小于第 1 个元素,则交换两者的位置。
然后是第 3 个元素,把它和第二个元素对比,如果第三个元素比较小,则交换两者位置。这时第 3 个元素在 第二个元素的位置,然后对比它与第一个元素的位置,如果小,则交换。
然后对第4…,N个元素分别进行相同的操作。
具体的流程,我们可以参考如下的动态演示图:
使用 Python 代码实现上述的过程:
比较相邻的两个元素,如果第一个元素比第二个元素大,则交换这两个元素。
从头到尾,将每一对相邻元素,做如上的处理。这样第一圈下来,最后一个元素一定是最大的元素。
针对处理最后一个元素外的所有元素在进行上述操作。(因为最后的元素已经是最大的了,不用进行对比了)
直到所有元素排序完成为止。
上述的过程就和我们的选择排序算法道理是一样的,将最大的那个数放在最后。具体流程参照如下的演示图:
上面我们举的例子都是整数的例子,正如一开所说的那样, 在 Python 我们可以自定义数据类型,只有这种数据类型是可以比较大小的,我们都可以进行排序,下面我们给出一个自定义的数据类型:日期。然后针对自定义的数据类型,使用上述介绍的三种排序算法进行排序。
在 Date 类中,我们定义了
下面,我们随机生成一些日期,将其放在列表中,然后进行排序,具体程序如下:
我们随机生成了 30 个日期对象,放在 date 这个列表中,然后调用了 选择排序函数对这个列表中的元素进行排序,然后打印结果。结果中第一列为原始数据,第二列为排序后的数据。
需要注意一点,在进行列表复制的时候,我们的程序是:
而不是
如果是第二种写法的话,再对 date 中的元素进行排序后, temp 中的元素也会改变。
1. 使用 Python 实现初级排序算法:选择排序,插入排序,冒泡排序,希尔排序
2. 简单分析比较四种排序算法的性能
写在最前面
更多内容,请关注我的公众号: PythonAndMachineLearning如需下载本文中的代码,关注公众号后,回复“初级排序” 即可获得下载链接~。
简介
关于排序的具体定义,这里就不多说了,写多了我都觉得是一些没有的废话。总之一句话,就是将给定的一组数据,按照从小到大或者从大到小的顺序进行排列。这一组数据,一般情况下都是指数组,Python 中则指列表。需要注意的是,我们没有限定数组内部具体每个元素是什么类型。常见的也就是:整数,实数,字符串等等,当然我们也可以自己定义数据类型,自定义的数据类型需要满足一个条件,那就是元素之间可以比较大小。
我参考学习的主要是《算法》这本书,其中就提及我们使用的数据类型需要通过 Comparable 接口实现 less() 方法。没看懂这句话?并没有没什么影响。这句话的意思就是说,我们使用的数据类型必须能比较大小。感觉在 Java 中实现起来有点小麻烦,但是在 Python 中则相对比较简单,我们需要定义重载运算符
__lt__()即可,关于这一点,后面会具体提及。
下面我们介绍三种排序算法:选择排序 、插入排序 和 冒泡排序,并做简单的分析。使用的数据为整数或者实数列表。
准备工作
在具体介绍之前,我们首先介绍几个简单的辅助函数:exch() 函数
def exch(datalist, i, j): ''' - 交换 datalist 中第 i 个数与第 j 个数的位置 ''' datalist[i], datalist[j] = datalist[j], datalist[i]
这里有一点需要注意,在 Python 中交换两个变量的值,并不需要中间再定义一个临时变量
isSorted() 函数
def isSorted(datalist): ''' - 检测 datalist 中的元素是否有序 ''' for i in range(len(datalist)-1): if datalist[i] > datalist[i+1]: return False
这里需要注意的是 len() 函数的用法,如果 datalist 是一个列表,则不用操心。但是如果 datalist 是我们自定义的数据类型,就得注意在类中加入
__len__()重载操作符。
选择排序
选择排序算法算是一种最简单的排序算法,其步骤如下:找到数组中最小的那个元素
将这个最小的元素与第一个元素互换位置
在剩下的元素中找到一个最小的元素
将这个最小的元素与第二个元素互换位置
依次类推,直到最后
下面给出相应的 Python 代码:
# _*_ encoding:utf-8 _*_ ''' Created on 2017\11\29 @author: wangs0622 ''' import sort # 上面给出的几个辅助函数都在 sort 这个文件中存放 def selectionSort(data): for i in range(len(data)): min_index = i for j in range(i,len(data)): if data[j] < data[min_index]: min_index = j sort.exch(data, i, min_index) if __name__ == '__main__': data = [5,3,6,9,12,35,32,89,43,1,-2,-5,24,100,-34,23,43,23,89,11] selectionSort(data) print data
代码看上去很简单,并不复杂,主要是因为这个算法本身就比较简单。
选择排序算法简单分析
虽然这个算法看上去简洁明了,但是其计算时间比较长。假设给定的数组长度为 N,则整个程序运行下来,我们需要进行大概 N2/2 次比较,并进行 N 次交换。插入排序
插入排序,这种排序的原理也相对简单。我们从某个位置的元素开始,我们认为,这个元素左边的数组已经有序了,按照从小到大的顺序排列。我们需要做的是,将这个元素插入到左边有序数组的合适位置,使得加入这个元素后,这个数组依旧有序。具体步骤如下:我们从第 2 个元素开始(其索引为 1,因为从零开始索引),对比第 2 个元素与第 1 个元素,如果第 2 个元素小于第 1 个元素,则交换两者的位置。
然后是第 3 个元素,把它和第二个元素对比,如果第三个元素比较小,则交换两者位置。这时第 3 个元素在 第二个元素的位置,然后对比它与第一个元素的位置,如果小,则交换。
然后对第4…,N个元素分别进行相同的操作。
具体的流程,我们可以参考如下的动态演示图:
使用 Python 代码实现上述的过程:
def insertionSort(data): for i in range(1, len(data)): temp = range(i) temp.reverse() for j in temp: if data[j+1] < data[j]: sort.exch(data, j, j+1)
插入排序算法简单分析
插入排序所需的时间取决于输入列表中元素的顺序,如果输入列表本身就是有序的,那我们需要做 N−1 次比较, 0 次交换。这也是最理想的情况了。最糟糕的情况下,我们需要做 N2/2 次比较, N2/2 次交换。由此可见,插入排序要比选择排序更加高效。冒泡排序
冒泡排序与选择排序有异曲同工之妙。当初我学习 C++ 的时候就遇见过这个名词,貌似还是一个考试重点。如今,关于 C++ 的知识基本上都快还给老师了,不过“冒泡排序”这个名词依稀还记得,因为这个名字起的很有特色,很难忘记。具体的排序步骤如下:比较相邻的两个元素,如果第一个元素比第二个元素大,则交换这两个元素。
从头到尾,将每一对相邻元素,做如上的处理。这样第一圈下来,最后一个元素一定是最大的元素。
针对处理最后一个元素外的所有元素在进行上述操作。(因为最后的元素已经是最大的了,不用进行对比了)
直到所有元素排序完成为止。
上述的过程就和我们的选择排序算法道理是一样的,将最大的那个数放在最后。具体流程参照如下的演示图:
def bubbleSort(data): for i in range(len(data)-1): for j in range(len(data)-i-1): if data[j] > data[j+1]: sort.exch(data, j, j+1)
冒泡排序复杂度简单分析
冒泡排序的操作次数也与列表元素的初始情况有关,最好的情况就是已经排好顺序的情况,这种情况下,我们需要做大概 N2/2 次比较,0 次交换;最差的情况就是输入列表是按照从大小的顺序排列,我们大概需要做 N2/2 次比较,并做 N2/2 次交换。总体来讲,不比选择排序高效。上面我们举的例子都是整数的例子,正如一开所说的那样, 在 Python 我们可以自定义数据类型,只有这种数据类型是可以比较大小的,我们都可以进行排序,下面我们给出一个自定义的数据类型:日期。然后针对自定义的数据类型,使用上述介绍的三种排序算法进行排序。
自定义数据类型举例
我们自定义的数据类型是日期,它包括了年、月、日三个变量,其定义大小的习惯于我们日常习惯相同,下面给出具体的代码:class Date(): def __init__(self, year = 0, month = 0, day = 0): self.year = year self.month = month self.day = day def __lt__(self, date): if self.year < date.year: return True elif self.year > date.year: return False else: if self.month < date.month: return True elif self.month > date.month: return False else: if self.day < date.day: return True else: return False def __repr__(self): return (str(self.year) + ' - '+ str(self.month) + ' - ' + str(self.day))
在 Date 类中,我们定义了
__lt__()方法,这个方法在两个 Date 对象使用 ‘<’ 的时候,自动调用。例如: date1 < date2,此时自动调用
__lt__()方法,相当于 date1.
__lt__(data2)。
__repr__()方法在之前的“用 Python 学习算法 – 链表” 那篇文章中已经介绍过了,简单来说,这个函数在我们打印对象的时候,自动调用。
下面,我们随机生成一些日期,将其放在列表中,然后进行排序,具体程序如下:
if __name__ == '__main__': date = [] for i in range(30): year = random.randint(2000,3000) month = random.randint(0,12) day = random.randint(0,30) date.append(Date(year, month, day)) temp = date[:-1] selectionSort(date) for x, y in zip(temp, date): print x, ' ', y
我们随机生成了 30 个日期对象,放在 date 这个列表中,然后调用了 选择排序函数对这个列表中的元素进行排序,然后打印结果。结果中第一列为原始数据,第二列为排序后的数据。
需要注意一点,在进行列表复制的时候,我们的程序是:
temp = date[:-1]
而不是
temp = date
如果是第二种写法的话,再对 date 中的元素进行排序后, temp 中的元素也会改变。
相关文章推荐
- 算法学习(1):排序算法-插入排序及python实现
- 算法第四版学习笔记之初级排序算法
- [数据结构与算法]排序算法(Python)
- 【排序算法】图解算法——用眼睛学习算法
- STL学习笔记----14.STL算法之 (排序算法)
- python--初级学习之numpy模块的安装
- 无需复杂深度学习算法,基于计算机视觉使用Python和OpenCV计算道路交通
- 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 用C++/lua/python/bash的四重实现(7)习题2.8 随机数组的三种生成算法
- STL学习笔记----14.STL算法之 (排序算法)
- 算法导论学习笔记-1-基础排序算法
- [python]感知机学习算法实现
- 算法学习-排序算法-快速排序
- ZH奶酪:【数据结构与算法】基础排序算法总结与Python实现
- 算法导论—排序算法学习(1)
- python学习之面向对象【入门初级篇】
- 【备忘】2017年最新北风网零基础学习机器学习(Python语言、算法、Numpy库、MatplotLib)视频教程)
- Python算法学习计划
- 感知机学习算法的简单实现(Python)
- 算法学习之排序算法(五)(高速排序)
- 聚类算法——python实现学习向量量化(LVQ)算法