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  看书、学习、写代码
  • 相关阅读:
    框架比较
    框架整理
    bootstrap-table中get请求携带的参数
    0514任务思路
    两台电脑对码云上面的项目进行迭代
    项目问题
    vue 中发送axios请求,解决跨域问题(没有config文件)
    正则表达式(未完待续)
    【转载】深入理解Linux文件系统
    浅谈IO优化
  • 原文地址:https://www.cnblogs.com/Quincy/p/4992517.html
Copyright © 2011-2022 走看看