日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

荷兰国旗与快速排序

發布時間:2024/8/1 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 荷兰国旗与快速排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 荷蘭國旗問題
      • 解決荷蘭國旗問題的思路
      • 代碼實現
    • 經典快排
      • 經典快排的思路
      • 代碼實現
      • 經典快排存在的缺陷
    • 隨機快排
      • 隨機快排的思路
      • 代碼實現

荷蘭國旗問題

荷蘭國旗問題:給定一個數組arr,和一個數num,請把小于num的數放在數組的左邊,等于num的數放在數組的中間,大于num的數放在數組的右邊。

以arr = [3,8,9,2,5,5],num = 5為例。

解決荷蘭國旗問題的思路

初始化小于邊界less = -1,大于邊界more = len(arr) = 6,當前比較的位置cur = 0。

  • 如果當前位置上的數小于 num,交換當前位置上的數與邊界less后一個元素,擴大小于num的范圍,less += 1,cur += 1;
  • 如果當前位置上的數大于 num,交換當前位置上的數與邊界more前一個元素,擴大大于num的范圍,more -=1, cur 不變;
  • 如果當前位置上的數等于num,less和more均不變,cur += 1。

當cur = more時,停止比較,返回。

第一步:

初始化小于邊界less = -1,大于邊界more = len(arr) = 6,當前比較的位置cur = 0。

第二步:比較cur = 0位置上的數與num

arr[cur] = 3,arr[cur] < num,所以,交換當前位置上的數與邊界less后一個元素(此處,兩者為同一元素3,可不做交換),less += 1, cur += 1。得到:less = 0,cur = 1,more = 6。

第三步:比較cur = 1位置上的數與num

arr[cur] = 8, arr[cur] > num,所以,交換當前位置上的數與邊界more前一個元素,more -= 1,cur不變。得到:less = 0,cur = 1,more = 5。

第四步:比較cur = 1位置上的數與num

arr[cur] = 5, arr[cur] = num, 所以,less不變,more不變,cur += 1。得到:less = 0,cur = 2,more = 5。

第五步:比較cur = 2位置上的數與num

arr[cur] = 9, arr[cur] > num, 所以,交換當前位置上的數與邊界more前一個元素,less不變,more -= 1,cur不變。得到:less = 0,cur = 2,more = 4。

第六步:比較cur = 2位置上的數與num

arr[cur] = 5, arr[cur] = num, 所以,less不變,more不變,cur += 1。得到:less = 0,cur = 3,more = 4。

第七步:比較cur = 3位置上的數與num

arr[cur] = 2, arr[cur] < num, 所以,交換當前位置上的數與邊界less后一個元素,less += 1,cur += 1,more不變。得到:less = 1,cur = 4,more = 4。

第八步:

此時,cur = 4 = more,停止比較,返回數組。實現了小于num的在左邊,大于num的在右邊,等于num的在中間。

代碼實現

def partition(arr, l, r, num):less = l - 1 # 小于邊界more = r + 1 # 大于邊界cur = less + 1 # 當前比較位置while cur < more:if arr[cur] < num:arr[less + 1], arr[cur] = arr[cur], arr[less + 1]less += 1cur += 1elif arr[cur] > num:arr[more - 1], arr[cur] = arr[cur], arr[more - 1]more -= 1else:cur += 1return arrif __name__ == '__main__':a = [3, 8, 9, 2, 5, 5]print(partition(a, 0, len(a) - 1, 5))

?

經典快排

經典快排的思路

取數組最后一個元素作為劃分值,將小于劃分值的數放在左邊,大于劃分值的數放在右邊,等于劃分值的數放在中間。然后,對左右兩部分繼續進行上述劃分。直到僅剩一個元素為止。

仍以數組arr = [3, 8, 9, 2, 5, 5]為例:

第一步:

取數組最后一個元素做劃分值,即num = 5。將小于5的放在左邊,大于5的放在右邊,等于5的放中間。屬于arr=[3,8,9,2,5,5],num = 5的荷蘭國旗問題。得到小于邊界less = 1,大于邊界more = 4,如下圖:

第二步:

對于0至less部分,取其最后一個元素做劃分值;相當于是arr = [3,2],num = 2的荷蘭國旗問題。得到小于邊界less = -1,大于邊界more = 1。

對于more至 len([3,2,5,5,9,8]) 部分,仍取其最后一個元素做劃分值;相當于是arr = [9,8],num = 8的荷蘭國旗問題。可得小于邊界less = 3,大于邊界more = 5。如下圖:

第三步:

對于左邊數組[2,3],其數組邊界為left = 0,right = 1

less = -1,對于left到less部分,left大于less,沒有元素,返回;

more = 1,對于more到len([2,3]) = 2,僅有一個元素,返回;

對于右邊數組[8,9],其數組邊界為left = 4,right = 5

less = 3,對于left到less部分,left大于less,沒有元素,返回;

more = 5,對于more到 len([2,3,5,5,8,9]) = 6, 僅有一個元素,返回。

排序完成!

代碼實現

def quick_sort(arr, l, r, num):if l < r: # 當滿足這個條件 一直做下去less, more = partition(arr, l, r, num)quick_sort(arr, l, less, arr[less])quick_sort(arr, more, r, arr[r])return arrdef partition(arr, l, r, num):less = l - 1more = r + 1cur = less + 1while cur < more:if arr[cur] < num:arr[less + 1], arr[cur] = arr[cur], arr[less + 1]less += 1cur += 1elif arr[cur] > num:arr[more - 1], arr[cur] = arr[cur], arr[more - 1]more -= 1else:cur += 1return less, moreif __name__ == '__main__':arr = [3, 8, 9, 2, 5, 5]print(quick_sort(arr, 0, len(arr) - 1, arr[-1]))

經典快排存在的缺陷

每次都使用數組最后一個元素做劃分值,復雜度跟數據狀況有很大的關系。

以數組 [1,2,3,4,5,6]為例,每次只排好了一個數,時間復雜度是O(n^2)。

于是,有了隨機快排。

隨機快排

隨機快排的思路

隨機選取數組中的數作為劃分值,將小于劃分值的數放在左邊,大于劃分值的數放在右邊,等于劃分值的數放在中間。然后,對左右兩部分繼續進行上述劃分。直到僅剩一個元素為止。使用隨機,完美地避開了數據狀況問題。

代碼實現

僅需在經典快排的基礎上,添加一個隨機函數即可。

import random, mathdef quick_sort(arr, l, r, num):if l < r: # 隨機選取l到r之間的數,與最后一個位置上的數進行交換# 舍棄浮點數后面的小數位,并取整random_pos = l + int(math.floor(random.random() * (r - l + 1))) arr[r],arr[random_pos] = arr[random_pos],arr[r]less, more = partition(arr, l, r, num)quick_sort(arr, l, less, arr[less])quick_sort(arr, more, r, arr[r])return arrdef partition(arr, l, r, num):less = l - 1more = r + 1cur = less + 1while cur < more:if arr[cur] < num:arr[less + 1], arr[cur] = arr[cur], arr[less + 1]less += 1cur += 1elif arr[cur] > num:arr[more - 1], arr[cur] = arr[cur], arr[more - 1]more -= 1else:cur += 1return less, moreif __name__ == '__main__':arr = [3, 8, 9, 2, 5, 5]print(quick_sort(arr, 0, len(arr) - 1, arr[-1]))

總結

以上是生活随笔為你收集整理的荷兰国旗与快速排序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。