排序是算法学习中最基本的问题。

1.平均时间复杂度均为O(N2)的排序

1.1 插入排序

插入排序对少量元素的排序非常有效。工作机制就像打牌一样,为了将牌插入到已排好序的牌中,需要将牌与手中的牌从右向左进行比较。

def insertionSort(alist):
n=len(alist)
for i in xrange(1,n):
key=alist[i]
j=i-1
while j>=0 and alist[j]>=key:
alist[j+1]=alist[j]
j-=1
alist[j+1]=key
return alist

1.2 冒泡排序

冒泡排序通过重复的交换相邻的两个反序元素来将最大元素置于数组末尾。

def bubbleSort(alist):
n=len(alist)
for i in xrange(n-2,0,-1):
for j in xrange(i+1):
if alist[j]>alist[j+1]:
alist[j],alist[j+1]=alist[j+1],alist[j]
return alist

1.3 选择排序

首先找出序列中的最大元素,与最后一个元素交换位置,然后找出次大元素,与倒数第二个元素交换位置,以此类推。

def selectionSort(alist):
n=len(alist)
for i in xrange(n-1,0,-1):
posofMax=0
for j in xrange(1,i+1):
if alist[j]>=alist[posofMax]:
posofMax=j
a[posofMax],a[i]=a[i],a[posofMax]
return alist

1.4 希尔排序

SHELL排序通过比较相距一定间隔的元素来工作。各趟排序随着算法的进行而减小,直到只比较相邻元素的最后一趟为止。

使用希尔增量(ht=N/2,hk=hk+1/2)时希尔排序的最坏运行时间为Θ(N2),使用Hibbard增量(1,3,7,...,2k-1)的希尔排序的最坏运行时间为Θ(N3/2)。

def shellSort(alist):
n=len(alist)/2
while n>0:
gapinsertionSort(alist,n)
n=n/2
return alist
def gapinsertionSort(alist,gap):
n=len(alist)
for i in xrange(gap):
for j in xrange(i+gap,n,gap):
key=alist[j]
x=j-gap
while x>=0 and a[x]>=key:
a[x+gap]=a[x]
x-=gap
a[x+gap]=key

2.平均时间复杂度均为O(NlogN)的排序

2.1 合并排序

合并排序基本的操作是合并两个已排序的表。它是递归算法的一个很好的实例。合并排序需要花费将数据拷贝到临时数组再拷贝回来这样一些附加的工作。

def mergeSort(alist):
if len(alist)>1:
q=len(alist)/2
left=alist[:q]
right=alist[q:]
mergeSort(left)
mergeSort(right)
i=0
j=0
k=0
while i<len(left) and j<len(right):
if left[i]<right[j]:
alist[k]=left[i]
i+=1
else:
alist[k]=right[j]
j+=1
k+=1
while i<len(left):
alist[k]=left[i]
i+=1
k+=1
while j<len(right):
alist[k]=right[j]
j+=1
k+=1
return alist

  合并排序的另一种非递归实现

def mergeSort(alist):
n=len(alist)
i=1
while i<n:
start=0
t=start+i-1
end=start+2*i-1
while end<n:
merge(alist,start,t,end)
start=end+1
t=start+i-1
end=start+2*i-1
if t<n-1:
merge(alist,start,t,n-1)
i=i*2
return alist def merge(alist,start,t,end):
left=alist[start:t+1]
right=alist[t+1:end+1]
i=0
j=0
k=start
while i<len(left) and j<len(right):
if left[i]<right[j]:
alist[k]=left[i]
i+=1
else:
alist[k]=right[j]
j+=1
k+=1
while i<len(left):
alist[k]=left[i]
i+=1
k+=1
while j<len(right):
alist[k]=right[j]
j+=1
k+=1

 2.2 堆排序

建立最大堆后将最大元素与堆最后的单元互换,堆大小缩小一,然后执行根的下滤操作找出第二大的元素。

def heapSort(alist):
n=len(alist)
buildMaxHeap(alist)
for i in xrange(n-1,0,-1):
alist[i],alist[0]=alist[0],alist[i]
perDown(alist,0,i-1)
return alist
def buildMaxHeap(alist):
n=len(alist)
for i in xrange(n/2-1,-1,-1):
perDown(alist,i,n-1)
def perDown(alist,start,end):
left=start*2+1
right=left+1
large=start
if left<=end and alist[left]>alist[start]:
large=left
if right<=end and alist[right]>alist[large]:
large=right
if large!=start:
alist[large],alist[start]=alist[start],alist[large]
perDown(alist,large,end)

2.3 快速排序

快速排序是在实践中最快的已知排序算法,像合并排序一样也是一种分治的递归算法。

1.如果元素个数为0或1,则返回。

2.取数组中任一元素v,称之为枢纽元。

3.将数组分为2个不相交的部分,一部分元素小于v,另一部分大于v。

4.对两部分分别递归的使用快速排序。

下图取第一个元素为枢纽元v,leftmark从第二个元素开始,rightmark从倒数第一个元素开始。

当leftmark在rightmark左边时,将leftmark右移,移过小于v的元素,将rightmark左移,移过大于v的元素,当leftmark,rightmark停止时,

将leftmark和rightmark元素互换,直到leftmark到rightmark右边为止。

