归并排序(Merge Sort)

归并排序是颇受欢迎的排序算法,因为他的时间复杂度恒为O(n log(n))。顾名思义,这个排序算法就是将多个排好序的数组合并成单个排好序的数组。

具体步骤如下:

  • 将待排序的数组分成左右两部分。
  • 再将这两部分分别分成左右两部分。
  • 一直分下去,直到不可分(每部分只有一个元素)。
  • 由于数组被分成许多的单个数据,比较起来就简单了,然后开始合并,合并的同时排序。
  • 持续合并直到得到排好序的数组。

下面这幅图可以帮助你理解算法过程:

merge_sort

上图中可以看到,算法将数组分为两个部分,然后再分,一直分到只有一个元素,然后合并成已排序的数组。

将两个已排序的数组合并成一个排序的数组的方法在前面已经讨论过了,不清楚的同学看一下

怎样合并排序数组(How to merge 2 sorted arrays?)

归并排序显然可以用分治法,算法如下:

# split in half
m = n / 2

# recursive sorts
sort a[1..m]
sort a[m+1..n]

# merge sorted sub-arrays using temp array
b = copy of a[1..m]
i = 1, j = m+1, k = 1
while i <= m and j <= n,
    a[k++] = (a[j] < b[i]) ? a[j++] : b[i++]
→ invariant: a[1..k] in final position
while i <= m,
    a[k++] = b[i++]
→ invariant: a[1..k] in final position

算法实现:

#include<stdio.h>
 
//defining a function to merge 2 sorted arrays
//note that the 2 arrays will be contained in a single array
//as the left and right part
void merge(int arr[], int start, int mid, int end)
{
    // the array is as:- {start, ... ..mid, mid+1, .....end}
    // thus there are 2 arrays we need to merge
 
    //1st array , starting index and last index
    int i = start;
    int l1 = mid;
 
    //2nd array , starting index and last index
    int j = mid+1;
    int l2 = end;
 
    //create an auxiliary array to store the elements
    int len = end-start + 1;
    int *arr2 = (int *)malloc(sizeof(int)*len);
    int k = 0;
 
    //apply the algorithm to merge 2 sorted arrays
    while(i<=l1 && j<=l2)
    {
        if(arr[i] < arr[j])
            arr2[k++] = arr[i++];
        else
            arr2[k++] = arr[j++];
    }
 
    while(i<=l1)
        arr2[k++] = arr[i++];
    while(j<=l2)
        arr2[k++] = arr[j++];
 
    //copy the auxiliary array to original array
    for(k = 0; k<len; k++)
        arr[start++] = arr2[k];
 
    //free the memory
    free(arr2);
}
 
// a function to perform merge sort on an array with the given
// starting and ending index
void performMergeSort(int arr[], int start, int end)
{
    if(start<end)
    {
        //to get the middle of the array
        int mid = start + (end - start) / 2;
 
        //recursively dividing the left and right parts
        performMergeSort(arr, start, mid);  /* left part */
        performMergeSort(arr, mid+1, end);  /* right part */
 
        //finally we need to merge them
        merge(arr, start, mid, end);
    }
}
 
//defining a function to perform merge sort on array arr[] of given size
void mergeSort(int arr[], int size)
{
    performMergeSort(arr, 0, size-1);
}
 
// driver function to test the above function
int main(void)
{
    int i;
    int arr[10] = {2, 6, 4, 10, 8, 1, 9, 5, 3, 7};
 
    mergeSort(arr,10);
 
    printf("SORTED array:- ");
    for(i=0;i<10;i++)
        printf("%d ",arr[i]);
 
    return 0;
}

Time Complexity: O(n log(n)) for all cases
Space Complexity: O(n) for the Sortauxiliary array

转载于:https://www.cnblogs.com/programnote/p/4723564.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值