用python实现各种排序算法
最简单的排序有三种:插入排序,选择排序和冒泡排序。它们的平均时间复杂度均为O(n^2),在这里对原理就不加赘述了。
贴出源代码:
插入排序:
def insertion_sort(sort_list):
iter_len = len(sort_list)
if iter_len < 2:
return sort_list
for i in range(1, iter_len):
key = sort_list[i]
j = i - 1
while j>=0 and sort_list[j]>key:
sort_list[j+1] = sort_list[j]
j =j - 1
sort_list[j+1] = key
return sort_list
冒泡排序:
def bubble_sort(sort_list):
iter_len = len(sort_list)
if iter_len < 2:
return sort_list
for i in range(iter_len-1):
for j in range(iter_len-i-1):
if sort_list[j] > sort_list[j+1]:
sort_list[j], sort_list[j+1] = sort_list[j+1], sort_list[j]
return sort_list
选择排序:
def selection_sort(sort_list):
iter_len = len(sort_list)
if iter_len < 2:
return sort_list
for i in range(iter_len-1):
smallest = sort_list[i]
location = i
for j in range(i, iter_len):
if sort_list[j] < smallest:
smallest = sort_list[j]
location = j
if i != location:
sort_list[i], sort_list[location] = sort_list[location], sort_list[i]
return sort_list
其中:
sort_list[i], sort_list[location] = sort_list[location], sort_list[i]
是不是觉得很奇怪?没错,这是交换两个数的做法,通常在其他语言中如果要交换a与b的值,常常需要一个中间变量temp,首先把a赋给temp,然后把b赋给a,最后再把temp赋给b。但是在python中你就可以这么写:a, b = b, a,其实这是因为赋值符号的左右两边都是元组(这里需要强调的是,在python中,元组其实是由逗号“,”来界定的,而不是括号)。
平均时间复杂度为O(nlogn)的算法有:归并排序,堆排序和快速排序。
归并排序。对于一个子序列,分成两份,比较两份的第一个元素,小者弹出,然后重复这个过程。对于待排序列,以中间值分成左右两个序列,然后对于各子序列再递归调用。源代码如下,由于有工具函数,所以写成了callable的类:
class merge_sort(object):
def _merge(self, alist, p, q, r):
left = alist[p:q+1]
right = alist[q+1:r+1]
for i in range(p, r+1):
if len(left)>0 and len(right)>0:
if left[0]<=right[0]:
alist[i] = left.pop(0)
else:
alist[i] = right.pop(0)
elif len(right)==0:
alist[i] = left.pop(0)
elif len(left)==0:
alist[i] = right.pop(0) def _merge_sort(self, alist, p, r):
if p<r:
q = int((p+r)/2)
self._merge_sort(alist, p, q)
self._merge_sort(alist, q+1, r)
self._merge(alist, p, q, r) def __call__(self, sort_list):
self._merge_sort(sort_list, 0, len(sort_list)-1)
return sort_list
class heap_sort(object):
def _left(self, i):
return 2*i+1
def _right(self, i):
return 2*i+2
def _parent(self, i):
if i%2==1:
return int(i/2)
else:
return i/2-1 def _max_heapify(self, alist, i, heap_size=None):
length = len(alist) if heap_size is None:
heap_size = length l = self._left(i)
r = self._right(i) if lalist[i]:
largest = l
else:
largest = i
if ralist[largest]:
largest = r if largest!=i:
alist[i], alist[largest] = alist[largest], alist[i]
self._max_heapify(alist, largest, heap_size) def _build_max_heap(self, alist):
roop_end = int(len(alist)/2)
for i in range(0, roop_end)[::-1]:
self._max_heapify(alist, i) def __call__(self, sort_list):
self._build_max_heap(sort_list)
heap_size = len(sort_list)
for i in range(1, len(sort_list))[::-1]:
sort_list[0], sort_list[i] = sort_list[i], sort_list[0]
heap_size -= 1
self._max_heapify(sort_list, 0, heap_size) return sort_list
class quick_sort(object):
def _partition(self, alist, p, r):
i = p-1
x = alist[r]
for j in range(p, r):
if alist[j]<=x:
i += 1
alist[i], alist[j] = alist[j], alist[i]
alist[i+1], alist[r] = alist[r], alist[i+1]
return i+1 def _quicksort(self, alist, p, r):
if p<r:
q = self._partition(alist, p, r)
self._quicksort(alist, p, q-1)
self._quicksort(alist, q+1, r) def __call__(self, sort_list):
self._quicksort(sort_list, 0, len(sort_list)-1)
return sort_list
import sys
sys.setrecursionlimit(99999)
def _randomized_partition(self, alist, p, r):
i = random.randint(p, r)
alist[i], alist[r] = alist[r], alist[i]
return self._partition(alist, p, r)
完整的randomize_quick_sort的代码如下(这里我直接继承之前的quick_sort类):
import random
class randomized_quick_sort(quick_sort):
def _randomized_partition(self, alist, p, r):
i = random.randint(p, r)
alist[i], alist[r] = alist[r], alist[i]
return self._partition(alist, p, r) def _quicksort(self, alist, p, r):
if p<r:
q = self._randomized_partition(alist, p, r)
self._quicksort(alist, p, q-1)
self._quicksort(alist, q+1, r)
关于快速排序的讨论还没有结束。我们都知道,Python是一门很优雅的语言,而Python写出来的代码是相当简洁而可读性极强的。这里就介绍快排的另一种写法,只需要三行就能够搞定,但是又不失阅读性。(当然,要看懂是需要一定的Python基础的)代码如下:
def quick_sort_2(sort_list):
if len(sort_list)<=1:
return sort_list
return quick_sort_2([lt for lt in sort_list[1:] if lt<sort_list[0]]) + \
sort_list[0:1] + \
quick_sort_2([ge for ge in sort_list[1:] if ge>=sort_list[0]])
class counting_sort(object):
def _counting_sort(self, alist, k):
alist3 = [0 for i in range(k)]
alist2 = [0 for i in range(len(alist))]
for j in alist:
alist3[j] += 1
for i in range(1, k):
alist3[i] = alist3[i-1] + alist3[i]
for l in alist[::-1]:
alist2[alist3[l]-1] = l
alist3[l] -= 1
return alist2 def __call__(self, sort_list, k=None):
if k is None:
import heapq
k = heapq.nlargest(1, sort_list)[0] + 1
return self._counting_sort(sort_list, k)

