[Python]快速排序

最近摸了下Pyhton,发现真心好用。写下快排来练手。

import random
def partition(a,lo,hi):
	i = lo
	j = hi+1
	v = a[lo]
	while True:
		while a[i]<=v:
			i = i+1
			if i == hi:
				break
		j = j-1                 
		while a[j]>v:
			j = j-1
			if j == lo:
				break
		if i>=j:
			break
		a[i],a[j]=a[j],a[i]
	a[lo],a[j] = a[j],a[lo]
	return j	

def quicksort(a,lo,hi):
	if hi<=lo:
		return
	j = partition(a,lo,hi)
	quicksort(a,lo,j-1)
	quicksort(a,j+1,hi)

a = []
for i in range(1000000):
	a.append(random.uniform(1,100000000))
quicksort(a,0,len(a)-1)

写的时候很多小细节要注意,比如要注意切分中j的移动,任何一点对i和j不合适的改动都会导致错误。

100万的数据时间是3.44223299616秒排序完成。

对比下选择排序:1万的数据在6.5秒内排序完成。100万数据时间太长。

def selectionsort(a):
	for i in range(len(a)):
		for j in range(i,len(a)):
			if a[i]>a[j]:
				a[i],a[j]=a[j],a[i]

即使是简单的快速排序也有多种改进方法:

1)存在很多重复元素的时候可以采用3路排序的方法,提高速度;

2)对小数组排序,插入排序比快速排序更快,因为快速排序是递归的。

下面继续修改代码(加入小数组用插入排序):

import random
import time   
def partition(a,lo,hi):
<span style="white-space:pre">	</span>i = lo
<span style="white-space:pre">	</span>j = hi+1
<span style="white-space:pre">	</span>v = a[lo]
<span style="white-space:pre">	</span>while True:
<span style="white-space:pre">		</span>while a[i]<=v:
<span style="white-space:pre">		</span>i = i+1
<span style="white-space:pre">		</span>if i == hi:
<span style="white-space:pre">			</span>break
<span style="white-space:pre">			</span>j = j-1
<span style="white-space:pre">		</span>while a[j]>v:
<span style="white-space:pre">			</span>j = j-1
<span style="white-space:pre">			</span>if i>=j:
<span style="white-space:pre">				</span>break
<span style="white-space:pre">				</span>a[i],a[j]=a[j],a[i]
<span style="white-space:pre">		</span>a[lo],a[j] = a[j],a[lo]
<span style="white-space:pre">	</span>return j


def quicksort(a,lo,hi):
<span style="white-space:pre">	</span>f hi>=lo+15:
<span style="white-space:pre">		</span>j = partition(a,lo,hi)
<span style="white-space:pre">		</span>quicksort(a,lo,j-1)
<span style="white-space:pre">		</span>quicksort(a,j+1,hi)
<span style="white-space:pre">	</span>else:
<span style="white-space:pre">		</span>selectionsort(a,lo,hi)


def selectionsort(a,lo,hi):
<span style="white-space:pre">	</span>for i in range(lo,hi+1):
<span style="white-space:pre">		</span>for j in range(i,hi+1):
<span style="white-space:pre">			</span>if a[i]>a[j]:
<span style="white-space:pre">				</span>a[i],a[j]=a[j],a[i]


a = []

for i in range(1000000):
<span style="white-space:pre">	</span>a.append((int)(random.uniform(1,100000000)))
start = time.clock()  
quicksort(a,0,len(a)-1)
end = time.clock()  
print end-start 
print a[0:10]
100万数据3.56445105976s完成,并没有体现特别大的优势,算法书上说省15%左右的时间,还要仔细再研究下。

对多个重复的元素进行排序:

三相切分

import random
import time
def quick3sort(a,lo,hi):
	if hi<=lo:
		return
	lt = lo
	i = lo+1
	gt = hi
	v = a[lo]
	while i<=gt:
		if a[i]<v:
			a[i],a[lt] = a[lt],a[i]
			i = i+1
			lt = lt+1
		elif a[i]>v:
			a[i],a[gt] = a[gt],a[i]
			gt =gt-1
		else:
			i = i+1

	quick3sort(a,lo,lt-1)
	quick3sort(a,gt+1,hi)
a =[]
for i in range(1000000):
	a.append((int)(random.uniform(1,100)))
start = time.clock()
quick3sort(a,0,len(a)-1)
end = time.clock()
print end-start
print a[0:10]
100万数据,范围(1,100000000)。6.12628795802s完成。

三相切分基本思路是把数据分成小于v,等于v,大于v的三段。然后再对小于v和大于v的进行快速排序。

如果对相同元素多的数据比如(1:100)100万组数据只在1.45126854664内完成。

(1:10)的数据只在0.754866314071内完成。

而对原始的quicksort要用3.83970068155,和范围大的时间一样。


实际上如果已知到键的种类,桶排序是最快的,它只需要O(N)的算法复杂度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值