def quickSort(alist):
n=len(alist)
_quickSort(alist,0,n-1)
return alist
def _quickSort(alist,s,e):
if s<e:
v=alist[s]
i=s+1
j=e
while True:
while i<=j and alist[i]<v: #如果i和j遇到等于枢纽元的关键字,都停止
i+=1
while j>=i and alist[j]>v:
j-=1
if i<j:
alist[i],alist[j]=alist[j],alist[i]
i+=1
j-=1
else:
break
alist[s],alist[j]=alist[j],alist[s]
_quickSort(alist,s,j-1)
_quickSort(alist,i,e)

另一种写法

def quickSort(alist):
n=len(alist)
_quickSort(alist,0,n-1)
return alist
def _quickSort(alist,s,e):
if s<e:
v=alist[e]
i=s #用i将数组分为两部分
for j in xrange(s,e):
if alist[j]<=v:
alist[j],alist[i]=alist[i],alist[j]
i+=1
alist[e],alist[i]=alist[i],alist[e]
_quickSort(alist,s,i-1)
_quickSort(alist,i+1,e)

  

Python基于比较的排序的更多相关文章

  1. 漫谈python中的搜索/排序

    在数据结构那一块,搜索有顺序查找/二分查找/hash查找,而排序有冒泡排序/选择排序/插入排序/归并排序/快速排序.如果遇到数据量和数组排列方式不同,基于时间复杂度的考虑,可能需要用到混合算法.如果用 ...

  2. [python学习] 语言基础—排序函数(sort()、sorted()、argsort()函数)

    python的内建排序函数有 sort.sorted两个. 1.基础的序列升序排序直接调用sorted()方法即可 ls = list([5, 2, 3, 1, 4]) new_ls = sorted ...

  3. Python list列表的排序

    当我们从数据库中获取一写数据后,一般对于列表的排序是经常会遇到的问题,今天总结一下python对于列表list排序的常用方法: 第一种:内建函数sort() 这个应该是我们使用最多的也是最简单的排序函 ...

  4. python基于LeanCloud的短信验证

    python基于LeanCloud的短信验证 1. 获取LeanCloud的Id.Key 2. 安装Flask框架和Requests库 pip install flask pip install re ...

  5. Python基于共现提取《釜山行》人物关系

    Python基于共现提取<釜山行>人物关系 一.课程介绍 1. 内容简介 <釜山行>是一部丧尸灾难片,其人物少.关系简单,非常适合我们学习文本处理.这个项目将介绍共现在关系中的 ...

  6. Python 基于Python实现的ssh兼sftp客户端(上)

    基于Python实现的ssh兼sftp客户端   by:授客 QQ:1033553122 实现功能 实现ssh客户端兼ftp客户端:实现远程连接,执行linux命令,上传下载文件 测试环境 Win7 ...

  7. 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序

    题目: 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序 public static int maxGap(int nums[]) { if ( ...

  8. Python字典按值排序的方法

    Python字典按值排序的方法: 法1: (默认升序排序,加  reverse = True 指定为降序排序) # sorted的结果是一个list dic1SortList = sorted( di ...

  9. solr特点三: 基于Solr实现排序定制化参考

    排序实现有N种形式,最低成本.最快响应时间是目标 一份索引,支持N种排序策略并且在线互不干扰是要考虑的每一种实现,处理的场景是不同的,不要千篇一律 020排序,从索引到效果,有不少坑,这篇文章没有细说 ...

随机推荐

  1. js源码保护

    js的不可读化处理分为三个方面:压缩(compression).混淆(obfuscation) 和加密(encryption). (不可读化处理,这是我自己发明的术语,一切会增加代码不可读性的代码转换 ...

  2. svn常用操作命令(不断更新中......)

      1.svn info显示本地或远程条目的信息.打印你的工作拷贝和URL的信息包括:路径.名称.URL.版本库的根.版本库的UUID.Revision.节点类型.最后修改作者.最后修改版本最后修改日 ...

  3. Windows7中Emacs 24 shell使用Gitbash

    今天发现可以在shell中直接打开Gitbash,Gitbash提供了一些有用的Linux风格命令,最关键是我用emacs的时候不用再打开一个Gitbash终端操纵Git了. 在~/.emacs.d/ ...

  4. Top 10 Algorithms for Coding Interview--reference

    By X Wang Update History:Web Version latest update: 4/6/2014PDF Version latest update: 1/16/2014 The ...

  5. python生成简单的验证码

    #coding=utf-8 from PIL import Image, ImageDraw, ImageFont, ImageFilter import random # 随机字母: def rnd ...

  6. android.os.NetworkOnMainThreadException 异常处理

    当我试图在UI线程(MainActivity)连接网络的时候,运行时抛出异常droid.os.NetworkOnMainThreadException 安卓的官方文档说 The exception t ...

  7. ES 中的那些坑

    数组 1. 数组中的 full-text 字段将被 [analyzed] 2. 数组中[所有元素]的数据类型必须一致 3. 数组的数据类型,以其 [第一个元素]为准 映射 1. 数据类型会自动进行转化 ...

  8. posix thread互斥量

    互斥量 互斥量(Mutex)是“mutual exclusion”的缩写.互斥量是实现线程同步,和保护同时写共享数据的主要方法.使用互斥量的典型顺序如下:1. 创建和初始一个互斥量 2. 多个线程尝试 ...

  9. nodejs 微信中使用file组件上传图片在某些机型上点击无反应

    看下下面的代码: <form action="/" class="file_upload" method="post" enctype ...

  10. IP地址,子网掩码划分(转)

    IP地址划分教程 IP和子网掩码我们都知道,IP是由四段数字组成,在此,我们先来了解一下3类常用的IP A类IP段 0.0.0.0 到127.255.255.255 B类IP段 128.0.0.0 到 ...