python快速排序

为了防止逆序列表导致性能大幅下降, 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()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值