<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>

          八十、歸并排序及其分而治之思想

          共 1459字,需瀏覽 3分鐘

           ·

          2021-01-15 17:19



          「@Author:Runsen」

          ?

          編程的本質(zhì)來源于算法,而算法的本質(zhì)來源于數(shù)學(xué),編程只不過將數(shù)學(xué)題進(jìn)行代碼化。「---- Runsen」

          ?

          歸并排序(Merge sort)是建立在歸并操作上的一種有效的排序算法。該算法是采用分治法(Divide and Conquer)的一個(gè)非常典型的應(yīng)用。

          分治算法

          分治法是把一個(gè)復(fù)雜的問題分成兩個(gè)或更多的相同或相似的子問題,再把子問題分成更小的子問題 直到最后子問題可以簡單的直接求解,原問題的解即子問題的解的合并。(百度百科)

          利用分治策略求解時(shí),所需時(shí)間取決于分解后子問題的個(gè)數(shù)、子問題的規(guī)模大小等因素,而二分法,由于其劃分的簡單和均勻的特點(diǎn),是經(jīng)常采用的一種有效的方法,例如二分法檢索。

          分治算法的基本思想:是將一個(gè)規(guī)模為N的問題分解為K個(gè)規(guī)模較小的子問題,這些子問題相互獨(dú)立且與原問題性質(zhì)相同。求出子問題的解,就可得到原問題的解。即一種分目標(biāo)完成程序算法,簡單問題可用二分法完成。

          分治法所能解決的問題一般具有以下幾個(gè)特征:

          原問題于分解成的小問題具有相同的模式,原問題分解成的小問題可以獨(dú)立求解,子問題之間沒有相關(guān)性。

          具有分解終止條件,當(dāng)問題足夠小時(shí),可以之間求解,分解出的子問題的解可以合并為該問題的解

          基本步驟

          • 分解,將要解決的問題劃分成若干規(guī)模較小的同類問題;
          • 求解,當(dāng)子問題劃分得足夠小時(shí),用較簡單的方法解決;
          • 合并,按原問題的要求,將子問題的解逐層合并構(gòu)成原問題的解。

          具體偽代碼如下:

          if?(問題不可分):
          ????返回解
          else:
          ????從原問題中劃出含一半運(yùn)算對象的子問題1
          ????遞歸調(diào)用分治法過程,求出解1
          ????從原問題中劃出含另一半運(yùn)算對象的子問題2;???
          ????遞歸調(diào)用分治法過程,求出解2
          ????將解1、解2組合成整個(gè)問題的解;??

          歸并排序

          分治算法問題求解,一個(gè)是二分搜索,一個(gè)就是歸并排序。

          歸并排序其實(shí)要做兩件事:

          「拆分」:核心問題是確定拆分位置即可,我們利用左右元素索引之和除2即可,也就是:mid = (left + right)/2,指導(dǎo)拆分到子序列僅僅存在一個(gè)元素的基本情形。

          「合并」:merge 是歸并排序的核心,將兩個(gè)已排序子序列合并為一個(gè)排序序列的過程。當(dāng)子序列中僅存在一個(gè)元素時(shí),可視為子序列已經(jīng)排序,因此我們的合并是從兩個(gè)單一元素子序列開始的。

          當(dāng)子序列存在多個(gè)元素時(shí),我們需要逐個(gè)得到當(dāng)前最小元素,進(jìn)而完成整體排序,過程中我們需要一個(gè)臨時(shí)區(qū)來存儲已排序的部分。

          最后將兩個(gè)區(qū)間合并為一個(gè)有序的區(qū)間,你會(huì)怎么思考呢?

          這個(gè)非常簡單,只要從比較二個(gè)數(shù)列的第一個(gè)數(shù),誰小就先取誰,取了后就在對應(yīng)數(shù)列中刪除這個(gè)數(shù)。然后再進(jìn)行比較,如果有數(shù)列為空,那直接將另一個(gè)數(shù)列的數(shù)據(jù)依次取出即可。

          '''
          @Author:Runsen
          @WeChat:RunsenLiu
          @微信公眾號:Python之王
          @CSDN:https://blog.csdn.net/weixin_44510615
          @Github:https://github.com/MaoliRUNsen
          @Date:2020/12/21
          '''

          def?merge(left,?right):??#?合并兩個(gè)有序數(shù)組
          ????l,?r?=?0,?0
          ????result?=?[]
          ????while?l?and?r?????????if?left[l]?<=?right[r]:
          ????????????result.append(left[l])
          ????????????l?+=?1
          ????????else:
          ????????????result.append(right[r])
          ????????????r?+=?1
          ????result?+=?left[l:]
          ????result?+=?right[r:]
          ????return?result


          def?merge_sort(nums):
          ????if?len(nums)?<=?1:
          ????????return?nums
          ????num?=?len(nums)?>>?1??#位運(yùn)算取中間
          ????left?=?merge_sort(nums[:num])
          ????right?=?merge_sort(nums[num:])
          ????return?merge(left,?right)
          ????
          ????
          if?__name__?==?'__main__':
          ????nums?=?[54,?26,?93,?17,?77,?31,?44,?55,?20]
          ????print(merge_sort(nums))????

          [17,?20,?26,?31,?44,?54,?55,?77,?93]

          歸并排序的運(yùn)行時(shí)間最差、最好和平均都是 O(NlogN),但是歸并排序并沒有像快排那樣,應(yīng)用廣泛,這是為什么呢?因?yàn)樗幸粋€(gè)致命的“弱點(diǎn)”,那就是歸并排序不是原地排序算法。它需要額外的存儲空間,空間復(fù)雜度為 O(N)

          「這世上沒有天才,你若對得起時(shí)間,時(shí)間便對得起你。關(guān)注我們,每天進(jìn)步一點(diǎn)點(diǎn),利用碎片化時(shí)間學(xué)習(xí)。」

          ?

          本文已收錄 GitHub,傳送門~[1] ,里面更有大廠面試完整考點(diǎn),歡迎 Star。

          ?

          Reference

          [1]

          傳送門~: https://github.com/MaoliRUNsen/runsenlearnpy100

          更多的文章

          點(diǎn)擊下面小程序


          - END -


          瀏覽 37
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  爱爱视频片段日韩 | 91人人妻人人澡人人爽人人狠 | 韩国精品无码一区二区三区18 | 日韩99在线 | 黄片在线网站 |