【归并排序】
使用合并排序为一列数字进行排序的过程
归并排序（Merge sort，或mergesort），是建立在归并操作上的一种有效的排序算法，效率为（大O符号）。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法（Divide and Conquer）的一个非常典型的应用，且各层分治递归可以同时进行。
== 概述 ==
采用分治法:
* 分割：递归地把当前序列平均分割成两半。
* 整合：在保持元素顺序的同时将上一步得到的子序列整合到一起（归并）。
== 归并操作 ==
归并操作（merge），也叫归并算法，指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
=== 递归法（Top-down） ===
#申请空间，使其大小为两个已经排序序列之和，该空间用来存放合并后的序列
#设定两个指针，最初位置分别为两个已经排序序列的起始位置
#比较两个指针所指向的元素，选择相对小的元素放入到合并空间，并移动指针到下一位置
#重复步骤3直到某一指针到达序列尾
#将另一序列剩下的所有元素直接复制到合并序列尾
=== 迭代法（Bottom-up） ===
原理如下（假设序列共有个元素）：
#将序列每相邻两个数字进行归并操作，形成个序列，排序后每个序列包含两/一个元素
#若此时序列数不是1个则将上述序列再次归并，形成个序列，每个序列包含四/三个元素
#重复步骤2，直到所有元素排序完毕，即序列数为1
==实作范例==
===C语言===
迭代版：
int min(int x, int y) {
return x
递归版：
// 分治-治
void mergeSort_conquer(int* array, int left, int mid, int right, int* temp) {
// left, mid和mid+1, right两个有序数组
int i = left;
int j = mid + 1;
int index = 0;
while (i
===C++===
迭代版：
template // 整数或浮点数皆可使用,若要使用物件(class)时必须设定"小于"(
递归版：
void Merge(vector &Array, int front, int mid, int end) {
// preconditions:
// Arrayfront...mid is sorted
// Arraymid+1 ... end is sorted
// Copy Arrayfront ... mid to LeftSubArray
// Copy Arraymid+1 ... end to RightSubArray
vector LeftSubArray(Array.begin() + front, Array.begin() + mid + 1);
vector RightSubArray(Array.begin() + mid + 1, Array.begin() + end + 1);
int idxLeft = 0, idxRight = 0;
LeftSubArray.insert(LeftSubArray.end(), numeric_limits::max());
RightSubArray.insert(RightSubArray.end(), numeric_limits::max());
// Pick min of LeftSubArrayidxLeft and RightSubArrayidxRight, and put into Arrayi
for (int i = front; i  &Array, int front, int end) {
if (front >= end)
return;
int mid = front + (end - front) / 2;
MergeSort(Array, front, mid);
MergeSort(Array, mid + 1, end);
Merge(Array, front, mid, end);
}
===C#===
public static List sort(List lst) {
if (lst.Count  left = new List();  // 定义左侧List
List right = new List(); // 定义右侧List
// 以下两个循环把 lst 分为左右两个 List
for (int i = 0; i
/// 合并两个已经排好序的List
///
/// 左侧List
/// 右侧List
///
static List merge(List left, List right) {
List temp = new List();
while (left.Count > 0 && right.Count > 0) {
if (left0  0) {
for (int i = 0; i  0) {
for (int i = 0; i
===Ruby===
def merge list
return list if list.size
===Java===
递归版：
static void merge_sort_recursive(int arr, int result, int start, int end) {
if (start >= end)
return;
int len = end - start, mid = (len >> 1) + start;
int start1 = start, end1 = mid;
int start2 = mid + 1, end2 = end;
merge_sort_recursive(arr, result, start1, end1);
merge_sort_recursive(arr, result, start2, end2);
int k = start;
while (start1
迭代版：
public static void merge_sort(int arr) {
int orderedArr = new intarr.length;
for (int i = 2; i = arr.length ? (arr.length - 1) : (left + i / 2);
int right = i * (j + 1) - 1 >= arr.length ? (arr.length - 1) : (i * (j + 1) - 1);
int start = left, l = left, m = mid;
while (l
===PHP===
function merge_sort($arr) {
$len = count($arr);
if ($len >1) + ($len & 1);
$arr2d = array_chunk($arr, $half);
$left = merge_sort($arr2d0);
$right = merge_sort($arr2d1);
while (count($left) && count($right))
if ($left0
===Python3===
def mergeSort(nums):
if len(nums)
===Erlang===
%% @doc 归并排序
g_sort() ->
;
g_sort(T) ->
T;
g_sort(L) ->
g_sort(L, length(L)).
g_sort( _ = L, Length) ->
SplitNum = trunc(Length / 2),
{L1, L2} = lists:split(SplitNum, L),
g_merge(g_sort(L1, SplitNum), g_sort(L2, Length - SplitNum));
g_sort(L, _Length) ->
L.
%% 已经排好序的两个list合并
g_merge(, L2) ->
L2;
g_merge(L1, ) ->
L1;
g_merge( Rest1 = L1,  Rest2 = L2) ->
if
T1 =  g_merge(Rest1, L2);
true ->  g_merge(L1, Rest2)
end.
===Javascript===
递归法
function merge(left, right){
var result = ;
while(left.length > 0 && right.length > 0){
if(left0 迭代法
===Go===
package main
import (
"fmt"
"sort"
)
func MergeSort(list int) int {
var length = len(list)
if length
递归版
package main
import (
"fmt"
)
func merge(data int) int {
sum := len(data)
if sum = 2 {
left = merge(left)
}
right := datasum/2:
rSize := len(right)
if rSize >= 2 {
right = merge(right)
}
j := 0
t := 0
arr := make(int, sum)
fmt.Println(left, right, data)
for i := 0; i = lSize{
arri = rightt
t++
}  else if t >= rSize{
arri = leftj
j++
}
}
return arr
}
func main() {
var aa = int{1000, 2, 31, 34, 5, 9, 7, 4, 6, 89, 90, 99, 99, 99, 99, 99}
var bb = merge(aa)
fmt.Println(bb)
}
== 算法复杂度 ==
比较操作的次数介于和。
赋值操作的次数是。归并算法的空间复杂度为：
== 参考文献 ==
==外部连结==
*  Dictionary of Algorithms and Data Structures: Merge sort date=20050307155740
*  Merge sort Algorithm with example program date=20190520050043
*  Merge Sort Algorithm Simulation
*  Mergesort For Linked Lists date=20050406031702
*  Mergesort in Java, Python, Perl, C, Ruby