归并排序算法

归并排序算法

归并排序是一种典型的分治算法

  1. 分解:总是对排序区间内的元素以中点二分,分别对左右区间进行排序
  2. 解决:归并排序不断递归调用自己,分解到底层后,待排序区间缩减为2个元素的比较
  3. 合并:在递归分解的每一层上,都得到左右两边已经排序的子序列,需要将有序子序列合并到一个序列. 实质上 “解决”环节是在“合并”中一起完成的,因为分解到每组2个元素还可以继续分解成左右各1个元素,然后再逐层向上合并.
  4. 合并是本算法的难点,需要两个指示器来分别标识两个子序列进行当前排序的两个元素;此外本设计中在左右两个子序列后面增加了一个无穷大元素,以方便处理边界问题

代码实现

#include <iostream>
#include <string>
#include <vector>
#include <cfloat>
using namespace std;
void merge(vector<double> & A, int p, int q, int r)
{
    int nl = q-p+1;
    int nr = r-q;
    vector<double> al(nl+1), ar(nr+1);
    for( int i = 0; i<nl; ++i)
    {
        al[i] = A[p+i];
    }
    for (int j = 0; j<nr; ++j)
    {
        ar[j] = A[q+1+j];
    }
    al[nl] = DBL_MAX;
    ar[nr] = DBL_MAX;
    int i = 0;
    int j = 0;
    for (int k = p; k <= r; ++k)
    {
        if(al[i] <= ar[j])
        {
            A[k] = al[i];
            ++i;
        }
        else 
        {
            A[k] = ar[j];
            ++j;
        }
    }
}
void mergesort(vector<double> & A, int p, int r)
{ 
    if (p<r)
    {
        int q = (p+r)/2;
        for (int i=0; i<A.size(); ++i)
        {
            cout<<A[i]<<" ";
        }
        cout<<endl;
        mergesort(A, p, q);
        mergesort(A, q+1, r);
        merge(A, p, q, r);
    }
}
int main()
{
    double arr[] =  {10, 12, 5, 56, 28, 15, 68, 45, 98, 2, 73};
    vector<double> A(arr, arr+11);
    for (int i=0; i<A.size(); ++i)
    {
        cout<<A[i]<<endl;
    }
    int p=0;
    int r=A.size()-1;
    mergesort(A, p, r);
    for (int i=0; i<A.size(); ++i)
    {
        cout<<A[i]<<endl;
    }
    return 0;
}

复杂度分析

  1. 每次进行二分分解,长度为 n 的序列,最大层数为 lg(n) . 每层之中要合并的总元素个数为 n , 合并的复杂度为 Θ(n)
  2. 整个算法的时间复杂度为 Θ(nlg(n))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值