zoukankan      html  css  js  c++  java
  • 归并排序(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

  • 相关阅读:
    DAY21
    DAY20
    DAY19
    @Autowired注解和静态方法
    PageHelper.startPage和new PageInfo(list)的一些探索和思考
    escape()、encodeURI()、encodeURIComponent()区别详解
    每日日报29
    1dialog 表单最基本的封装
    mongoose
    数组
  • 原文地址:https://www.cnblogs.com/programnote/p/4723564.html
Copyright © 2011-2022 走看看