資料結構 歸併排序

2021-08-21 20:30:34 字數 3282 閱讀 4421

def inversepairs(data):

# write code here

if not data:

return 0

copy =

for i in data:

length = len(data)

count = inversepairscore(data, copy, 0, length - 1)

print(count%1000000007)

return count%1000000007

def inversepairscore(data, copy, start, end):

if start == end:

copy[start] = data[start]

return 0

length = int((end - start) / 2)

left = inversepairscore(copy, data, start, start + length)

right = inversepairscore(copy, data, start + length + 1, end)

i = start + length

j = end

index_copy = end

count = 0

while i >= start and j >= start + length + 1:

if data[i] > data[j]:

copy[index_copy] = data[i]

index_copy -= 1

i -= 1

count += j - start - length

else:

copy[index_copy] = data[j]

index_copy -= 1

j -= 1

copy += data[start:i+1]

copy += data[start + length + 1:j+1]

return (left + right + count)

data = [364, 637, 341, 406, 747, 995, 234, 971, 571, 219, 993, 407, 416, 366, 315, 301, 601, 650, 418, 355, 460, 505, 360, 965, 516, 648, 727, 667, 465, 849, 455, 181, 486, 149, 588, 233, 144, 174, 557, 67, 746, 550, 474, 162, 268, 142, 463, 221, 882, 576, 604, 739, 288, 569, 256, 936, 275, 401, 497, 82, 935, 983, 583, 523, 697, 478, 147, 795, 380, 973, 958, 115, 773, 870, 259, 655, 446, 863, 735, 784, 3, 671, 433, 630, 425, 930, 64, 266, 235, 187, 284, 665, 874, 80, 45, 848, 38, 811, 267, 575]

inversepairs(data)

基本思想:

歸併排序與之前的交換(快速)、選擇(堆)等排序的思想不一樣,「歸併」的含義就是:

將兩個或者兩個以上的有序表組合成乙個新的有序表,假定待排序表含有n個記錄,則可以看做是n個有序的子表,每個子表的長度為1,然後兩兩歸併,得到合併成乙個長度為n的有序表為止,這種排序方法為2-路歸併排序

初始關鍵字: 49  38

65  97

76  1327

一趟歸併後: 38  49  65  97

13  76  27

二趟歸併後: 38  49  65  97  13  27  76

三趟歸併後: 13  27  38  49  65  76  97

merge()的功能是將前後相鄰的兩個有序表歸併成為乙個有序表的演算法。

設兩段有序表a[low,...mid]、a[mid+1,...high]放在同乙個有序表的兩個位置上,先讓它們複製到輔助陣列b裡面,每次從對應b中的兩個段取出乙個記錄進行關鍵字的比較,先將小者放入a中,當陣列b中有一段的下標超出其對應的表長時,即該段所有的元素已經完全複製到a中,另一端中的剩餘部分直接複製到a中。

遞迴形式的2-路歸併排序是基於分治的!過程如下:

**如下:

# merge函式的功能是將前後相鄰的兩個有序子表歸併成為乙個有序表

# left和right就是兩個前後相鄰的有序子表,我們需要乙個輔助陣列result,最後返回的result就是最後的

# 歸併排序結果

# i和j一起從0開始向後走,對應位置(不一定就是下標相同)誰小誰被收到result中去,然後下去的那個指標向

# 後走乙個,直到最後

# 其實result += left[i:] 和 result += right[j:]只會執行乙個,因為有乙個已經被收光了。

def merge(left, right):

i, j = 0, 0

result =

while i < len(left) and j < len(right):

if left[i] <= right[j]:

i += 1

else:

j += 1

result += left[i:]

result += right[j:]

return result

# 遞迴形式的二路歸併演算法是基於分治的

# 分解:將n個記錄一分為2,然後對分開的兩個各含有n/2個元素的子表遞迴呼叫自身

# 合併: 合併兩個已經排序的子表得到結果

def merge_sort(lists):

if len(lists) <= 1:

return lists

num = len(lists) /2

left = merge_sort(lists[:num])

right = merge_sort(lists[num:])

return merge(left, right)

效能:穩定性:

merge不會改變相同關鍵字記錄的相對次序,所以2路歸併排序是乙個穩定的排序演算法。

資料結構 歸併排序

排序 sort 或分類 內部排序方法可以分為五類 插入排序 選擇排序 交換排序 歸併排序和分配排序。歸併排序 include using namespace std 歸併排序中的合併演算法 void merge int a,int left,int center,int len int t int ...

資料結構 歸併排序

歸併排序,即merge sort,通過遞迴式的merge操作 merge即歸併 實現排序。演算法思想是分治思想 divide and conquer 歸併排序一般是遞迴實現的 時間複雜度o nlgn 遞迴都是一去一回,去的時候divide,回的時候conquer。表達欠提煉 1 divide,分 遞...

資料結構 歸併排序!!!

歸併排序 整體思想 將資料分成很多的部分,每次排序資料的一部分,然後將兩部分的資料進行整體排序,這樣一步一步將整體資料排序。如圖 注 將需要排序的資料進行分塊,當每個塊的資料足夠的少的時候就可以進行效率高的排序方法,當兩塊資料排序好的時候就可以將兩塊排序好的資料進行合併。具體實現方法 ifndef ...