用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).是稳定的排序方法.插入算法 ...
随机推荐
- Struts2 利用AJAX 导出大数据设置遮罩层
Struts2 利用AJAX 导出大数据设置遮罩层 需求背景: 每次我们导出excel的时候 ,如果数据量很大,导出花费的时间会很长,页面却有没人任何反应,这个时候用户会认为系统有问题,要么关了页面, ...
- visibility和display
visibility: hidden----将元素隐藏,但是在网页中该占的位置还是占着.display: none----将元素的显示设为无,即在网页中不占任何的位置.
- 2018 Jar_Feb_Newwords
检测钩子程序 开发一个检测钩子程序的工具 - 豆丁网http://www.docin.com/p-1363993661.html pdf掺杂病毒的方法 Java的:xml文件中跳过的二进制数据在解析 ...
- 如何判断int类型相等
int a=10: int b=10: a==b 通过==判断两个int值是否相等. if(a==b){ 相等 }else{ 不相等 }
- Html解析类的新选择CsQuery
今天在做一个html解析的方法,以前用HtmlAgilityPack或Winista.HTMLParser. 现在发现了一个巨好用的项目叫CsQuery,这货据说不仅能解析html还能提取css. 选 ...
- Ansible Playbook Conditionals
通常,play的结果可能取决于变量的值,facts(有关远程系统的知识)或先前的任务结果. 在某些情况下,变量的值可能取决于其他变量. 此外,可以创建其他组,以根据主机是否与其他条件匹配来管理主机. ...
- HSTS详解
1. 缘起:启用HTTPS也不够安全 有不少网站只通过HTTPS对外提供服务,但用户在访问某个网站的时候,在浏览器里却往往直接输入网站域名(例如www.example.com),而不是输入完整的URL ...
- httpclient4例子
参考:http://hc.apache.org/httpclient-3.x/tutorial.html import org.apache.http.HttpEntity; import org.a ...
- 如何用INNO安装添加快捷启动方式到Win7的快速启动栏(超级任务栏)
问题:如何用INNO安装添加快捷启动方式到Win7的快速启动栏(超级任务栏) 在XP下,添加方式是直接把快捷方式复制到%appdata%\Microsoft\Internet Explorer\Qui ...
- JDK-8不是有效的Win32应用程序