1. 程式人生 > >3-5 回顧,快速二分法的疑點解惑:為啥先右j移動?因為設定a[left]為基準點

3-5 回顧,快速二分法的疑點解惑:為啥先右j移動?因為設定a[left]為基準點

思路 i+1 pad 從大到小 設定 二分 出現 移動 文章

快速二分法的疑點解惑:為啥先右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]為基準點