zoukankan      html  css  js  c++  java
  • 归并排序+典型例题(逆序对)

    归并排序用的是分治的思想。分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。

    这里的归并排序就是将一个序列分成多个序列,可分成每个序列只有一个元素,然后将挨着的两个区间的元素进行对比,然后排序。

    我们可以用递归来完成这个分区间的步骤,直至每个区间只有一个元素,将左右区间的每个元素进行比较,较小的存放进辅助数组。

    大致步骤:(记作左区间的指针为i,右区间的指针为j)

    1:建立辅助数组。

    2:分区间(递归完成)

    3:比较左右区间的的第一个值,如果左区间的较小,存入辅助数组,i++,如果右区间的数较小,存入辅助数组,j++,直到i=mid或者j=end。

    4:将左区间或者右区间剩余的数存入到辅助数组中去(由于到了i=mid||j=mid的时候我们就不在比较了,所以会存在左区间的数或者右区间的数没有全部存入辅助数组中去。)

    5:将辅助数组中的数存入原数组中去。

    图解:

    由图我们可以看到起始数组为:{80,30,60,40,20,10,,50,70},

    经过分解之后我们分成了8个数组:{80},{30},{60},{40},{20},{10},{50},{70}。

    分解之后自然要合并:

    第一步我们可以看到都是单个元素在比较大小,小的先存入到辅助数组。

    第二步就是两个区间在进行比较了,就要之前将到的比较大小的方法来讲区间中的每个数存入到辅助数组中去。

    代码:

    #include<iostream>
    using namespace std;
    int B[100000];//辅助数组 
    void m_sort(int A[],int start,int end)
    {
        if(start==end) return ;
        int mid=(start+end)/2;
        m_sort(A,start,mid);//分左边区间 
        m_sort(A,mid+1,end);//分右边区间 
        int i=start,j=mid+1,k=start;
        while(i<=mid&&j<=end)//左右区间的数作比较,较小的放在辅助数组的前面 
        {
            if(A[i]<=A[j])  
            {
                B[k]=A[i];
                k++;
                i++;
            }
            else 
            {
                B[k]=A[j];
                j++;
                k++;
            }    
        }
        while(i<=mid)//将左边剩余的放在辅助数组 
            {
                B[k]=A[i];
                i++;
                k++;
            }
            while(j<=end)//将右边区间剩余的放在辅助数组 
            {
                B[k]=A[j];
                k++;
                j++;
            }
            for(int t=start;t<=end;t++)//存放进A数组 
               A[t]=B[t];    
    }
    int main()
    {
        int n;
        cin>>n;
        int A[n];
        for(int i=0;i<n;i++)
          cin>>A[i];
        m_sort(A,0,n-1);
        for(int i=0;i<n;i++)
          cout<<A[i]<<" ";
         return 0; 
    }

     逆序对例题:

    题目链接:https://www.luogu.org/problem/P1908

    代码:

    #include<iostream>
    using namespace std;
    int B[1000000];
    long long ans=0;
    void m_sort(int A[],int s,int t)
    {
        if(s==t) return ;
        int mid=(s+t)/2;
        m_sort(A,s,mid);
        m_sort(A,mid+1,t);
        int i=s,j=mid+1;
        int k=s;
        while(i<=mid&&j<=t)
        {
            if(A[i]<=A[j])
            {
                B[k]=A[i];
                i++;
                k++;
            }
            else 
            {
                ans+=mid+1-i;//在此找逆序对, 
                B[k]=A[j];
                j++;
                k++;
            }
        }
        while(i<=mid)
        {
            B[k]=A[i];
            i++;
            k++;
        }
        while(j<=t)
        {
            B[k]=A[j];
            j++;
            k++;
        }
        for(int i=s;i<=t;i++)
        {
            A[i]=B[i];
         } 
    }
    int main()
    {
        int n;
        cin>>n;
        int A[n];
        for(int i=0;i<n;i++)
          cin>>A[i];
        m_sort(A,0,n-1);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    27 Spring Cloud Feign整合Hystrix实现容错处理
    26 Spring Cloud使用Hystrix实现容错处理
    25 Spring Cloud Hystrix缓存与合并请求
    24 Spring Cloud Hystrix资源隔离策略(线程、信号量)
    23 Spring Cloud Hystrix(熔断器)介绍及使用
    22 Spring Cloud Feign的自定义配置及使用
    21 Spring Cloud使用Feign调用服务接口
    20 Spring Cloud Ribbon配置详解
    19 Spring Cloud Ribbon自定义负载均衡策略
    18 Spring Cloud Ribbon负载均衡策略介绍
  • 原文地址:https://www.cnblogs.com/zhoubo123/p/11403581.html
Copyright © 2011-2022 走看看