<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          數組排序——從荷蘭國旗問題到快速排序

          共 2983字,需瀏覽 6分鐘

           ·

          2023-05-31 18:25

          ??本文首先將會介紹荷蘭國旗問題,再講述如何從該問題過渡到快速排序。

          荷蘭國旗問題

          ??荷蘭國旗問題(Dutch National Flag Problem)是由荷蘭計算機科學家Edsger Dijkstra所提出,該問題的描述如下:

          給定n個紅、白、藍三種顏色的小球,無序地排列在一起。對這些小球進行排序,使得所有相同顏色的球在一起,且顏色順序依次為紅、白、藍。

          因荷蘭國旗的顏色從上到下分別為紅、白、藍,故該問題被稱為荷蘭國旗問題
          ??事實上,在Leetcode中,該問題又被描述為:

          給定一個包含紅色、白色和藍色、共 n 個元素的數組 nums ,原地對它們進行排序,使得相同顏色的元素相鄰,并按照紅色、白色、藍色順序排列。我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。要求使用的空間復雜度為常數空間。

          因此,荷蘭國旗問題又被稱為顏色分類問題
          ??針對該問題,其解決的算法采用雙指針法。我們采用兩個指針lowhigh,分別指向0和2,再使用變量mid對數量進行遍歷。具體的步驟如下:

          • 若mid遍歷到的位置為0,則和low處的元素交換,同時向右移動low和mid。

          • 若mid遍歷到的位置為1,則不需要處理,只需向右移動mid。

          • 若mid遍歷到的位置為2,則和high處的元素交換,交換后只把high向左移動,mid仍然指向原位置。

          整個算法的示意圖如下:

          34cd67c72d6458bd5fb502ad967e7116.webp荷蘭國旗問題的算法示意圖
          上述算法的Python代碼如下:
          def?sort_colors(nums):
          ????low,?high,?mid?=?0,?len(nums)-1,?0
          ????while?mid?<=?high:
          ????????if?nums[mid]?==?0:
          ????????????nums[low],?nums[mid]?=?nums[mid],?nums[low]
          ????????????low?+=?1
          ????????????mid?+=?1
          ????????elif?nums[mid]?==?2:
          ????????????nums[high],?nums[mid]?=?nums[mid],?nums[high]
          ????????????high?-=?1
          ????????else:
          ????????????mid?+=?1
          ????return?nums


          if?__name__?==?'__main__':
          ????numbers?=?[1,?0,?1,?0,?2,?0,?2,?1]
          ????result?=?sort_colors(numbers)
          ????print(result)

          輸出結果如下:

          [0,?0,?0,?1,?1,?1,?2,?2

          快速排序

          ??對于上述的荷蘭國旗問題,我們可以將思路拓寬,用它來實現快速排序。
          ??對于數組array,我們取其切片,即從位置low到high的數組片段(包括位置low和high),我們使用類似于荷蘭國旗問題的思路,先選擇一個數字作為樞紐(pivot),再找到合適的位置,使其作為小于pivot的數字排列和等于pivot的數字排列的分割點(類似于荷蘭國旗問題中的數字0和1的分割點位置low)。
          ??接著,我們再循環(huán)調用上述算法,實現整個數組(從位置0到長度-1的數組切片)的排序。
          ??上述算法的Python實現代碼如下:

          def?partition(array,?low,?high):
          ????pivot?=?array[low]
          ????a,?b,?c?=?low,?high,?low
          ????while?c?<=?b:
          ????????if?array[c]?<?pivot:
          ????????????array[a],?array[c]?=?array[c],?array[a]
          ????????????a?+=?1
          ????????????c?+=?1
          ????????elif?array[c]?>?pivot:
          ????????????array[b],?array[c]?=?array[c],?array[b]
          ????????????b?-=?1
          ????????else:
          ????????????c?+=?1
          ????return?a


          def?quick_sort(array,?low,?high):
          ????if?low?<?high:
          ????????pi?=?partition(array,?low,?high)
          ????????#?Recursive?call?on?the?left?of?pivot
          ????????quick_sort(array,?low,?pi?-?1)
          ????????#?Recursive?call?on?the?right?of?pivot
          ????????quick_sort(array,?pi?+?1,?high)
          ????return?array


          if?__name__?==?'__main__':
          ????n?=?13
          ????my_list?=?list(range(n))
          ????from?random?import?shuffle
          ????shuffle(my_list)
          ????print('排序前:',?my_list)
          ????result?=?quick_sort(my_list,?0,?len(my_list)-1)
          ????print('排序后:',?result)

          輸出結果如下:

          排序前:?[12,?8,?7,?3,?1,?0,?4,?2,?9,?6,?11,?10,?5]
          排序后:?[0,?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12]

          注意,該算法的時間復雜度為O(nlogn),空間復雜度為O(1).
          ??另外,還有其它的快速排序的實現代碼,如下:

          def?quick_sort(array):
          ????n?=?len(array)
          ????if?n?<=?1:
          ????????return?array
          ????pivot?=?array[n//2]
          ????left?=?[x?for?x?in?array?if?x?<?pivot]
          ????middle?=?[x?for?x?in?array?if?x?==?pivot]
          ????right?=?[x?for?x?in?array?if?x?>?pivot]
          ????return?quick_sort(left)?+?middle?+?quick_sort(right)

          但顯然,該實現代碼在空間復雜度上不如上一種。

          總結

          ??近來ChatGPT大火,我們也嘗試著用ChatGPT來實現快速排序,如下:

          8612ac031399d2d5bb98ee16bebc5a66.webpChatGPT實現快速排序
          ??本文介紹了荷蘭國旗問題,并將其擴展快速排序,并介紹了兩種快速排序的算法,最后再用ChatGPT來實現快速排序。


          參考文獻

          1. 荷蘭國旗問題: https://juejin.cn/post/6890141987988340749

          2. 顏色分類: https://leetcode.cn/problems/sort-colors/description/

          3. QuickSort:https://www.geeksforgeeks.org/quick-sort/


          瀏覽 58
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲综合免费观看高清完整版在线观 | 久草久热精品视频 | 欧美性爱国产 | 亚洲欧洲精品成人 | 黄片视频链接 |