[经典算法] 归并排序

题目说明:

归并排序是建立在归并操作上的一种有效的排序算法。该算法也是采用分治法(Divide and Conquer)的一个非常典型的应用。算法复杂度为O(N*logN)。

 

题目解析:

归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列。

归并排序包括两个步骤:

1)划分子表

2)合并半子表 

 

伪代码:

合并排序伪代码(使用哨兵):
merge(A,p,q,r):
    n1 <—— q-p+1
    n2 <—— r-q
    create array L[0,n1] and R[0,n2]
    for i <—— 0 to n1-1
        do L[i] <—— A[p+i]
    for j <—— 0 to n2-1
        do R[j] <—— A[q+j+1]
    L[n1] <—— +∞
    R[n2] <—— +∞
    i <—— 0
    j <—— 0
    for k i <—— p to r
        do if L[i]<=R[j]
            then A[k]  <—— L[i]
                 i <—— i+1
           else A[k] <—— R[j]
                 j <—— j+1
 
//通过调用merge完成排序:
merge_sort(A,p,r):
    if p<r
       then q <—— [(p+r)/2] //向下取整
          merge_sort(A,p,q) //分治
          merge_sort(A,q+1,r)
          merge(A,p,q,r)    //合并结果

 

程序代码:

#include <gtest/gtest.h>
#include <algorithm>

using namespace std;

template<typename T>
void Merge(T* data, int low, int mid, int high)
{
    T* tmp = new T[high - low + 1];
    int i = low;
    int j = mid + 1;
    int k = 0;

    // 把较小的数先移到新数组中 
    while (i <= mid && j <= high)
    {
        if (data[i] < data[j])
        {
            tmp[k++] = data[i++];
        }
        else
        {
            tmp[k++] = data[j++];
        }
    }

    // 把左边剩余的数移入数组  
    while (i <= mid)
    {
        tmp[k++] = data[i++];
    }

    // 把右边边剩余的数移入数组
    while (j <= high)
    {
        tmp[k++] = data[j++];
    }

    // 把新数组中的数覆盖nums数组  
    for (int i = 0; i < k; ++i)
    {
        data[i+low] = tmp[i];
    }

    delete[] tmp;
}

template<typename T>
void MergeSort(T* data, int low, int high)
{
    if (low < high)
    {
        int mid = (low + high)/2;
        // 左边
        MergeSort(data, low, mid);
        // 右边 
        MergeSort(data, mid+1, high);
        // 左右归并
        Merge(data, low, mid, high);
    }
}

template<typename T>
static void ShowElem(T& val)
{
    cout << val << " ";
}

template<typename T>
static bool Validate(T* data, int len)
{
    for (int i=0; i < len-1; ++i)
    {
        if (data[i] > data[i+1])
        {
            return false;
        }
    }

    return true;
}

TEST(Algo, tMergeSort)
{
    int d1[] = {2,8,7,1,3,5,6,4};
    MergeSort(d1, 0, 7);
    for_each(d1, d1+8, ShowElem<int>);
    ASSERT_TRUE(Validate(d1,8));
    cout << endl;

    int d2[] = {2};
    MergeSort(d2, 0, 0);
    for_each(d2, d2+1, ShowElem<int>);
    ASSERT_TRUE(Validate(d2,1));
    cout << endl;

    int d3[] = {2,4,5,6,7,5,2,3,5,7,10,111,2,4,5,6,3,4,5};
    MergeSort(d3, 0, 18);
    for_each(d3, d3+19, ShowElem<int>);
    ASSERT_TRUE(Validate(d3,19));
    cout << endl;
}

 

运行结果:

[经典算法] 归并排序_第1张图片

 

参考引用:

http://www.cricode.com/2001.html

http://blog.csdn.net/middlekingt/article/details/8446552

 

Book167  看书、学习、写代码

你可能感兴趣的:([经典算法] 归并排序)