算法与数据结构算法高薪算法+计算机职称考试

归并排序 merge sort

2019-03-12  本文已影响10人  1江春水

归并排序

时间复杂度:平均、最好、最坏都是O(nlogn)
空间复杂度:O(n)
稳定性:稳定

算法解析

算法描述(来源于百度)

归并操作的工作原理如下:

图片解析:


merge.jpg

上图已经很清楚了解释了归并排序的步骤及思路!如果还觉得不清晰,看下动画演示。

动画演示:


mergeSort.gif

一、从上到下的方式实现

c实现
void mergeSort(int *arr,int s,int mid,int e) {
    int *tmp = (int *)malloc((e-s+1)*sizeof(int));
    int i = s;
    int j = mid+1;
    int k = 0;
    while (i<=mid && j<=e) {
        if (arr[i] < arr[j]) {
            tmp[k++] = arr[i++];
        } else {
            tmp[k++] = arr[j++];
        }
    }
    while (i<=mid) {
        tmp[k++] = arr[i++];
    }
    while (j<=e) {
        tmp[k++] = arr[j++];
    }
    for (int l = 0; l<k; l++) {
        arr[l+s] = tmp[l];
    }
    free(tmp);
    tmp = NULL;
}

void merge(int *arr,int s,int e) {
    if (arr == NULL || s >= e) { return; }
    int mid = (s+e)/2;
    merge(arr, s, mid);
    merge(arr, mid+1, e);
    mergeSort(arr, s, mid, e);
}
OC实现
void mergeSort(NSMutableArray *arr,int s,int mid,int e) {
    NSMutableArray *arrM = [NSMutableArray array];
    int i = s;
    int j = mid + 1;
    while (i<=mid && j <= e) {
        if ([arr[i] intValue] <= [arr[j] intValue]) {
            [arrM addObject:arr[i++]];
        } else {
            //k+=(mid-i+1);逆序数
            [arrM addObject:arr[j++]];
        }
    }
    
    while (i<=mid) {
        [arrM addObject:arr[i++]];
    }
    while (j<=e) {
        [arrM addObject:arr[j++]];
    }
    for (int k = 0; k<arrM.count; k++) {
        arr[k+s] = arrM[k];
    }
}

void merge(NSMutableArray *arr,int s,int e) {
    if (s >= e) { return; }
    int mid = (s+e)/2;
    merge(arr, s, mid);
    merge(arr, mid+1, e);
    mergeSort(arr, s, mid, e);
}
Swift实现
func mergeSort(arr:inout [Int],start:Int,end:Int) -> Void {
    if arr.count == 0 || start >= end { return }
    let mid = (start+end)/2;
    mergeSort(arr: &arr, start: start, end: mid)
    mergeSort(arr: &arr, start: mid+1, end: end)
    //归并
    merge(arr: &arr, start: start, mid: mid, end: end)
}

func merge(arr:inout [Int],start:Int,mid:Int,end:Int) -> Void {
    if arr.count == 0 || start >= end { return }
    var tmp = Array.init(repeating: 0, count: end-start+1)
    var i = start
    var j = mid+1
    var k = 0
    while i <= mid && j <= end {
        if arr[i] <= arr[j] {
            tmp[k] = arr[i]
            i+=1
        } else {
            tmp[k] = arr[j]
            j+=1
        }
        k+=1
    }
    //把剩余的加进来
    while i<=mid {
        tmp[k] = arr[i]
        i+=1
        k+=1
    }
    while j<=end {
        tmp[k] = arr[j]
        j+=1
        k+=1
    }
    for l in 0..<k {
        arr[l+start] = tmp[l]
    }
}

以下实现均来源于网络,未验证

js实现
function mergeSort(arr) {  // 采用自上而下的递归方法
    var len = arr.length;
    if(len < 2) {
        return arr;
    }
    var middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right)
{
    var result = [];

    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }

    while (left.length)
        result.push(left.shift());

    while (right.length)
        result.push(right.shift());

    return result;
}
Python 代码实现
def mergeSort(arr):
    import math
    if(len(arr)<2):
        return arr
    middle = math.floor(len(arr)/2)
    left, right = arr[0:middle], arr[middle:]
    return merge(mergeSort(left), mergeSort(right))

def merge(left,right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0));
        else:
            result.append(right.pop(0));
    while left:
        result.append(left.pop(0));
    while right:
        result.append(right.pop(0));
    return result
go实现
func mergeSort(arr []int) []int {
    length := len(arr)
    if length < 2 {
        return arr
    }
    middle := length / 2
    left := arr[0:middle]
    right := arr[middle:]
    return merge(mergeSort(left), mergeSort(right))
}

func merge(left []int, right []int) []int {
    var result []int
    for len(left) != 0 && len(right) != 0 {
        if left[0] <= right[0] {
            result = append(result, left[0])
            left = left[1:]
        } else {
            result = append(result, right[0])
            right = right[1:]
        }
    }

    for len(left) != 0 {
        result = append(result, left[0])
        left = left[1:]
    }

    for len(right) != 0 {
        result = append(result, right[0])
        right = right[1:]
    }

    return result
}
Java 代码实现
public class MergeSort implements IArraySort {

    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        if (arr.length < 2) {
            return arr;
        }
        int middle = (int) Math.floor(arr.length / 2);

        int[] left = Arrays.copyOfRange(arr, 0, middle);
        int[] right = Arrays.copyOfRange(arr, middle, arr.length);

        return merge(sort(left), sort(right));
    }

    protected int[] merge(int[] left, int[] right) {
        int[] result = new int[left.length + right.length];
        int i = 0;
        while (left.length > 0 && right.length > 0) {
            if (left[0] <= right[0]) {
                result[i++] = left[0];
                left = Arrays.copyOfRange(left, 1, left.length);
            } else {
                result[i++] = right[0];
                right = Arrays.copyOfRange(right, 1, right.length);
            }
        }

        while (left.length > 0) {
            result[i++] = left[0];
            left = Arrays.copyOfRange(left, 1, left.length);
        }

        while (right.length > 0) {
            result[i++] = right[0];
            right = Arrays.copyOfRange(right, 1, right.length);
        }
        return result;
    }
}
PHP 代码实现
function mergeSort($arr)
{
    $len = count($arr);
    if ($len < 2) {
        return $arr;
    }
    $middle = floor($len / 2);
    $left = array_slice($arr, 0, $middle);
    $right = array_slice($arr, $middle);
    return merge(mergeSort($left), mergeSort($right));
}

function merge($left, $right)
{
    $result = [];

    while (count($left) > 0 && count($right) > 0) {
        if ($left[0] <= $right[0]) {
            $result[] = array_shift($left);
        } else {
            $result[] = array_shift($right);
        }
    }

    while (count($left))
        $result[] = array_shift($left);

    while (count($right))
        $result[] = array_shift($right);
    return $result;
}
上一篇 下一篇

猜你喜欢

热点阅读