Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 合并、堆和快速排序计数未正确显示_Python_Sorting - Fatal编程技术网

Python 合并、堆和快速排序计数未正确显示

Python 合并、堆和快速排序计数未正确显示,python,sorting,Python,Sorting,正如你所看到的,我的结果与我所学到的大不相同。你能告诉我为什么快速排序不是我代码中最快的吗?以及为什么合并是最快的。我可以看到,您正在选择数组的第一个元素作为快速排序的轴心。现在,考虑未排序数组的元素的顺序。是随机的吗?如何生成输入数组 你看,如果轴是aray的最小值或最大值,或者接近mind/max值的某个位置,那么在这种情况下(最坏情况)快速排序的运行时间将是O(n^2)。这是因为在每次迭代中,您只中断一个元素来划分arry 为了获得O(n log n)的最佳快速排序性能,您的枢轴应尽可能接

正如你所看到的,我的结果与我所学到的大不相同。你能告诉我为什么快速排序不是我代码中最快的吗?以及为什么合并是最快的。我可以看到,您正在选择数组的第一个元素作为快速排序的轴心。现在,考虑未排序数组的元素的顺序。是随机的吗?如何生成输入数组

你看,如果轴是aray的最小值或最大值,或者接近mind/max值的某个位置,那么在这种情况下(最坏情况)快速排序的运行时间将是O(n^2)。这是因为在每次迭代中,您只中断一个元素来划分arry

为了获得O(n log n)的最佳快速排序性能,您的枢轴应尽可能接近中间值。为了增加这种情况的可能性,首先考虑从阵列中随机选取3个值,并使用中值作为支点。显然,你从一开始选择的中值越多,你的支点效率就越高,但是你通过选择这些值来增加额外的移动,所以这是一种权衡。我想人们甚至可以根据阵列的大小精确地计算应该选择多少个元素以获得最佳性能

另一方面,不管输入是什么,合并排序的复杂度总是按O(n logn)的顺序,这就是为什么在不同的样本上使用它可以得到一致的结果


TL:DR我的猜测是,输入数组的第一个元素非常接近该数组的最小值或最大值,它最终成为快速排序算法的轴心。

我可以看出,您正在选择数组的第一个元素作为快速排序的轴心。现在,考虑未排序数组的元素的顺序。是随机的吗?如何生成输入数组

你看,如果轴是aray的最小值或最大值,或者接近mind/max值的某个位置,那么在这种情况下(最坏情况)快速排序的运行时间将是O(n^2)。这是因为在每次迭代中,您只中断一个元素来划分arry

为了获得O(n log n)的最佳快速排序性能,您的枢轴应尽可能接近中间值。为了增加这种情况的可能性,首先考虑从阵列中随机选取3个值,并使用中值作为支点。显然,你从一开始选择的中值越多,你的支点效率就越高,但是你通过选择这些值来增加额外的移动,所以这是一种权衡。我想人们甚至可以根据阵列的大小精确地计算应该选择多少个元素以获得最佳性能

另一方面,不管输入是什么,合并排序的复杂度总是按O(n logn)的顺序,这就是为什么在不同的样本上使用它可以得到一致的结果

TL:DR,我的猜测是,输入数组的第一个元素非常接近该数组的最小值或最大值,它最终成为快速排序算法的轴心

import random, timeit

#Qucik sort
def quick_sort(A,first,last):
    global Qs,Qc
    if first>=last: return
    left, right= first+1, last
    pivot = A[first]
    while left <= right:
        while left <=last and A[left]<pivot:
            Qc= Qc+1
            left= left + 1
        while right > first and A[right] >= pivot:
            Qc=Qc+1
            right = right -1
        if left <= right:   
            A[left],A[right]=A[right],A[left]
            Qs = Qs+1
            left= left +1
            right= right-1

    A[first],A[right]=A[right],A[first]
    Qs=Qs+1
    quick_sort(A,first,right-1)
    quick_sort(A,right+1,last)


#Merge sort
def merge_sort(A, first, last): # merge sort A[first] ~ A[last]
    global Ms,Mc
    if first >= last: return
    middle = (first+last)//2
    merge_sort(A, first, middle)
    merge_sort(A, middle+1, last)
    B = []
    i = first
    j = middle+1
    while i <= middle and j <= last:
        Mc=Mc+1
        if A[i] <= A[j]:
            B.append(A[i])
            i += 1
        else:
            B.append(A[j])
            j += 1
    for i in range(i, middle+1): 
        B.append(A[i])
        Ms=Ms+1
    for j in range(j, last+1):
        B.append(A[j])
    for k in range(first, last+1): A[k] = B[k-first]

#Heap sort
def heap_sort(A):
    global Hs, Hc
    n = len(A)
    for i in range(n - 1, -1, -1):
        while 2 * i + 1 < n:
            left, right = 2 * i + 1, 2 * i + 2
            if left < n and A[left] > A[i]:
                m = left
                Hc += 1
            else:
                m = i
                Hc += 1
            if right < n and A[right] > A[m]:
                m = right
                Hc += 1
            if m != i:
                A[i], A[m] = A[m], A[i]
                i = m
                Hs += 1
            else:
                break                               
    for i in range(n - 1, -1, -1):
        A[0], A[i] = A[i], A[0]
        n -= 1
        k = 0
        while 2 * k + 1 < n:
            left, right = 2 * k + 1, 2 * k + 2
            if left < n and A[left] > A[k]:
                m = left
                Hc += 1
            else:
                m = k
                Hc += 1
            if right < n and A[right] > A[m]:
                m = right
                Hc += 1
            if m != k:
                A[k], A[m] = A[m], A[k]
                k = m
                Hs += 1
            else:
                break

#

def check_sorted(A):
    for i in range(n-1):
        if A[i] > A[i+1]: return False
    return True

#

#

Qc, Qs, Mc, Ms, Hc, Hs = 0, 0, 0, 0, 0, 0

n = int(input())
random.seed()
A = []
for i in range(n):
    A.append(random.randint(-1000,1000))
B = A[:]
C = A[:]

print("")
print("Quick sort:")
print("time =", timeit.timeit("quick_sort(A, 0, n-1)", globals=globals(), number=1))
print("  comparisons = {:10d}, swaps = {:10d}\n".format(Qc, Qs))
print("Merge sort:")
print("time =", timeit.timeit("merge_sort(B, 0, n-1)", globals=globals(), number=1))
print("  comparisons = {:10d}, swaps = {:10d}\n".format(Mc, Ms))

print("Heap sort:")
print("time =", timeit.timeit("heap_sort(C)", globals=globals(), number=1))
print("  comparisons = {:10d}, swaps = {:10d}\n".format(Hc, Hs))


assert(check_sorted(A))
assert(check_sorted(B))
assert(check_sorted(C))
Quick sort:
time = 0.0001289689971599728
  comparisons =        474, swaps =        168

Merge sort:
time = 0.00027709499408956617
  comparisons =        541, swaps =         80

Heap sort:
time = 0.0002578190033091232
  comparisons =        744, swaps =        478

Quick sort:
time = 1.1767549149953993
  comparisons =    3489112, swaps =     352047

Merge sort:
time = 0.9040642600011779
  comparisons =    1536584, swaps =      77011

Heap sort:
time = 1.665754442990874
  comparisons =    2227949, swaps =    1474542

Quick sort:
time = 4.749891302999458
  comparisons =   11884246, swaps =     709221

Merge sort:
time = 3.1966246420051903
  comparisons =    3272492, swaps =     154723

Heap sort:
time = 6.2041203819972
  comparisons =    4754829, swaps =    3148479