Python 优化合并排序

Python 优化合并排序,python,sorting,Python,Sorting,我需要优化我的排序(合并排序),这样对于大小为10^6的列表,将在不到100秒内进行排序。目前我最好的时间是105秒,我想不出一种方法来让这段代码更优化 def my_sort(lst): if len(lst) > 1: puolivali = len(lst) // 2 vas = lst[:puolivali] oik = lst[puolivali:] vas = my_sort(vas) oik = my_sort(oik) lst

我需要优化我的排序(合并排序),这样对于大小为10^6的列表,将在不到100秒内进行排序。目前我最好的时间是105秒,我想不出一种方法来让这段代码更优化

def my_sort(lst):
if len(lst) > 1:
    puolivali = len(lst) // 2
    vas = lst[:puolivali]
    oik = lst[puolivali:]
    vas = my_sort(vas)
    oik = my_sort(oik)
    lst = []
    while len(vas) > 0 and len(oik) > 0:
        if vas[0] < oik[0]:
            lst.append(vas[0])
            vas.pop(0)
        else:
            lst.append(oik[0])
            oik.pop(0)

    for i in vas:
        lst.append(i)
    for i in oik:
        lst.append(i)

return lst
def my_sort(lst):
如果len(lst)>1:
puolivali=len(lst)//2
vas=lst[:puolivali]
oik=lst[puolivali:]
vas=我的分类(vas)
oik=我的分类(oik)
lst=[]
而len(vas)>0和len(oik)>0:
如果vas[0]
.pop(0)
是主要的性能杀手,因为它转移了所有后续元素。请改用移动索引:

    # ...
    vas_i = oik_i = 0
    lst = []
    while vas_i < len(vas) and oik_i < len(oik):
        if vas[vas_i] < oik[oik_i]:
            lst.append(vas[vas_i])
            vas_i += 1
        else:
            lst.append(oik[oik_i])
            oik_i += 1

    lst.extend(vas[vas_i:])
    lst.extend(oik[oik_i:])
#。。。
vas_i=oik_i=0
lst=[]
而vas_i
或作为一个完整的功能:

def my_sort(lst):
    mid = len(lst) // 2
    if mid:
        lo, hi = my_sort(lst[:mid]), my_sort(lst[mid:])
        lo_i = hi_i = 0
        lst = []
        while lo_i < len(lo) and hi_i < len(hi):
            if lo[lo_i] > hi[hi_i]:
                lo, lo_i, hi, hi_i = hi, hi_i, lo, lo_i
            lst.append(lo[lo_i])
            lo_i += 1
        lst.extend(lo[lo_i:])
        lst.extend(hi[hi_i:])
    return lst
def my_sort(lst):
mid=len(lst)//2
如果是中期:
lo,hi=my_sort(lst[:mid]),my_sort(lst[mid:])
lo_i=hi_i=0
lst=[]
而lo_ihi[hi_i]:
lo,lo_i,hi,hi_i=嗨,hi_i,lo,lo_i
lst.append(lo[lo_i])
lo_i+=1
一级延伸(lo[lo_i:])
一级扩展(hi[hi_i:])
返回lst

@Toppe——这个是O(N),很贵。其他合并排序算法,不涉及pop(0)。
vas.pop(0)
oik.pop(0)
在每次传递时都会移动所有剩余的元素,这使得遍历它们的次数总计
O(n**2)
,排序的复杂性
O(n**2 log n)
而不是预期的
O(n log n)
。您可以尝试反转子列表并从末尾弹出,即O(1),@DarrylG-Ugh,那里的第二个Python解决方案也是
pop(0)
。Geeksforgeks确实是有史以来最糟糕的网站。也许OP真的从那里得到了它,除了重命名的变量之外,它似乎是完全相同的代码。@user4815162342它们的排序复杂性是O(n**2)。@superbrain--谢谢,我只看到了第一个解决方案,乍一看似乎还可以。同意除学习体验外,第二种解决方案不是一种合理的选择。您可以通过
lo[lo_i:]或hi[hi_i::
进行扩展,以保存另一行。