归并排序

归并排序(Merging Sort)就是利用归并的思想来实现的排序方法。它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,再两两归并,... ,如此反复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。

 

核心代码(C实现)

void Merge(int arr[], int low, int high)
{
    int begin1;
    int end1;
    int begin2;
    int end2;
    int i;
    int * pTemp = NULL;

    if ((NULL == arr) || (low >= high)) {
        return;
    }

    pTemp = (int *)malloc(sizeof(int)*(high-low+1));
    begin1 = low;
    end1 = (low+high)/2;
    begin2 = end1+1;
    end2 = high;

    i = 0;
    while(begin1<=end1 && begin2<=end2)
    {
        if(arr[begin1]<arr[begin2])
        {
            pTemp[i] = arr[begin1];
            ++begin1;
        }
        else
        {
            pTemp[i] = arr[begin2];
            ++begin2;
        }
        ++i;
    }

    //将剩余元素放入数组
    while(begin1 <= end1)
    {
        pTemp[i] = arr[begin1];
        ++begin1;
        ++i;
    }

    while(begin2 <= end2)
    {
        pTemp[i] = arr[begin2];
        ++begin2;
        ++i;
    }

    //元素放回原数组
    for(i=0; i<high-low+1; ++i)
    {
        arr[low+i] = pTemp[i];
    }

    free(pTemp);
    pTemp = NULL;
}

void MergeSort(int arr[], int low, int high)
{
    int mid;

    if ((NULL == arr) || (low >= high)) {
        return;
    }

    mid = (low+high)/2;

    //先拆分
    MergeSort(arr, low, mid);
    MergeSort(arr, mid+1, high);

    //合并
    Merge(arr, low, high);
}

 核心代码(C++实现)

#include <iostream>

template <typename T>
void merge(T array[], int low, int high)
{
    if ((NULL == array) || low >= high) {
        return;
    }

    int* pTempArr = new int[high-low+1];
    int begin1 = low;
    int end1 = (low + high)/2;
    int begin2 = end1 + 1;
    int end2 = high;

    int index = 0;
    while ((begin1 <= end1) && (begin2 <= end2))
    {
        if (array[begin1] < array[begin2]) {
            pTempArr[index] = array[begin1];
            ++begin1;
        }
        else {
            pTempArr[index] = array[begin2];
            ++begin2;
        }
        ++index;
    }

    while (begin1 <= end1)
    {
        pTempArr[index] = array[begin1];
        ++begin1;
        ++index;
    }

    while (begin2 <= end2)
    {
        pTempArr[index] = array[begin2];
        ++begin2;
        ++index;
    }

    int length = high-low+1;
    for (index = 0; index < length; ++index)
    {
        array[low+index] = pTempArr[index];
    }

    if (pTempArr != NULL) {
        delete pTempArr;
        pTempArr = NULL;
    }
}

void mergeSort(int array[], int low, int high)
{
    if ((NULL == array) || (low >= high)) {
        return;
    }

    int mid = (low + high)/2;

    mergeSort(array, low, mid);
    mergeSort(array, mid+1, high);

    merge(array, low, high);
}

#if 0
void mergeSort(arr, 0, 8)
{
    mid = 4;
    mergeSort(arr, 0, 4)
    {
        mergeSort(arr, 0, 2)
        {
            mergeSort(arr, 0, 1)
            {
                mergeSort(arr, 0, 0)
                {
                    return; // 100
                }
                mergeSort(arr, 1, 1)
                {
                    return; // 2
                }

                merge(); // 2, 100
            }
            mergeSort(arr, 2, 2)
            {
                return; // 32
            }

            merge(); // 2, 32, 100
        }
        mergeSort(arr, 3, 4)
        {
            mergeSort(arr, 3, 3)
            {
                return; // 66
            }
            mergeSort(arr, 4, 4)
            {
                return; // 78
            }

            merge(); // 66, 78
        }

        merge(); // 2, 32, 66, 78, 100
    }
    mergeSort(arr, 5, 8)
    {
        mergeSort(arr, 5, 6)
        {
            mergeSort(arr, 5, 5)
            {
                return; // 500
            }
            mergeSort(arr, 6, 6)
            {
                return; // -23
            }

            merge(); // -23, 500
        }
        mergeSort(arr, 7, 8)
        {
            mergeSort(arr, 7, 7)
            {
                return; // -98
            }
            mergeSort(arr, 8, 8)
            {
                return; // 123
            }

            merge(); // -98, 123
        }

        merge(); // -98, -23, 123, 500
    }

    merge(); // -98, -23, 2, 32, 66, 78, 100, 123, 500
}
#endif

void print(int array[], int length)
{
    if ((NULL == array) || length < 1) {
        return;
    }

    for (int index = 0; index < length; ++index)
    {
        std::cout << array[index] << " ";
    }
}

int main()
{
    int arr[] = { 100, 2, 32, 66, 78, 500, -23, -98, 123 };
    int len = sizeof(arr)/sizeof(arr[0]);
    mergeSort(arr, 0, len-1);
    print(arr, len);
    std::cout << std::endl;

    return 0;
}

算法分析:

  最好时间复杂度:O(nlog2(n))

  平均时间复杂度:O(nlog2(n))

  最坏时间复杂度:O(nlog2(n))

    空间复杂度:O(n+log2(n))

      稳定性:稳定

posted @ 2017-10-17 22:12  c&z  阅读(202)  评论(0编辑  收藏  举报