def normal_find_same(alist):
length = len(alist)
for i in range(length):
for j in range(i+1, length):
if alist[i] == alist[j]:
return True
return False
这种方法的代价是非常大的(平均时间复杂度是O(n^2),当列表中没有重复元素的时候会达到最坏情况),由之前的经验,我们可以想到,利用内置sort方法极快的经验,我们可以这么做:首先将列表排序,然后遍历一遍,看是否有重复元素。包括完整的测试代码如下:
import time
import random def record_time(func, alist):
start = time.time()
func(alist)
end = time.time() return end - start def quick_find_same(alist):
alist.sort()
length = len(alist)
for i in range(length-1):
if alist[i] == alist[i+1]:
return True
return False if __name__ == "__main__":
methods = (normal_find_same, quick_find_same)
alist = range(5000)
random.shuffle(alist) for m in methods:
print 'The method %s spends %s' % (m.__name__, record_time(m, alist))
运行以后我的数据是,对于5000长度,没有重复元素的列表,普通方法需要花费大约1.205秒,而快速查找法花费只有0.003秒。这就是排序在实际应用中的一个例子。
文章来源:http://www.cnblogs.com/chineking/archive/2011/05/24/implement-sort-algorithm-with-python.html
用python实现各种排序算法的更多相关文章
- Python实现各种排序算法的代码示例总结
Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...
- Python实现常用排序算法
Python实现常用排序算法 冒泡排序 思路: 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完 ...
- python 的常见排序算法实现
python 的常见排序算法实现 参考以下链接:https://www.cnblogs.com/shiluoliming/p/6740585.html 算法(Algorithm)是指解题方案的准确而完 ...
- 用 python 实现各种排序算法(转)
常见几种排序的算法: 归并排序 归并排序也称合并排序,是分治法的典型应用.分治思想是将每个问题分解成个个小问题,将每个小问题解决,然后合并. 具体的归并排序就是,将一组无序数按n/2递归分解成只有一个 ...
- python基础===八大排序算法的 Python 实现
本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一 ...
- python实现简单排序算法
算法 递归两个特点: 调用自身 有穷调用 计算规模越来越小,直至最后结束 用装饰器修饰一个递归函数时会出现问题,这个问题产生的原因是递归的函数也不停的使用装饰器.解决方法是,只让装饰器调用一次即可,那 ...
- Python实现八大排序算法(转载)+ 桶排序(原创)
插入排序 核心思想 代码实现 希尔排序 核心思想 代码实现 冒泡排序 核心思想 代码实现 快速排序 核心思想 代码实现 直接选择排序 核心思想 代码实现 堆排序 核心思想 代码实现 归并排序 核心思想 ...
- python实现桶排序算法
桶排序算法也是一种可以以线性期望时间运行的算法,该算法的原理是将数组分到有限数量的桶里,每个桶再分别排序. 它的算法流程如下所示: 设置一个定量的数组当作空桶子. 寻访序列,并且把项目一个一个放到对应 ...
- python实现八大排序算法
插入排序 核心思想 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为 O(n^2).是稳定的排序方法.插入算法 ...
随机推荐
- windows phone, 应用最大内存
windows phone应用最大内存为150M,当app运行时所占内存超过150M时app会自动退出(VS debug时不容易捕捉到这个内存超出异常). [注]可通过配置增大最大内存
- redis 查询key数量
info查询所有库的key数量 dbsize查询当前库的key数量 keys * 查询当前库的所有key,数量少的时候可以用,当key很多的时候很慢,be careful!
- mongodb基础学习6-用户管理
下面来说一下用户管理,前面对mongodb进行操作都无需用户名密码进行登陆,可以设置用户进行数据库的访问 添加用户:三个参数:用户名,密码,是否只读 开启权限验证 进行验证 修改密码 删除用户 用户角 ...
- The 2018 Nobel prizesThe Nobel prize for economics is awarded for work on the climate and economic growth
The 2018 Nobel prizesThe Nobel prize for economics is awarded for work on the climate and economic g ...
- 在windows 2008 R2中SQl Server 2008中代理启动失败的一个原因总结
启动SQL代理的时候报错如下: 关调用实时(JIT)调试而不是此对话框的详细信息,请参见此消息的结尾. ************** 异常文本 **************System.NullRef ...
- Wilcoxon Signed Rank Test
1.Wilcoxon Signed Rank Test Wilcoxon有符号秩检验(也称为Wilcoxon有符号秩和检验)是一种非参数检验.当统计数据中使用“非参数”一词时,并不意味着您对总体一无所 ...
- MySQL8 重置改root密码及开放远程访问
1. 修改配置文件 先修改配置文件:vim /etc/my.conf 在 [mysqld] 下加上下面这行 skip-grant-tables 重启 mysql 服务: service mysqld ...
- MySQL+Navicat for MySQL安装
一.安装MySQL 1.下载MySQL http://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.10-winx64.zip 2.安装 2.1解压安装包 ...
- mysql 导出sql结果成csv文件
mysql -uroot -p -e "use database;sql语句:" > a.csv 举例: mysql -uroot -p -e "use main; ...
- goim源码分析与二次开发-comet分析一
因为要完成一个聊天的项目,所以借鉴了goim,第一篇分析打算半原版,先摘抄http://www.jianshu.com/p/8bd96a9a473d他的一些理解,写这些还是为了让自己更好的理解这个项目 ...