【算法导论】2-2 二路归并排序(分治)merge-sort 和逆序对的问题

来源:互联网 发布:广告宣传语音制作软件 编辑:程序博客网 时间:2024/05/08 15:41

二路归并排序代码如下。

#include <iostream>using namespace std;//二路排序算法,书p17 正确性证明见p18-19void merge(int *b,int p,int q,int r)                    //归并程序,线性时间复杂度{    int i=0,j=0;    int L[18]={4,23,3,1,7,8,12,4,8,24,11,10,9,30,12,17,19,20};    int R[18]={4,23,3,1,7,8,12,4,8,24,11,10,9,30,12,17,19,20};    for (i=0;i<18;i++)    {        L[i]=1000;        R[i]=1000;    }    for (i=0;i<q-p+1;i++)        L[i]=b[p+i];    for(i=0;i<r-q;i++)        R[i]=b[q+i+1];    i=0;    int k=0;    for (k=p;k<=r;k++)    {        if (L[i]<=R[j])            {            b[k]=L[i];            i++;            }        else        {            b[k]=R[j];            j++;        }    }}void merge_sort(int* b,int p,int r)         //递归,Ologn{        int q=0;        if (p+1<r)    {        q=(p+r)/2;        merge_sort(b,p,q);        merge_sort(b,q+1,r);        merge(b,p,q,r);    }}int main(){    int b[18]={4,23,3,1,7,8,12,4,8,24,11,10,9,30,12,17,19,20};    merge_sort(b,0,17);    for (int ii=0;ii<18;ii++)        cout<<b[ii]<<' ';    cout<<endl;}/*测试输出如下:1 3 4 4 7 8 8 9 10 12 12 17 19 20 23 24 11 30*/

一组数的逆序对满足如下公式。
A(p,r)=A(p,q)+A(q,r)+s(A(p,q)+A(q,r))
A(m,n)表示从序列中第m到n个数的逆序数个数。s(A,B)表示A,B序列之间的逆序数对数。s(A,B)与A,B内部顺序无关。
由此可对原二路归并排序的代码进行微调。

#include <iostream>using namespace std;//二路归并求逆序数int merge(int *b,int p,int q,int r)                 //归并程序,线性时间复杂度{    int i=0,j=0;    int temp=0;                                     //temp即表示逆序数对数    int L[18]={4,23,3,1,7,8,12,4,8,24,11,10,9,30,12,17,19,20};    int R[18]={4,23,3,1,7,8,12,4,8,24,11,10,9,30,12,17,19,20};    for (i=0;i<18;i++)    {        L[i]=1000;        R[i]=1000;    }    for (i=0;i<q-p+1;i++)        L[i]=b[p+i];    for(i=0;i<r-q;i++)        R[i]=b[q+i+1];    i=0;    int k=0;    for (k=p;k<=r;k++)    {        if (L[i]<R[j])            {            b[k]=L[i];            i++;            temp=temp+j;                          //每次左边的数组记号移动的时候记录右边的编号累加            }        else        {            b[k]=R[j];            j++;        }    }    return temp;}int merge_sort(int* b,int p,int r)      //递归,Ologn{        int q=0;        if (p<r)    {        q=(p+r)/2;        return merge_sort(b,p,q)+merge_sort(b,q+1,r)+merge(b,p,q,r);    }        else return 0;}int main(){    int b[18]={4,23,3,1,7,8,12,4,8,24,11,10,9,30,12,17,19,20};    cout<<merge_sort(b,0,17);}
0 0