归并排序(迭代法)
歸并排序
一、思路(自下而上迭代)
4 9 2 7 1
1、以區間大小sz=1劃分數組,即在長度為1的區間內進行merge排序。
4|9|2|7|12、sz*2,繼續上述過程,注意:最后一個元素只有一個,不過沒關系,__merge2支持這樣的操作,只要傳入正確的left,mid,right
4 9|2 7|13、設定邊界條件,sz < len(list)+1
, 同時由于數組下標用到變量i + 2*sz -1,保證不越界,即取數組右邊界即可
二、實現
def __merge2(array, left, mid, right):temp = array[left:right+1]#新數組temp的左中右標記,充當常量n = right -left + 1l = 0r = right -leftm = mid -left#左數組標記i,右數組標記j,賦值外部循環標記ki = 0j = m + 1#遍歷【0,n)即整個數組長度,每次確定一個下標應該賦值的元素并完成賦值操作k = 0 while k < n:#2、定義判斷條件,防越界;循環的次數是由n確定的,不存在i,j同時越界的情況if i > m:array[k + left] = temp[j]j += 1elif j > r:array[k + left] = temp[i]i += 1#1、判斷兩個子數組當前位置的值,并賦值給原數組array的對應位置,此處可能涉及到越界問題,所以循環主體開始之前要判斷一下elif temp[i] < temp[j]:array[k + left] = temp[i]i += 1else:array[k + left] = temp[j]j += 1k += 1def merge_sort_BU(array):n = len(array)#初始最小區間長度為1sz = 1while sz < n + 1:i = 0 while i < n:l1 = ir1 = i+2*sz-1if r1 > n -1:r1 = n-1m1 = l1 + sz - 1# print(l1,m1,r1)__merge2(array, l1, m1, r1)i += 2*sz sz *= 2- 為什么修改__merge函數
在遞歸法中,該函數傳入參數的mid,必定是left + (right - left)//2,,即一定是平分目標區間
但在迭代法中,可能出現不平分的數組需要__merge,此時之前函數的內部實現仍然是平分,顯然狹義化了__merge函數
4 9 2 7 |1三、迭代法有何優勢(適合單鏈表排序)
- 從算法實現過程可以看出,算法總共經過logn層,每層自左向右遍歷所有元素,具有單向性,非常適合單鏈表的排序!(代碼稍加修改)
- 相比之下,歸并時,每次一分為2,對于單鏈表來說,必須從頭結點往下遍歷,查找元素為O(n),使用遞歸法不合適;對于數組,查找元素為O(1),所以對于二分取中值的過程毫無壓力。
總結
- 上一篇: 归并排序的实现及其优化(递归法)
- 下一篇: 玩转OpenVswitch 简介