归并排序

使用合并排序为一列数字进行排序的过程
归并排序（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