zoukankan      html  css  js  c++  java
  • [经典算法] 归并排序

    题目说明:

    归并排序是建立在归并操作上的一种有效的排序算法。该算法也是采用分治法(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;
    }

    运行结果:

    image

    参考引用:

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

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

    Book167  看书、学习、写代码
  • 相关阅读:
    C# Xamarin For Android自动升级项目实战
    C# Xamarin移动开发基础进修篇
    .NET轻量级ORM框架Dapper入门精通
    ASP.NET WebApi技术从入门到实战演练
    (简单、可靠的安装方法)在Windows Server2016中安装SQL Server2016
    ASP.NET (Core) WebAPI IIS PUT和DELETE请求失败 405的解决办法
    js中判断对象是否为空的三种实现方法
    windows10如何设置只显示时间不显示日期
    NuGet微软官方中国国内镜像
    Win10找不到hosts文件解决方法
  • 原文地址:https://www.cnblogs.com/Quincy/p/4992517.html
Copyright © 2011-2022 走看看