quick sortの簡略化の実現
15015 ワード
Pivotランダム選択はあまり意味がありません
第1の方法はランダムpivotを用いて、可能な限り二分配列を平均するが、実際には一般的に並べ替えが必要な集合は往々にして乱順であり、ランダム数をpivotとして再生成する必要がなく、固定位置の数をpivotとして大きく使用することができ、このようにほとんどの状況に適応することができ、論理を簡略化することができ、第2のsimple quick Sortがある.
演算結果からランダムpivotを用いても用いなくても性能はほぼ同じである.
大量の繰返し元素が存在する場合,時間的複雑度はO(n 2)に劣化する
多くの教材では,入力が秩序化されているなどの特定の場合,クイックソート(quicksort)の時間的複雑さはO(n 2)に劣化すると述べている.実際には,並べ替え対象の集合に同じ要素が多く含まれる限り,ほとんどの教材での実装はO(n 2)に劣化する.多くの実装のpartition実装方法はpivotに等しい要素をpivotの同一辺に分けることが問題である.
第3の実装quick_sort_quickはこの問題を解決するためである(大量の重複要素が存在する場合、n*10倍の性能向上がある).
第1の方法はランダムpivotを用いて、可能な限り二分配列を平均するが、実際には一般的に並べ替えが必要な集合は往々にして乱順であり、ランダム数をpivotとして再生成する必要がなく、固定位置の数をpivotとして大きく使用することができ、このようにほとんどの状況に適応することができ、論理を簡略化することができ、第2のsimple quick Sortがある.
演算結果からランダムpivotを用いても用いなくても性能はほぼ同じである.
大量の繰返し元素が存在する場合,時間的複雑度はO(n 2)に劣化する
多くの教材では,入力が秩序化されているなどの特定の場合,クイックソート(quicksort)の時間的複雑さはO(n 2)に劣化すると述べている.実際には,並べ替え対象の集合に同じ要素が多く含まれる限り,ほとんどの教材での実装はO(n 2)に劣化する.多くの実装のpartition実装方法はpivotに等しい要素をpivotの同一辺に分けることが問題である.
第3の実装quick_sort_quickはこの問題を解決するためである(大量の重複要素が存在する場合、n*10倍の性能向上がある).
====== sort 80*500 numbers ======
quick QS: 2014-11-18 10:08:34.281000
my_quick_sort: 2014-11-18 10:08:35.425000
default sort: 2014-11-18 10:08:36.576000
after sort: 2014-11-18 10:08:36.579000
====== sort 21*300 numbers with many duplicated ======
quick QS: 2014-11-18 10:08:36.579000 37ms # ,
my_quick_sort: 2014-11-18 10:08:36.616000 994ms
default sort: 2014-11-18 10:08:37.610000 1ms
after sort: 2014-11-18 10:08:37.611000
====== compare with random or without random ======
simple QS: 2014-11-18 10:08:37.611000
my_quick_sort: 2014-11-18 10:08:38.758000
default sort: 2014-11-18 10:08:39.908000
after sort: 2014-11-18 10:08:39.909000
====== sort 90000 numbers without duplicated ======
qucik QS: 2014-11-18 10:08:39.916000
simple QS: 2014-11-18 10:08:40.285000
my_quick_sort: 2014-11-18 10:08:40.661000
default sort: 2014-11-18 10:08:41.016000
after sort: 2014-11-18 10:08:41.018000
# 1 :
simple QS: 2014-11-17 16:53:03.450000 38ms
my_quick_sort: 2014-11-17 16:53:03.488000 35ms
default sort: 2014-11-17 16:53:03.523000
after sort: 2014-11-17 16:53:03.524000
2014-11-17 16:53:03.524000
# 1 :
simple QS: 2014-11-17 16:53:03.524000 35ms
my_quick_sort: 2014-11-17 16:53:03.559000 35ms
default sort: 2014-11-17 16:53:03.594000
after sort: 2014-11-17 16:53:03.594000
#9 :
simple QS: 2014-11-17 16:57:12.885000 367ms
my_quick_sort: 2014-11-17 16:57:13.252000 352ms
default sort: 2014-11-17 16:57:13.604000 1ms
after sort: 2014-11-17 16:57:13.605000
#-------------------------------------------------------------------------------
# Name: quick sort
# Purpose:
#
# Author: ScottGu<[email protected], [email protected]>
#
# Created: 04/09/2013
# Copyright: (c) ScottGu<[email protected], [email protected]> 2013
# Licence: <your licence>
#-------------------------------------------------------------------------------
from datetime import datetime
from random import randint
import sys
sys.setrecursionlimit(10000)
def quick_sort(lst):
if len(lst)==0:
return lst
else:
pivot_idx = randint(0, len(lst) - 1)
pivot = lst[pivot_idx]
lesser=quick_sort([val for idx, val in enumerate(lst)
if val <= pivot and idx!=pivot_idx])
greater=quick_sort([x for x in lst if x > pivot])
return lesser+[pivot]+greater
def quick_sort_simple(lst):
if len(lst)==0:
return lst
else:
pivot = lst[0]
lesser=quick_sort([x for x in lst[1:] if x <= pivot])
greater=quick_sort([x for x in lst[1:] if x > pivot])
return lesser+[pivot]+greater
def quick_sort_quick(lst):
if len(lst)==0:
return lst
else:
pivot = lst[0]
lesser=quick_sort([x for x in lst[1:] if x < pivot])
greater=quick_sort([x for x in lst[1:] if x > pivot])
return lesser+[pivot]+[x for x in lst[1:] if x == pivot]+greater
def main():
lst=[20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
lst=lst*500
ls2=[1,2,1,1,1,3,4,7,9,11,12,1,1,1,1,1,1,1,1,1,1]
ls2=ls2*300
print '====== sort 80*500 numbers ====== '
print 'quick QS: '+str(datetime.now())
quick_sort_quick(lst)
print 'my_quick_sort: '+str(datetime.now())
quick_sort_simple(lst)
print 'default sort: '+str(datetime.now())
lst.sort()
print 'after sort: '+str(datetime.now())
print '====== sort 21*300 numbers with many duplicated ====== '
print 'quick QS: '+str(datetime.now())
quick_sort_quick(ls2)
print 'my_quick_sort: '+str(datetime.now())
quick_sort_simple(ls2)
print 'default sort: '+str(datetime.now())
ls2.sort()
print 'after sort: '+str(datetime.now())
print '====== compare with random or without random ====== '
print 'simple QS: '+str(datetime.now())
quick_sort_simple(lst)
print 'my_quick_sort: '+str(datetime.now())
quick_sort(lst)
print 'default sort: '+str(datetime.now())
lst.sort()
print 'after sort: '+str(datetime.now())
print '====== sort 90000 numbers without duplicated ====== '
lst=[]
for x in range(90000):
lst.append(x)
print 'qucik QS: '+str(datetime.now())
quick_sort_quick(lst)
print 'simple QS: '+str(datetime.now())
quick_sort_simple(lst)
print 'my_quick_sort: '+str(datetime.now())
quick_sort(lst)
print 'default sort: '+str(datetime.now())
lst.sort()
print 'after sort: '+str(datetime.now())
if __name__ == '__main__':
main()