您的位置:首页 > 其它

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

2015-05-02 19:33 465 查看
二路归并排序代码如下。

#include <iostream>
using namespace std;
//二路排序算法,书p17 正确性证明见p18-19
void 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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: