二分歸併排序 分治演算法與歸併排序

2021-10-12 07:56:13 字數 1769 閱讀 1764

距離上次寫快排演算法的文章已經過去乙個半月了,和本文要提到的歸併排序演算法類似,快排也是分治思想的一種典型應用,如果有不熟悉快速排序的同學可以翻閱我之前寫過的的快速排序演算法的文章。

首先為大家介紹一下什麼是分治,分治是將乙個大問題分割成若干個和原來問題形式相同但規模更小的子問題,然後處理這些小問題,最終實現整個大問題的過程。

額...上面說的概念確實很難理解,我們換乙個生活中的場景來介紹一下什麼是分治吧。

小明手裡有8枚硬幣,其中有1枚是假幣,已知假幣比真幣輕,現在我們有一架天平,那麼我們該怎麼找出假幣呢?

首先我們將硬幣分成兩組,每組4枚硬幣,分別放到天平上稱,硬幣一定在輕的那一組裡,再次將輕的那一邊的硬幣分成兩組,每組2枚硬幣,然後再取輕的那一邊在進行二分,直到最後將2枚硬幣放在天平上,輕的那一枚就是假幣。這裡用的就是簡單的分治思想,每次把問題規模縮小一半,這裡不僅是分治思想,其實也是用到了二分法的思想。

歸併排序是分治演算法的一種典型應用,基本思路如下:

不多逼逼,直接給你們看**。

public void mergesort(int arr, int s, int e, int tmp) 

}private void merge(int arr, int s, int m, int e, int tmp) else

} while (p1 <= m)

while (p2 <= e)

for (int i = 0; i < e - s + 1; ++i)

}

咱們來梳理一下上面的**,首先是mergesort方法,當起始位置小於終止位置的時候才會執行**,否則直接結束這個方法。再看看這個判斷語句裡的內容,首先是求出陣列的中點,對陣列一分為二進行分治,然後這兩個陣列又遞迴呼叫這個方法,最後對兩個已經排好序的陣列執行merge方法,進行歸併操作。我們可以知道的是,當分到一定程度(s和e指向相同的元素)時,會結束遞迴,進行歸併。我們用一組資料來模擬這個過程。

以上是乙個待排序的陣列,陣列長度為10,因此傳入的s和e分別為0和9,求出的m值為4,於是將陣列分為下標0~4和下標5~9的兩個陣列再分別進行歸併排序。

為了簡化內容,我們嘗試對前乙個陣列進行遞迴。此時傳入的s和e分別是0和4,則m是2,再對前乙個陣列進行遞迴,s和e是0和2,m是1,繼續遞迴,s和e是0和1,m是0,這時候兩個陣列都只有乙個數了,這時候就需要對這兩個數進行merge操作。所謂的merge操作,就是將兩個陣列中的元素按從小到大的順序複製到tmp陣列中,然後複製回arr陣列中。咱們下面用來展示一下上面的**到底對這個陣列幹了些什麼。

實際上,上述過程只是邏輯上的切分和歸併,事實上由於遞迴需要不斷壓棧以及以上**需要順序執行,切分和歸併的次數還要更多一些。

最後需要提到的是,歸併排序是一種穩定的排序演算法,時間複雜度為

二分歸併排序演算法 排序演算法之歸併排序

一 分治模式 許多有用的演算法在結構上是遞迴的 為了解決乙個給定的問題,演算法一次或多次遞迴地呼叫其自身以解決緊密相關的若干子問題。這些演算法典型地遵循分治法的思想 將原問題分解為幾個規模較小但類似於原問題的子問題。遞迴的求解這些問題,然後再合併這些子問題的解來建立原問題的解。分治模式在每層遞迴都有...

分治演算法二 歸併排序

目錄 1 將原始序列拆分成兩個序列 分解過程 2 針對拆分後的序列,利用歸併演算法遞迴處理,進一步拆分,直到不能拆分為止,即僅乙個元素 最小問題,治理 3 利用合併兩個有序序列方法,將 2 中的最小問題逐個組合,最終組合成問題的解 合併 4 整個過程,是真的在分解整個序列,完美地體現了分治思想。me...

歸併排序 二分

歸併排序就是將陣列反覆拆分成兩部分,然後分別在這兩部分裡面再反覆拆分,講拆分成的兩部分按順序排好之後再歸併起來,歸併起來之後再反覆交換位置,最終使整個陣列按順序排列。具體操作方法 按從小到大排 拆分成的兩部分依次比較,若前半部分的較小,將其存入陣列tmp中,將前面的下標i 若後面一部分較小,則將後面...