歸併排序 自底向上的歸併排序演算法

2021-10-24 17:17:28 字數 1818 閱讀 1676

歸併排序(merge sort)是建立在歸併操作上的一種有效,穩定的排序演算法,該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。

分解: 將原序列分解成length長度的若干子串行

求解子問題: 將相鄰的兩個子串行呼叫merge演算法合併成乙個有序子串行

合併: 由於整個序列存放在數字a中,排序過程是就地進行的,合併步驟不需要執行任何操作.

例如:

// merge_sort.cpp : 此檔案包含 "main" 函式。程式執行將在此處開始並結束。

//#include

#include

using

namespace std;

void

disp

(int a,

int n)

//輸出a中所有元素

}void

merge

(int a,

int low,

int mid,

int high)

//將a[low..mid]和a[mid+1..high]兩個相鄰的有序子串行歸併成乙個有序子串行a[low..high]

else

}while

(i <= mid)

//將1表剩下的放進去

while

(j <= high)

//將2表剩下的放進去

for(k =

0, i = low; i <= high; i++

, k++

)//將tampa複製回a中

free

(tampa);}

void

mergepass

(int a,

int length,

int n)

//一趟二路歸併排序

if(i + length -

1< n)

//若餘下兩個子表,後者長度小於length

}void

merge_sort

(int a,

int n)

//二路歸併演算法

}int

main()

; cout <<

"排序前:"

<< endl;

disp

(a, n)

; cout << endl;

merge_sort

(a, n)

; cout <<

"排序後:"

<< endl;

disp

(a, n)

;return0;

}

歸併排序是穩定的排序.即相等的元素的順序不會改變.如輸入記錄 1(1) 3(2) 2(3) 2(4) 5(5) (括號中是記錄的關鍵字)時輸出的 1(1) 2(3) 2(4) 3(2) 5(5) 中的2 和 2 是按輸入的順序.這對要排序資料報含多個資訊而要按其中的某乙個資訊排序,要求其它資訊盡量按輸入的順序排列時很重要。歸併排序的比較次數小於快速排序的比較次數,移動次數一般多於快速排序的移動次數。

速度僅次於快速排序,為穩定排序演算法,一般用於對總體無序,但是各子項相對有序的數列,應用見2023年普及複賽第3題「瑞士輪」的標程。

自底向上的歸併排序

先每兩個元素進行歸併,把它看作是元素個數為1的兩個區間,每兩個進行排序,然後按照每2個元素為乙個區間繼續排序,再按照每4個元素乙個區間進行歸併。1,2,4,8,16。自底向上的歸併排序 public static comparable void sortbu e arr 合併區間 arr l.mid...

3 4 自底向上的歸併排序演算法

下面我們使用一種全新的思路來實現歸併排序演算法。待排序的陣列為,8,6,2,3,1,5,7,4。圖 自底向上的歸併排序演算法 以上我們使用的是 自頂向下 的歸併排序,下面我們介紹 自底向上 的歸併排序演算法。我們並不須要遞迴呼叫,只須要迭代就可以了。下面展示了這種演算法的乙個框架。for int s...

演算法系列 自底向上歸併排序

思路 先歸併微型陣列,然後再成對歸併得到的子陣列,直到我們將整個陣列歸併到一起 先進行兩兩歸併 每個元素想象成大小為1的陣列 然後四四歸併,然後八八歸併。最後一次歸併的第二個子陣列可能比第乙個子陣列要小 merge方法可以解決此問題 對於長度為n的任意陣列,自底向上的歸併排序需要 1 2nlgn至n...