原地歸併與非原地歸併

2021-08-21 02:58:47 字數 2261 閱讀 1743

看演算法時看到原地歸併和非原地歸併,不是很懂兩者的區別,故記錄如下:

原地演算法(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 的索引,假設陣列元素如...