標籤:neu 排列 結束 設定 turn nbsp san tom return
快速二分法的疑點解惑:為啥先右j移動?因為設定a[left]為基準數
思路:(查看了網上的2篇文章,關鍵點就是誰為基準數,我自己又嘗試了不同排序,不同基準數left,right。得出??的結論)
步驟:
1. 在序列中設a[left]為基準數。最左邊設i,最右邊設j(目標是從大到小排列)
2. 先從右往左找大於基準數的數,再從左往右找小於基準數的數,找到後兩數交換位置
3. 然後重複2和3步驟。直到i和j最終相遇,結束本次迴圈。
4. 把基準數和最終相遇的數交換,結束。此步驟定位了一個數。
5. 原基準數左邊和右邊的序列再分別重複1-4的步驟。繼續定位新的基準數。直到全部數字定位結束。
第2步,先右移動,是因為基準點設為a[left]。如果先左邊i移動的話得到的a[i]必然比a[left]小。
在第4步交換a[i]和a[left]的時候導致了基準點a[left]右邊竟然有比它小的數字。不符合每次迴圈定位1個基準點的原則,從大到小排序就失敗了。(當然如果是從小往大排序也一樣,會導致類似的問題出現。)
所以如果基準點定位到最左邊的話,j就要先移動。當然基準點定位到最右邊的話,i就先移動了。
def quicksort(a,left,right) if left > right # 設定何時停止該方法的調用。 return end
temp = a[left] #設定最左邊的為基準數 i = left j= right while i != j # i和j從兩邊向中間靠攏,直到i和j重合,結束本輪迴圈。
# 根據是升序還是降序來選擇 比較子號。
while a[j] <= temp && i < j #根據基準點是a[left],要先從右往左找。 j -= 1 end while a[i] >= temp && i < j #再從左向右找,這裡找小於基準數的數。 i += 1 end if i < j #當i 和 j 沒有相遇的時候,交換資料 t = a[i] a[i] = a[j] a[j] = t end end a[left] = a[i] #將基準數歸位。 a[i] = temp
print a.to_s + "\n" #列印每次交換的結果
quicksort(a,left,i-1) # 在quciksort的方法中,再次調用本方法,形成遞迴的過程。這個是處理i左邊。 # 直到窮盡,即當left>right時停止調用該方法。 quicksort(a,i+1,right) # 這個處理i右邊end
a = [7, 68, 42, 46, 9, 91, 77, 46, 86, 1]quicksort(a,0,9)# 0和9 代表數組最左邊和最右邊的key print a
結果:
[86, 68, 42, 46, 9, 91, 77, 46, 7, 1][91, 86, 42, 46, 9, 68, 77, 46, 7, 1][91, 86, 42, 46, 9, 68, 77, 46, 7, 1][91, 86, 77, 46, 46, 68, 42, 9, 7, 1][91, 86, 77, 46, 46, 68, 42, 9, 7, 1][91, 86, 77, 68, 46, 46, 42, 9, 7, 1][91, 86, 77, 68, 46, 46, 42, 9, 7, 1][91, 86, 77, 68, 46, 46, 42, 9, 7, 1][91, 86, 77, 68, 46, 46, 42, 9, 7, 1][91, 86, 77, 68, 46, 46, 42, 9, 7, 1][91, 86, 77, 68, 46, 46, 42, 9, 7, 1] #最終結果
3-5 回顧,快速二分法的疑點解惑:為啥先右j移動?因為設定a[left]為基準點