import random, timeit#Qucik sortdef 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 sortdef 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 sortdef 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 我編寫的代碼告訴我們用 3 種排序方式對列表大小 n(數字輸入)進行排序需要多長時間。然而,我發現我的結果非常出乎意料。
1 回答

猛跑小豬
TA貢獻1858條經驗 獲得超8個贊
我可以看到您正在選擇數組的第一個元素作為快速排序中的樞軸。現在,考慮未排序數組元素的順序。是隨機的嗎?你如何生成輸入數組?
您會看到,如果樞軸是數組的最小值或最大值,或者接近頭腦/最大值的某個地方,那么在這種情況下(最壞情況)快速排序的運行時間將是 O(n^2 )。這是因為在每次迭代中,您都通過僅斷開一個元素來對數組進行分區。
為了獲得 O(n log n) 的最佳快速排序性能,您的樞軸應盡可能接近中值。為了增加這種情況的可能性,請考慮最初從數組中隨機選擇 3 個值,并使用中值作為樞軸。顯然,您從最初選擇中位數的值越多,您的樞軸越有效率的可能性就越大,但是您通過選擇這些值開始添加額外的移動,所以這是一個權衡。我想人們甚至可以準確計算出相對于數組大小應該選擇多少元素以獲得最佳性能。
另一方面,無論輸入如何,合并排序總是具有 O(n log n) 順序的復雜性,這就是為什么您在不同樣本上得到一致結果的原因。
TL:DR 我的猜測是輸入數組的第一個元素非常接近該數組的最小值或最大值,它最終成為快速排序算法的關鍵。
添加回答
舉報
0/150
提交
取消