用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).是稳定的排序方法.插入算法 ...
随机推荐
- Python之风湿理论值函数即变量
一,风湿历练:函数即变量,这样执行程序是不会报错的 def foo(): print ("from foo") bar() def bar(): print "form ...
- SRC是在本位置显示:source的缩写,源的意思 HREF是点击后连接的目标:HyperlinkReference,超链接引用
SRC是在本位置显示:source的缩写,源的意思HREF是点击后连接的目标:HyperlinkReference,超链接引用
- 软件工程导论复习 如何画系统流程图和数据流图 part1
一.数据流图与流程图的区别 数据流程图是以图形的方式表达在问题中信息的变换和传递过程.它把系统看成是由数据流联系的各种概念的组合,用分解及抽象手段来控制需求分析的复杂性,采用分层的数据流程图来表示一个 ...
- JSP复习(part 2 )
3.4.2 访问(获取)请求参数 1.方法 String 字符串变量 =request.getParameter("客户端提供参数的name属性名"): 2.传参数的三种形式 (1 ...
- Oracle VM VirtualBox做好虚拟硬盘后,如何进一步修改虚拟硬盘的大小
以管理员身份打开, 命令提示符窗口,然后利用命令cd进入Oracle VM VirtualBox安装目录,如下图: 我进入了Oracle VM VirtualBox安装目录:D:\Program Fi ...
- bedtools简介及应用
1)背景处理基因组数据中,比较基因组不同区域,例如寻找overlap等,是一种基本的且常见的问题.虽然UCSC 中‘Table Browser’或者Galaxy可以用来处理,但是当这些工具面对大的数据 ...
- 查看webdriver针对浏览器的一些函数
在用webdriver对浏览器进行操作时,很多操作并不是那么好找,后来在朋友的推荐下可以用下面的方法来寻找针对浏览器的一些操作,函数或属性等,这样方便我们可以查找一些方法去完成我们要的操作. 下面是查 ...
- ubuntu安装谷歌拼音输入法
在这篇教程中,我将告诉你如何在ubuntu系统上安装谷歌拼音输入法.谷歌拼音输入法有基于ibus框架的,也有基于fcitx框架的.我只演示fcitx框架下谷歌拼音输入法的安装,因为ibus框架的谷歌拼 ...
- 128. Longest Consecutive Sequence最长连续序列
[抄题]: Given an unsorted array of integers, find the length of the longest consecutive elements seque ...
- db2 批处理
db2在Windows下执行批处理,需要使用两个.bat文件 1)把以下命令保存为first_do.bat@echo off@@ECHO ------------------------------- ...