几种常用排序算法的python实现
1:快速排序
思想:
任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
#*-* coding: utf-8 *-*
import random
# produce random numbers to be sorted
s = []
for i in range(0,100):
s.append(random.randint(1,100))
print(s[i]),
#
print("\nbegin")
def partition(inlist,start,end):
i = start
j = end
k = inlist[i]
while i<j:
while i<j and inlist[j]>=k:
j = j-1
inlist[i]=inlist[j]
while i<j and inlist[i]<=k:
i = i+1
inlist[j]=inlist[i]
inlist[i]=k
return i def quickSort(inlist,start,end):
if start>=end:
return
middle = partition(inlist,start,end)
quickSort(inlist,start,middle-1)
quickSort(inlist,middle+1,end) quickSort(s,0,len(s)-1)
for i in s:
print "%d " %i,
print("done")
2:直接插入排序
思想:
#*-* coding: utf-8 *-*
import random
# produce random numbers to be sorted
s = []
for i in range(0,100):
s.append(random.randint(1,100))
print(s[i]),
#
print("\nbegin") j=0
for i in range(1,len(s)):
if s[i]<s[i-1]:
temp = s[i]
j=i-1
while j>=0 and s[j]>temp:
s[j+1]=s[j]
s[j]=temp
j=j-1
for i in s:
print "%d " %i,
print("\ndone")
3:冒泡排序
思想:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
python 代码:
#*-* coding: utf-8 *-*
import random
# produce random numbers to be sorted
s = []
for i in range(0,100):
s.append(random.randint(1,100))
print(s[i]),
#
print("\nbegin") i = len(s)-1
while i>0:
j=0
for j in range(0,i):
if s[j+1]<s[j]:
temp = s[j]
s[j]=s[j+1]
s[j+1]=temp
j = j+1
i = i-1
for i in s:
print "%d " %i,
print("\ndone")
4:桶排序
思想:
假定:输入是由一个随机过程产生的[0, 1)区间上均匀分布的实数。将区间[0, 1)划分为n个大小相等的子区间(桶),每桶大小1/n:[0, 1/n), [1/n, 2/n), [2/n, 3/n),…,[k/n, (k+1)/n ),…将n个输入元素分配到这些桶中,对桶中元素进行排序,然后依次连接桶输入0 ≤A[1..n] <1辅助数组B[0..n-1]是一指针数组,指向桶(链表)。
太难懂了,举个简单的例子:
#*-* coding: utf-8 *-*
import random
# produce random numbers to be sorted
#10000 numbers,range in (0,100)
s = []
for i in range(0,10000):
s.append(random.randint(0,100))
#print(s[i]),
#
print("\nbegin")
r = {}
for i in range(0,101):
r[i]=[]
for i in s:
r[i].append(i)
f = file("r.txt","w")
for i in range(0,101):
for j in r[i]:
f.write(str(j)+',')
print("\ndone")
5:归并排序
思想:
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列。
python代码:
#*-* coding: utf-8 *-*
import random
# produce random numbers to be sorted
s = []
for i in range(0,100):
s.append(random.randint(1,100))
print(s[i]),print("\nbegin") def spli(inlist):
if len(inlist)<=1:
return inlist
num = len(inlist)/2
left = spli(inlist[0:num])
right = spli(inlist[num:])
return sor(left,right)
def sor(left,right):
#print(left)
#print(right)
l = 0
r = 0
result =[]
while l<len(left) and r <len(right):
if left[l]<right[r]:
result.append(left[l])
l =l+1
else:
result.append(right[r])
r = r+1
result = result+right[r:]
result = result+left[l:]
return result
s=spli(s)
for i in s:
print "%d " %i,
print("\ndone")
6:堆排序
思想:
1.什么是堆?
堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:
Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key>=key[2i+2]
即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。
堆分为大顶堆和小顶堆,满足Key[i]>=Key[2i+1]&&key>=key[2i+2]称为大顶堆,满足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]称为小顶堆。由上述性质可知大顶堆的堆顶的关键字肯定是所有关键字中最大的,小顶堆的堆顶的关键字是所有关键字中最小的。
2.堆排序的思想
利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。
其基本思想为(大顶堆):
1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;
2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];
3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
操作过程如下:
1)初始化堆:将R[1..n]构造为堆;
2)将当前无序区的堆顶元素R[1]同该区间的最后一个记录交换,然后将新的无序区调整为新的堆。
python 代码:
#*-* coding: utf-8 *-*
import random
# produce random numbers to be sorted
s = []
count=0
for i in range(0,100):
s.append(random.randint(1,100))
print(s[i]),
#
print("\nbegin")
def heap_sort(inlist):
for start in range((len(inlist)-2)/2,-1,-1):#1:初始化堆:从最底层开始建树,并且保证是堆
sift_down(inlist,start,len(inlist)-1)
for end in range(len(inlist)-1,0,-1):#2:将堆顶元素与最后一个元素交换,调整
inlist[0],inlist[end]=inlist[end],inlist[0]
sift_down(inlist,0,end-1)
return inlist def sift_down(inlist,start,end):
"""调整算法:从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换
(交换之后可能造成被交换的孩子节点不满足堆的性质,
因此每次交换之后要重新对被交换的孩子节点进行调整)"""
root = start
while True:
global count
count=count+1
child = 2*root +1#左节点
if child>end:
break
if child+1<=end and inlist[child]<inlist[child+1]:#左节点比右节点小
child = child+1#保证child对应的是左右节点中最大的
if inlist[root]<inlist[child]:#如果root不是最大,交换
inlist[root],inlist[child]=inlist[child],inlist[root]
root=child
else:
break
heap_sort(s)
for i in s:
print (i),
print("\ndone")
print(count)
6种算法比较次数的比较
随机生成10000的数据
| 快速排序 | 直接插入排序 | 冒泡排序 | 桶排序 | 归并排序 | 堆排序 | |
| 比较次数 | 512689 | 24795124 | 24934964 | 10000 | 120275 | 128265 |
| 效率 | NlogN | N*N | N*N | N | NlogN | NlogN |
很容易可以看出:
1:桶排序是最快的,但使用范围有限,排序的标准和数据的属性是一致的
2:快速排序、归并排序和堆排序都是NlogN的,但具体还是差别的,随机数据来看,比较次数:归并《堆《快速
有序序列的影响:
快速排序:有序》》》》(远大于)无序
直接插入:有序《无序
冒泡:有序《无序
桶排序:无差别
归并:有序《无序
堆排序:有序》无序
几种常用排序算法的python实现的更多相关文章
- 常用排序算法的python实现和性能分析
常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...
- 【Python】常用排序算法的python实现和性能分析
作者:waterxi 原文链接 背景 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试题整 ...
- 面试中常用排序算法的python实现和性能分析
这篇是关于排序的,把常见的排序算法和面试中经常提到的一些问题整理了一下.这里面大概有3个需要提到的问题: 虽然专业是数学,但是自己还是比较讨厌繁琐的公式,所以基本上文章所有的逻辑,我都尽可能的用大白话 ...
- 用 Java 实现的八种常用排序算法
八种排序算法可以按照如图分类 交换排序 所谓交换,就是序列中任意两个元素进行比较,根据比较结果来交换各自在序列中的位置,以此达到排序的目的. 1. 冒泡排序 冒泡排序是一种简单的交换排序算法,以升序排 ...
- 常用排序算法的Python实现
冒泡排序 算法思想: 对于一组需要排序的数据,对于相邻的两个数进行比较,使较大(或者较小)的数一直向后推,经过多层排序之后,使整个序列是有序的. 算法实现: def bubble_sort(L): l ...
- Java种八种常用排序算法
1 直接插入排序 经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中. 将第一个数和第二个数排序,然后构成一个有序序列 将第三个数插入进去,构成一个新的有序序列. 对第四个数.第五个数……直 ...
- 几种常用排序算法代码实现和基本优化(持续更新ing..)
插入排序(InsertSort): 插入排序的基本思想:元素逐个遍历,在每次遍历的循环中,都要跟之前的元素做比较并“交换”元素,直到放在“合适的位置上”. 插入排序的特点:时间复杂度是随着待排数组的有 ...
- 面试中常用排序算法实现(Java)
当我们进行数据处理的时候,往往需要对数据进行查找操作,一个有序的数据集往往能够在高效的查找算法下快速得到结果.所以排序的效率就会显的十分重要,本篇我们将着重的介绍几个常见的排序算法,涉及如下内容: 排 ...
- Python实现常用排序算法
Python实现常用排序算法 冒泡排序 思路: 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完 ...
随机推荐
- 在线算法&离线算法
[在线算法] 定义:指用户每输入一个查询便马上处理一个查询.该算法一般用较长的时间做预处理,待信息充足以后便可以用较少的时间回答每个查询. 常见在线算法:ST算法 [离线算法] 定义:
- winform timer时间间隔小于执行时间
如果SetTimer的时间间隔为t,其响应事件OnTimer代码执行一遍的时间为T,且T>t.这样,一次未执行完毕,下一次定时到,这时候程序会如何执行? 可能的情况:1.丢弃还未执行的代码,开始 ...
- 【iOS开发】多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用
http://blog.csdn.net/crycheng/article/details/21799611 本篇文章主要介绍下多线程下NSOperation.NSBlockOperation.NSI ...
- Linux建立FTP服务器
http://blog.chinaunix.net/uid-20541719-id-1931116.html http://www.cnblogs.com/hnrainll/archive/2011/ ...
- fetch_array()与fetch_assoc()的用法
fetch_array()与fetch_assoc()用起来没有什么大的差别,主要是怎么用?fetch_array()如果单独作为while的条件,则能够取出结果集中的所有结果.如果单独作用于结果集, ...
- 详细介绍弹性盒模型(display:flex)
弹性盒模型,即Flexbox,是css3中的新特性,其实弹性盒模型的原身是dispaly:box:这里,我们暂时不考虑旧的,我们只看新的. 为容器指定弹性盒子,只需在父元素(也就是容器)中设置:dis ...
- 【bzoj3940】[Usaco2015 Feb]Censoring AC自动机
题目描述 Farmer John has purchased a subscription to Good Hooveskeeping magazine for his cows, so they h ...
- 【bzoj3262】陌上花开 CDQ分治+树状数组
题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...
- $.ajax()方法参数总结
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址.type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和d ...
- NOIP临考经验【转】
NOIP临考经验 1.提前15分钟入场,此时静坐调整心态,适当的深呼吸 2.打开编辑器并调整为自己喜欢的界面 3.熟悉文件目录,写好准确无误的代码模板 4.压缩包或许还不能解压,但是文件名已经可以知道 ...