您的位置:首页 > 其它

归并排序与逆序对问题

2007-10-05 23:26 393 查看
转眼间国庆节就差不多过完了.明天又要回实验室坐班了.前些天一个高中同学到武汉来玩了两天,三年不见,还是高中时的那幅模样, 当然对她来说我也没有什么变化.而当初没上大学提前进入社会的同学则完全是挺一幅景象,应该感谢我的大学,让我们多保持了几年的纯真.

言归正转. 买了几天的算法导论一直没有时间看.今天终于把前两章啃完了,复习了一下合并排序/归并排序.在这里帖一下我实现的源码.顺便解一下第二章习题中的逆序对问题:

一.归并排序.

因为突然想和O(n*n)的算法做一下效率的对比,所以又加了一个冒泡,用了N=100,000 的倒序数组做测试.归并用时 17ms. 冒泡用时 34,328 ms.

//=================================================
// bottom up sort test
//=================================================
#include<windows.h>
#include<iostream>
using namespace std;

const int MAX=100000;

int MERGE(int *a,int p,int q,int r)
{
int *b=new int[r-p+1];
int s,t,k;
s=p;t=q+1;k=0;

while(s<=q && t<=r)
{
if (a[s]<=a[t])
{
b[k++]=a[s];
s++;
}

else
{
b[k++]=a[t];
t++;
}
}

while(s<=q)
{
b[k++]=a[s++];
}
while(t<=r)
{
b[k++]=a[t++];
}

for(int i=0;i<r-p+1;i++)
{
a[i+p]=b[i];
}
return 0;
}

int main()
{

int a[MAX];
int t,s;
long t1,t2;
for(int i=0;i<MAX;i++)
a[i]=MAX-i;

//bottom up sort ----------------------------------
t1=GetTickCount();
cout<<"Bottom up sort is running..."<<endl;
t=1;
while (t<MAX)
{
s=t;t=2*s;i=0;
while ((i+t)<MAX)
{
MERGE(a,i,i+s-1,i+t-1);
i+=t;
}

if(i+s<MAX)
MERGE(a,i,i+s-1,MAX-1);
}
t2=GetTickCount();
//for(i=0;i<MAX;i++)
//cout<<a[i]<<endl;
cout<<"Bottom up sort complete!"<<endl;
cout<<"used time: "<<t2-t1<<" ms"<<endl<<endl;
//bootom up sort complete--------------------------

//bubble sort--------------------------------------
t1=GetTickCount();
cout<<"bubble sort is running..."<<endl;
int temp;
for(i=0;i<MAX-1;i++)
for(int j=i+1;j<MAX;j++)
{
if(a[i]<a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}

}

t2=GetTickCount();
cout<<"bubble sort complete!"<<endl;
cout<<"used time: "<<t2-t1<<" ms"<<endl;

//bubble sort complete-----------------------------

return 0;
}

//quicksort-----------------------------------------
int Quicksort()
{
//to be continued...
return 0;
}
//quicksort complete--------------------------------

int HeapSort()
{
//to be continued...
return 0;
}

二.寻找逆序对问题.

根据书上的提示,只用对合并排序的MERGE函数做一下小修改即可得出O(n* lg n) 的算法. 定义一个变量 g_count 用来计数,在int MERGE(int *a,int p,int q,int r) 加入一行代码即可:

int MERGE(int *a,int p,int q,int r)
{
int *b=new int[r-p+1];
int s,t,k;
s=p;t=q+1;k=0;

while(s<=q && t<=r)
{
if (a[s]<=a[t])
{
b[k++]=a[s];
s++;
}

else
{
b[k++]=a[t];
t++;
g_count+=q-s+1;
}
}

while(s<=q)
{
b[k++]=a[s++];
}
while(t<=r)
{
b[k++]=a[t++];
}

for(int i=0;i<r-p+1;i++)
{
a[i+p]=b[i];
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: