归并排序

归并排序（Merge sort，或mergesort），是建立在归并操作上的一种有效的排序算法，效率为formula_1（大O符号）。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法（Divide and Conquer）的一个非常典型的应用，且各层分治递归可以同时进行。
概述.
采用分治法:
归并操作.
归并操作（merge），也叫归并算法，指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
迭代法（Bottom-up）.
原理如下（假设序列共有formula_2个元素）：
实作范例.
C语言.
迭代版：
<syntaxhighlight lang=c>
int min(int x, int y) {
void merge_sort(int arr[], int len) {
递归版：
<syntaxhighlight lang=c>
// 分治-治
void mergeSort_conquer(int* array, int left, int mid, int right, int* temp) {
// 分治-分
void mergeSort_divide(int* array, int left, int right, int* temp) {
void mergeSort(int* array, int size) {
</syntaxhighlight>
C++.
迭代版：
<syntaxhighlight lang=cpp>
template<typename T> // 整数或浮点数皆可使用,若要使用物件(class)时必须设定"小于"(<)的运算子功能
void merge_sort(T arr[], int len) {
递归版：
<syntaxhighlight lang="cpp">
void Merge(vector<int> &Array, int front, int mid, int end) {
void MergeSort(vector<int> &Array, int front, int end) {
</syntaxhighlight>
C#.
<syntaxhighlight lang=csharp>
public static List<int> sort(List<int> lst) {
/// <summary>
/// 合并两个已经排好序的List
/// </summary>
/// <param name="left">左侧List</param>
/// <param name="right">右侧List</param>
/// <returns></returns>
static List<int> merge(List<int> left, List<int> right) {
</syntaxhighlight>
Ruby.
<syntaxhighlight lang=ruby>
def merge list
end
</syntaxhighlight>
Java.
递归版：
<syntaxhighlight lang=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 <= end1 && start2 <= end2)
 result= arr[start1 < arr? arr[start1++ : arr[start2++];
 while (start1 <= end1)
 result= arr[start1++;
 while (start2 <= end2)
 result= arr[start2++;
 for (k = start; k <= end; k++)
 arr= result[k;
public static void merge_sort(int[] arr) {
 int len = arr.length;
 int[] result = new int;
 merge_sort_recursive(arr, result, 0, len - 1);
</syntaxhighlight>
迭代版：
<syntaxhighlight lang=java>
public static void merge_sort(int[] arr) {
 int[] orderedArr = new int[arr.length];
 for (int i = 2; i < arr.length * 2; i *= 2) {
 for (int j = 0; j < (arr.length + i - 1) / i; j++) {
 int left = i * j;
 int mid = left + i / 2 >= 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 < mid && m <= right) {
 if (arr< arr[m) {
 orderedArr= arr[l++;
 } else {
 orderedArr= arr[m++;
 while (l < mid)
 orderedArr= arr[l++;
 while (m <= right)
 orderedArr= arr[m++;
 System.arraycopy(orderedArr, left, arr, left, right - left + 1);
</syntaxhighlight>
PHP.
<syntaxhighlight lang="php">
function merge_sort($arr) {
 $len = count($arr);
 if ($len <= 1)
 return $arr;
 $half = ($lenÂ»1) + ($len & 1);
 $arr2d = array_chunk($arr, $half);
 $left = merge_sort($arr2d);
 $right = merge_sort($arr2d);
 while (count($left) && count($right))
 if ($left< $right[0)
 $reg[] = array_shift($left);
 else
 $reg[] = array_shift($right);
 return array_merge($reg, $left, $right);
$arr = array(21, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70);
$arr = merge_sort($arr);
for ($i = 0; $i < count($arr); $i++) {
 echo $arr[$i] . ' ';
</syntaxhighlight>
Python3.
<syntaxhighlight lang=python>
def mergeSort(nums):
if __name__ == "__main__":
</syntaxhighlight>
Erlang.
<syntaxhighlight lang="erlang">
%% @doc 归并排序
g_sort([]) ->
g_sort() ->
g_sort(L) ->
g_sort(_ | _ = L, Length) ->
g_sort(L, _Length) ->
%% 已经排好序的两个list合并
g_merge([], L2) ->
g_merge(L1, []) ->
g_merge(| Rest1 = L1, | Rest2 = L2) ->
</syntaxhighlight>
Javascript.
递归法<syntaxhighlight lang=javascript>
function merge(left, right){
function mergeSort(arr){
</syntaxhighlight>迭代法
Go.
<syntaxhighlight lang="go">
package main
import (
 "fmt"
 "sort"
func MergeSort(list []int) []int {
 var length = len(list)
 if length < 2 {
 return list
 var mid = length / 2
 return merge(MergeSort(list[:mid]), MergeSort(list[mid:]))
func merge(x, y []int) []int {
 var r []int = make([]int, len(x)+len(y))
 for i, j := 0, 0; ; {
 if i < len(x) && (j == len(y) || x< y[j) {
 r= x[i
 i++
 } else if j < len(y) {
 r= y[j
 j++
 } else {
 break
 return r
func main() {
 fmt.Println(MergeSort(list))
 fmt.Println(list)
 sort.Ints(list)
 fmt.Println(list)
</syntaxhighlight>
递归版
<syntaxhighlight lang="go">
package main
import (
 "fmt"
func merge(data []int) []int {
 sum := len(data)
 if sum <= 1 {
 return data
 left := data: sum/2
 lSize := len(left)
 if lSize >= 2 {
 left = merge(left)
 right := data[sum/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 < sum; i++ {
 if j < lSize && t < rSize {
 if left<= right[t {
 arr= left[j
 j++
 } else {
 arr= right[t
 t++
 } else if j >= lSize{
 arr= right[t
 t++
 } else if t >= rSize{
 arr= left[j
 j++
 return arr
func main() {
 var bb = merge(aa)
 fmt.Println(bb)
</syntaxhighlight>
算法复杂度.
比较操作的次数介于formula_5和formula_6。
赋值操作的次数是formula_7。归并算法的空间复杂度为：formula_8