此处C语言参考王道书,此外结合Go语言,一起理解

    “归并”的含义是将两个或者两个以上的有序表组合成一个新表,以下的例子都是二路归并为例子。

    Go 归并排序

    话不多少,先看Go语言版本的参考代码:

    1. package main
    2. import (
    3. "fmt"
    4. )
    5. func main() {
    6. s := []int{6, 7, 8, 10, 4, 6, 99}
    7. res := mergeSort(s)
    8. fmt.Println(res)
    9. }
    10. func mergeSort(s []int) []int {
    11. len := len(s)
    12. if len == 1 {
    13. return s //最后切割只剩下一个元素
    14. }
    15. m := len / 2
    16. leftS := mergeSort(s[:m])
    17. rightS := mergeSort(s[m:])
    18. return merge(leftS, rightS)
    19. }
    20. //把两个有序切片合并成一个有序切片
    21. func merge(l []int, r []int) []int {
    22. lLen := len(l)
    23. rLen := len(r)
    24. res := make([]int, 0)
    25. lIndex, rIndex := 0, 0 //两个切片的下标,插入一个数据,下标加一
    26. for lIndex < lLen && rIndex < rLen {
    27. if l[lIndex] > r[rIndex] {
    28. res = append(res, r[rIndex])
    29. rIndex++
    30. } else {
    31. res = append(res, l[lIndex])
    32. lIndex++
    33. }
    34. }
    35. if lIndex < lLen { //左边的还有剩余元素
    36. res = append(res, l[lIndex:]...)
    37. }
    38. if rIndex < rLen {
    39. res = append(res, r[rIndex:]...)
    40. }
    41. return res
    42. }

    代码还是很容易理解的,接下来看C语言版的。

    C语言版归并排序

    C语言由于没有来计算数组长度很好的函数,一般要标定数组的起始与结束的下标。
    已下参考王道书,

    ElemType *B = (Elmetype *)malloc((n+1)*sizeof(Elemtype));// 辅助数组 空间复杂度:O(n)
    // 合并左右子列
    void Merge(Elemtype A[],int low,int mid,int high)
    {    int k;
        // 将数组B赋值
        for (int i = low ;i <= high;i++)
            B[i] = A[i];
        // B的左右子列比较,覆盖对应的A的位置
        for(int i = low,j = mid+1,k = i;i<=mid&&j<=high;k++)
    
            {if(B[i] > B[j])
                    A[k] = B[j++];
              else
                    A[k] = B[i++];
            }
        // 以上完成对于A的初步排序,若此时还有i或者j未到达最右端
        while(i<=mid) A[k++] = B[i++];
        while(j<=high) A[k++] = B[j++];    
    
        // 设置k是为了完善A的排序
    
    }
    // 递归深度logn,每趟的归并O(n),时间复杂度O(nlogn)
    void MergeSort(Elemtype A[],int low,int high)
    {
        if(low < high)
        {    int mid = (low+high)/2;
            MergeSort(A,low,mid);
            MergeSort(A,mid+1,high);
            Merge(A,low,mid,hign);   // 归并
        }
    
    }