为什么结合使用插入排序和快速排序会得到较差的结果?

时间:2019-05-19 12:51:09

标签: python quicksort

我试图设置一个合并快速排序和插入排序的临界值,当n(要排序的数据数)小于临界值时,使用插入排序。但是,我发现该方法无效,甚至比以前更糟。为什么以及如何改善呢?

要对10e4随机整数进行排序,使用cutoff(50)进行快速排序需要0.6s,而没有cutoff的方法只需0.02s。

具有截止值的快速排序(50):

def quick_sort(line, l, r):
    if r - l > 50:
        pivot = find_median(line, l, r)
        i, j = l+1, r-2
        while True:
            while line[i] < pivot:
                i += 1
            while line[j] > pivot:
                j -= 1
            if i < j:
                line[i], line[j] = line[j], line[i]
                i += 1
                j -= 1
            else:
                break
        line[i], line[r-1] = line[r-1], line[i]
        quick_sort(line, l, i-1)
        quick_sort(line, i+1, r)
    else:
        insert_sort_index(line, l, r)


def find_median(line, l, r):
    center = (l + r) / 2
    if line[l] > line[r]:
        line[l], line[r] = line[r], line[l]
    if line[l] > line[center]:
        line[l], line[center] = line[center], line[l]
    if line[center] > line[r]:
        line[center], line[r] = line[r], line[center]
    line[center], line[r-1] = line[r-1], line[center]
    return line[r-1]


def insert_sort_index(line, l, r):
    if l < r:
        for idi in range(l+1, r+1):
            data = line[idi]
            for idj in range(idi+1)[::-1]:
                if idj >= l+1 and line[idj-1] > data:
                    line[idj] = line[idj-1]
                else:
                    break
            line[idj] = data

没有截止值的方法:

def quick_sort(line, l, r):
    if r - l > 1:
        pivot = find_median(line, l, r)
        i, j = l+1, r-2
        while True:
            while line[i] < pivot:
                i += 1
            while line[j] > pivot:
                j -= 1
            if i < j:
                line[i], line[j] = line[j], line[i]
                i += 1
                j -= 1
            else:
                break
        line[i], line[r-1] = line[r-1], line[i]
        quick_sort(line, l, i-1)
        quick_sort(line, i+1, r)
    else:
        if r == l + 1:
            if line[l] > line[r]:
                line[l], line[r] = line[r], line[l]

1 个答案:

答案 0 :(得分:1)

python3实现范围和其他函数作为迭代器/生成器,因此在此应用程序中它可能会效率更高,但是python2 range函数会在内存中创建完整列表。您可以多次使用range insert_sort_index(并使用[::-1]拼接创建另一个列表。您可以将step作为参数传递给该范围)。

我的python2实现似乎正在优化带有range(0,x)的循环,这使得更难以证明问题,但是当(l,r)在较大列表中时,就不是这种情况,就像这种quicksort截止值那样

我测量了aprox。通过对idi,idj(而不是range())使用while循环,在较大列表的范围内进行操作时,插入排序的速度提高了一倍。