歸併排序(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...