看演算法時看到原地歸併和非原地歸併,不是很懂兩者的區別,故記錄如下:
原地演算法(in-place algorithm)基本上不需要額外輔助的資料結構,然而,允許少量額外的輔助變數來轉換資料的演算法。當演算法執行時,輸入的資料通常會被要輸出的部分覆蓋掉。——wiki
那麼我們來看下兩種演算法的**:
非原地
class
sort:
def__init__
(self):
self.count = 0
# 用於計數mergesort的執行次數
defmergesort
(self, alist):
if len(alist) <= 1:
return alist
mid = int(len(alist) / 2)
left = self.mergesort(alist[:mid])
right = self.mergesort(alist[mid:])
self.count += 1
return self.mergesortedarray(left, right)
defmergesortedarray
(self, a, b):
sortedarray =
l = 0
r = 0
while l < len(a) and r < len(b):
if a[l] < b[r]:
l += 1
else:
r += 1
sortedarray += a[l:]
sortedarray += b[r:]
return sortedarray
unsortedarray = [6, 5, 3, 1, 8, 7, 2, 4]
merge_sort = sort()
print(merge_sort.mergesort(unsortedarray), merge_sort.count)
# [1, 2, 3, 4, 5, 6, 7, 8] 7
原地
class
sort:
def__init__
(self):
self.count = 0
defmergesort
(self, alist, low, high):
if high - 1
<= low:
return
mid = low + int((high - low) / 2)
self.mergesort(alist, low, mid)
self.mergesort(alist, mid, high)
self.count += 1
self.mergesortedarray(alist, low, mid, high)
defmergesortedarray
(self, alist, low, mid, high):
helper = alist[:]
originmid = mid
for index in range(low, high):
if low >= originmid:
alist[index] = helper[mid]
mid += 1
elif mid >= high:
alist[index] = helper[low]
low += 1
elif helper[low] < helper[mid]:
alist[index] = helper[low]
low += 1
else:
alist[index] = helper[mid]
mid += 1
unsortedarray = [6, 5, 3, 1, 8, 7, 2, 4]
merge_sort = sort()
merge_sort.mergesort(unsortedarray, 0, len(unsortedarray))
print(unsortedarray, merge_sort.count)
# [1, 2, 3, 4, 5, 6, 7, 8] 7
我們可以看到二者的差別在於:
所以可以理解為在mergesort這一步驟,原地演算法的空間複雜度是o(1),非原地是o(n)
In place Merge 原地歸併
陣列al 0,mid 1 和 al mid,num 1 都分別有序。將其merge成有序陣列al 0,num 1 要求空間複雜度o 1 思路 一般的歸併是需要o n 的空間,而這裡要求空間複雜度為o 1 也就是只能使用常熟級別的臨時變數。而原地操作無非就是移動,關鍵是怎麼移動。在程式設計珠璣中有乙個...
原地歸併排序
原地歸併排序相比於普通歸併排序,不需要開拓額外空間就可進行兩個有序陣列的merge,故空間複雜度為o 1 無論是原地歸併排序還是普通歸排序 最外層的遞迴形式都是統一的,如下 void mergesort int arr,int low,int high 下面首先給出普通的merge 函式,需要申請輔...
原地歸併排序
原地歸併排序 原地歸併排序不需要輔助陣列既可以歸併。關鍵在於merge函式。假設有兩段遞增的子陣列arr begin.mid 1 和arr mid.end 但是整個陣列不是遞增的。其中i begin,j mid,k end 第一步 i往後移動,找到第乙個arr i arr j 的索引,假設陣列元素如...