排序專題 (2)歸併排序

2021-10-10 17:27:55 字數 1749 閱讀 5618

一、以順序表為儲存結構的歸併排序

自頂向下遞迴分治 (排序地基本邏輯略過,**有詳細注釋)

// 偽**

template

void

_mergesort

(t arr,

int l,

int r)

t aux[l-r+1]

;// 申請輔助陣列, 可以malloc動態申請,也可以用vector

void

_merge

(t arr,

int l,

int mid,

int r)

/* 下列這兩個while為同一操作, 故只會執行其中乙個, 均為剩餘數填充 */

while

(i <= mid)

// 左側表未檢測完

arr[k++

]= aux[i++];

while

(j <= high)

// 右側表未檢測完

arr[k++

]= aux[j++];

}

使用迴圈進行自底向上的歸併排序

template 

void

mergesortbu

(t arr,

int n)

}

二、以煉表為儲存結構的歸併排序

對鍊錶自頂向下歸併排序的過程如下。

(1)、找到鍊錶的中點,以中點為分界,將鍊錶拆分成兩個子鍊錶。尋找鍊錶的中點可以使用快慢指標的做法,快指標每次移動 2 步,慢指標每次移動 1 步,當快指標到達鍊錶末尾時,慢指標指向的鍊錶節點即為鍊錶的中點。【leetcode 876. 鍊錶的中間結點】

(2)、對兩個子鍊錶分別排序,遞迴到最後只有乙個節點或者為空,比較兩個不為空節點大小即可得到乙個有序子鏈。

(3)、遞迴合併鍊錶。【leetcode 21. 合併兩個有序鍊錶】

// 以下為leetcode官方給出的題解,用過載函式轉了介面

class

solution

listnode*

sortlist

(listnode* head, listnode* tail)

listnode* slow = head,

*fast = head;

// 快慢指標的方法確定中間位置

while

(fast != tail)

listnode* mid = slow;

return

merge

(sortlist

(head, mid)

,sortlist

(mid, tail));

} listnode*

merge

(listnode* head1, listnode* head2)

else

temp = temp -

> next;

// 更新temp}if

(temp1 !=

nullptr

)// 值大的表一定有剩餘, 掛到temp上

temp -

> next = temp1;

else

if(temp2 !=

nullptr

) temp -

> next = temp2;

return dummyhead-

>next;}}

;

排序專題之歸併排序

歸併排序 基本思想是將兩個或兩個以上有序表合併成乙個新的有序表。假設初始序列含有n個記錄,首先將這n個記錄看成n個有序的子串行,每個子串行的長度為1,然後兩兩歸併,得到?n 2?個長度為2 n為奇數時,最後乙個序列的長度為1 的有序子串行 在此基礎上,再進行兩兩歸併,如此重複,直至得到乙個長度為n的...

歸併排序(2 路歸併排序)

遞迴寫法 include define maxn 100 void merge int a,int l1,int r1,int l2,int r2 將陣列a的區間 l1,r1 和區間 l2,r2 合併為乙個有序區間 else while i r1 while j r2 for int i 0 i非遞...

2 歸併排序

兩個有序陣列合併成乙個總的有序陣列 public static void merge int data int left,int mid int right else 最後有可能兩個有序陣列其中乙個並沒有排完就跳出了迴圈 此時補上剩餘陣列的剩餘元素 while leftpoint mid while...