为了防止逆序列表导致性能大幅下降, quick_sort3()加入了随机因素,对比传统的快速排序quick_sort2(),排序性能比较稳定。
# -*- coding: UTF-8 -*-
#!/usr/bin/python
#python3.6
import sys
#import numpy as np
import random
import time
def quick_sort(data):
if len(data) >= 2:
#mid = data[len(data)//2]
mid=data[random.randrange(0, len(data))]
left, right = [], []
data.remove(mid)
for num in data:
if num >= mid:
right.append(num)
else:
left.append(num)
return quick_sort(left) + [mid] + quick_sort(right)
else:
return data
def quick_sort2(List, start, end):
if start < end:
i,j = start,end
#设置第一个值为基准数
base = List[i]
while i < j:
#如果列表后边的数,比基准数大或相等,则前移一位直到有比基准数小的数出现
while (i < j) and (List[j] >= base):
j = j - 1
#如找到,则把第j个元素赋值给第个元素i,此时表中i,j个元素相等
List[i] = List[j]
#同样的方式比较前半区
while (i < j) and (List[i] <= base):
i = i + 1
List[j] = List[i]
#做完第一轮比较之后,列表被分成了两个半区,并且i=j,需要将这个数设置回base
List[i] = base
#递归前后半区
quick_sort2(List, start, i - 1)
quick_sort2(List, j + 1, end)
return List
def quick_sort3(List, start, end):
if start < end:
i,j = start,end
#设置随机基准数
mid = random.randint(i, j)
base = List[mid]
List[mid] = List[i]
List[i] = base
while i < j:
#如果列表后边的数,比基准数大或相等,则前移一位直到有比基准数小的数出现
while (i < j) and (List[j] >= base):
j = j - 1
#如找到,则把第j个元素赋值给第个元素i,此时表中i,j个元素相等
List[i] = List[j]
#同样的方式比较前半区
while (i < j) and (List[i] <= base):
i = i + 1
List[j] = List[i]
#做完第一轮比较之后,列表被分成了两个半区,并且i=j,需要将这个数设置回base
List[i] = base
#递归前后半区
quick_sort3(List, start, i - 1)
quick_sort3(List, j + 1, end)
return List
def main():
#
# m=1000#10000000
# n=128#1000000
#ll=np.random.randint(10000000, size=1000000).tolist() #可能重复
# ll=[465, 973, 139, 605, 445, 560, 834, 896, 524, 606, 414, 197, 80, 804, 769, 749,
# 752, 359, 490, 451, 73, 386, 95, 514, 409, 725, 270, 714, 56, 631, 37, 391,
# 543, 435, 288, 490, 512, 937, 402, 301, 48, 376, 239, 229, 20, 365, 741, 263,
# 175, 87, 661, 614, 373, 927, 829, 347, 764, 271, 281, 302, 236, 860, 600, 565,
# 577, 629, 493, 389, 127, 359, 472, 45, 948, 968, 342, 745, 512, 365, 291, 88,
# 9, 365, 971, 431, 885, 808, 415, 858, 341, 34, 799, 614, 200, 937, 841, 104,
# 297, 178, 478, 913, 512, 713, 111, 977, 616, 455, 370, 791, 32, 758, 977, 499,
# 978, 56, 395, 97, 300, 285, 280, 163, 3, 598, 47, 164, 12, 630, 220, 744]
# ll=[495, 466, 989, 730, 428, 232, 856, 328, 24, 980, 727, 128, 920, 506, 639, 527, 176, 542, 868, 575, 212, 33, 370, 437, 349, 422, 271, 673, 100, 970, 15, 390, 757, 347, 855, 163, 507, 672, 969, 337, 496, 828, 729, 832, 904, 28, 671, 899, 817, 610, 42, 955, 830, 198, 565, 266, 13, 578, 190, 716, 108, 734, 579, 816, 643, 504, 889, 396, 376, 399, 178, 650, 374, 934, 746, 354, 160, 647, 813, 602, 117, 432, 417, 611, 302, 938, 627, 22, 572, 682, 897, 699, 314, 264, 407, 710, 58, 775, 674, 860, 762, 259, 932, 965, 307, 96, 255, 207, 557, 72, 256, 340, 958, 43, 667, 341, 92, 964, 304, 996, 430, 268, 105, 721, 219, 221, 247, 776]
# m=10000000
# n=2000000
# ll=random.sample([x for x in range(0, m)], n) #不重复
ll=[x for x in range(2000000, 1, -1)]
# sys.setrecursionlimit(1000000)
# print(ll)
# print("after quit_sort()")
# starttime = time.time()
# aa=quick_sort(ll)
# endtime = time.time()
# # print(aa)
# print("count=%d"%count)
# print((endtime - starttime))
print("after quit_sort3()")
starttime = time.time()
quick_sort3(ll, 0, len(ll)-1)
endtime = time.time()
print((endtime - starttime))
if __name__ == '__main__':
main()