#
!/usr/bin/python
#import asserts
# -*- coding: utf-8 -*-
from time import time
def _isort(a , p , q) :
for i in range(p , q) :
tmp = a[i]
j = i - 1
while j > - 1 and a[j] > tmp :
a[j + 1 ] = a[j]
j -= 1
a[j + 1 ] = tmp
def isort(a) :
''' sort list using insert-sort '''
_isort(a , 0 , len(a))
# print a
def __msort(a , p , q , t) :
''' sort [q,r) '''
max = 99999999
l = a[p : q]
l . append(max)
r = a[q : t]
r . append(max)
i = 0
j = 0
k = p
while k < t :
if (l[i] < r[j]) :
a[k] = l[i]
i += 1
else :
a[k] = r[j]
j += 1
k += 1
def _msort(a , p , q) :
''' sort the portion p,q '''
if p < q - 1 :
r = int ((p + q) / 2 )
_msort(a , p , r)
_msort(a , r , q)
__msort(a , p , r , q)
# else:
# _isort(a,p,q)
def msort(a) :
_msort(a , 0 , len(a))
# print a
def swap(a , i , j) :
tmp = a[i]
a[i] = a[j]
a[j] = tmp
def hsort(a) :
makeheap(a , len(a))
_hsort(a)
# print a
def _hsort(a) :
max = len(a)
while max > 1 :
swap(a , 0 , max - 1 )
max -= 1
__heapmax(a , 0 , max)
def makeheap(a , max) :
i = max / 2 - 1
while i > - 1 :
__heapmax(a , i , max)
i -= 1
# print a
def __heapmax(a , i , max) :
l = i * 2 + 1
r = i * 2 + 2
lagest = i
if l < max and a[l] > a[i] :
lagest = l
else :
lagest = i
if r < max and a[r] > a[lagest] :
lagest = r
if lagest != i :
swap(a , i , lagest)
__heapmax(a , lagest , max)
def qsort(a) :
_qsort(a , 0 , len(a))
# print a
def _qsort(a , p , q) :
if p < q - 10 :
i = _pation(a , p , q)
_qsort(a , p , i - 1 )
_qsort(a , i + 1 , q)
# else:
# _isort(a,p,q)
# _csort(a,p,q)
import random
def _pation(a , p , q) :
i = p - 1
j = p
span = False
tmp = a[random . randint(p , q - 1 )]
for j in range(p , q) :
if a[j] <= tmp :
i += 1
if span :
swap(a , i , j)
span = False
else :
span = True
return i
def csort(a) :
max = min = a[ 0 ]
for i in range( 1 , len(a)) :
if max < a[i] :
max = a[i]
if min > a[i] :
min = a[i]
b = []
for i in range(min , max + 1 ) :
b . append( 0 )
for i in range( 0 , len(a)) :
b[a[i] - min] += 1
index = 0
for i in range(min , max + 1 ) :
while b[i - min] > 0 :
a[ index ] = i
b[i - min] -= 1
index += 1
def csort2(a) :
a = _csort(a , 0 , len(a))
def equ(i) :
return i
def _csort(src , p , q , op = equ) :
if p > q - 1 :
return
a = []
for i in range(p , q) :
a . append(op(src[i]))
max = min = a[p]
c = []
for i in range(p , q) :
if max < a[i] :
max = a[i]
if min > a[i] :
min = a[i]
c . append( 0 )
b = []
for i in range(min , max + 1 ) :
b . append( 0 )
for i in range(p , q) :
b[a[i] - min] += 1
for i in range( 1 , len(b)) :
b[i] += b[i - 1 ]
k = q - 1
while k > p - 1 :
c[b[a[k] - min] - 1 ] = src[k]
b[a[k] - min] -= 1
k -= 1
return c
def rsort(a) :
''' radix sort '''
max = a[ 0 ]
for i in range( 0 , len(a)) :
if max < a[i] :
max = a[i]
# calcu dig nums
dig = 0
while max > 0 :
dig += 1
max /= 10
for i in range( 0 , dig) :
d = digcompare(i)
a = _csort(a , 0 , len(a) , d . compare)
class digcompare :
def __init__(self , len) :
self . len = len
def compare(self , i) :
tmp = self . len
while tmp > 0 :
i = i / 10
tmp -= 1
return i % 10
import unittest
import random
class Sortor(unittest . TestCase) :
impl = [ ' qsort ' , ' msort ' , ' hsort ' , ' csort ' , ' csort2 ' , ' rsort ' ]
items = range( 1 , 2000 )
random . shuffle(items)
times = 100
# once only
def testSort(self) :
for item in self . impl :
try :
sort = globals()[item]
except KeyError :
print ' %s is undef ' %item
continue
if sort != None :
b = time ()
for i in range( 0 , self . times ) :
sort (self . items)
random . shuffle(self . items)
e = time ()
print ' %10s sort time %f ' % (item , (e - b) / self . times )
if __name__ == ' __main__ ' :
unittest . main()
#import asserts
# -*- coding: utf-8 -*-
from time import time
def _isort(a , p , q) :
for i in range(p , q) :
tmp = a[i]
j = i - 1
while j > - 1 and a[j] > tmp :
a[j + 1 ] = a[j]
j -= 1
a[j + 1 ] = tmp
def isort(a) :
''' sort list using insert-sort '''
_isort(a , 0 , len(a))
# print a
def __msort(a , p , q , t) :
''' sort [q,r) '''
max = 99999999
l = a[p : q]
l . append(max)
r = a[q : t]
r . append(max)
i = 0
j = 0
k = p
while k < t :
if (l[i] < r[j]) :
a[k] = l[i]
i += 1
else :
a[k] = r[j]
j += 1
k += 1
def _msort(a , p , q) :
''' sort the portion p,q '''
if p < q - 1 :
r = int ((p + q) / 2 )
_msort(a , p , r)
_msort(a , r , q)
__msort(a , p , r , q)
# else:
# _isort(a,p,q)
def msort(a) :
_msort(a , 0 , len(a))
# print a
def swap(a , i , j) :
tmp = a[i]
a[i] = a[j]
a[j] = tmp
def hsort(a) :
makeheap(a , len(a))
_hsort(a)
# print a
def _hsort(a) :
max = len(a)
while max > 1 :
swap(a , 0 , max - 1 )
max -= 1
__heapmax(a , 0 , max)
def makeheap(a , max) :
i = max / 2 - 1
while i > - 1 :
__heapmax(a , i , max)
i -= 1
# print a
def __heapmax(a , i , max) :
l = i * 2 + 1
r = i * 2 + 2
lagest = i
if l < max and a[l] > a[i] :
lagest = l
else :
lagest = i
if r < max and a[r] > a[lagest] :
lagest = r
if lagest != i :
swap(a , i , lagest)
__heapmax(a , lagest , max)
def qsort(a) :
_qsort(a , 0 , len(a))
# print a
def _qsort(a , p , q) :
if p < q - 10 :
i = _pation(a , p , q)
_qsort(a , p , i - 1 )
_qsort(a , i + 1 , q)
# else:
# _isort(a,p,q)
# _csort(a,p,q)
import random
def _pation(a , p , q) :
i = p - 1
j = p
span = False
tmp = a[random . randint(p , q - 1 )]
for j in range(p , q) :
if a[j] <= tmp :
i += 1
if span :
swap(a , i , j)
span = False
else :
span = True
return i
def csort(a) :
max = min = a[ 0 ]
for i in range( 1 , len(a)) :
if max < a[i] :
max = a[i]
if min > a[i] :
min = a[i]
b = []
for i in range(min , max + 1 ) :
b . append( 0 )
for i in range( 0 , len(a)) :
b[a[i] - min] += 1
index = 0
for i in range(min , max + 1 ) :
while b[i - min] > 0 :
a[ index ] = i
b[i - min] -= 1
index += 1
def csort2(a) :
a = _csort(a , 0 , len(a))
def equ(i) :
return i
def _csort(src , p , q , op = equ) :
if p > q - 1 :
return
a = []
for i in range(p , q) :
a . append(op(src[i]))
max = min = a[p]
c = []
for i in range(p , q) :
if max < a[i] :
max = a[i]
if min > a[i] :
min = a[i]
c . append( 0 )
b = []
for i in range(min , max + 1 ) :
b . append( 0 )
for i in range(p , q) :
b[a[i] - min] += 1
for i in range( 1 , len(b)) :
b[i] += b[i - 1 ]
k = q - 1
while k > p - 1 :
c[b[a[k] - min] - 1 ] = src[k]
b[a[k] - min] -= 1
k -= 1
return c
def rsort(a) :
''' radix sort '''
max = a[ 0 ]
for i in range( 0 , len(a)) :
if max < a[i] :
max = a[i]
# calcu dig nums
dig = 0
while max > 0 :
dig += 1
max /= 10
for i in range( 0 , dig) :
d = digcompare(i)
a = _csort(a , 0 , len(a) , d . compare)
class digcompare :
def __init__(self , len) :
self . len = len
def compare(self , i) :
tmp = self . len
while tmp > 0 :
i = i / 10
tmp -= 1
return i % 10
import unittest
import random
class Sortor(unittest . TestCase) :
impl = [ ' qsort ' , ' msort ' , ' hsort ' , ' csort ' , ' csort2 ' , ' rsort ' ]
items = range( 1 , 2000 )
random . shuffle(items)
times = 100
# once only
def testSort(self) :
for item in self . impl :
try :
sort = globals()[item]
except KeyError :
print ' %s is undef ' %item
continue
if sort != None :
b = time ()
for i in range( 0 , self . times ) :
sort (self . items)
random . shuffle(self . items)
e = time ()
print ' %10s sort time %f ' % (item , (e - b) / self . times )
if __name__ == ' __main__ ' :
unittest . main()
1. 插入排序 类似于冒泡排序,每一项都要与其他项比较,算法复杂度O(n^2),但是处理小序列的时候往往有出人意料的惊喜。
2, 归并排序 一个大的序列可以由两个有序的序列排成,通过这种思想将一个问题进行分解,从而排序,算法复杂度O(nlogn)(log底数为2,以下皆是)
3. heap排序,通过数组形成的heap排序,建立堆容易,但是排序后建好的堆就消失了,算法复杂度O(nlogn).
4 快速排序 这个没什么好说的,基本上是属于经典的不用额外划分空间的排序方法,而且,通过随即取值,它的复杂度也是O(nlogn)
以上都是比较排序,如果算是非比较排序,我们有:
5 counting sort,用于整数排序,通过一个段的数组记录数的使用情况,然后进行排序,算法复杂度O(n)
6 radix sort,(counting sort的发展),对于多位整数,通过对每一位进行一次counting sort来排序。
最后的结果如下:
isort sort time 0.512181 (插入排序)
qsort sort time 0.014857 (快速排序)
msort sort time 0.023441 (归并排序)
hsort sort time 0.042476 (heap排序)
csort sort time 0.005777 (counting sort)
csort2 sort time 0.007931 (通过函数确定比较值大小的counting sort)
rsort sort time 0.030162 (radix sort)
看来快速排序果然是很不错的好东西阿,跟O(n)复杂度的算法也差不到哪里去,难怪gcc也用它做为sort算法的主体。
当然,我的时间测试估计不是特别符合测试标准,不过至少能体现哪个算法相对较好吧,hoho。