归并排序与逆序对问题

原创 2007年10月05日 23:26:00

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

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

一.归并排序.

         因为突然想和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<=&& 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<=&& 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;
}

 

 

归并排序,树状数组 两种方法求逆序对

我们知道,求逆序对最典型的方法就是树状数组,但是还有一种方法就是Merge_sort(),即归并排序。 实际上归并排序的交换次数就是这个数组的逆序对个数,为什么呢? 我们可以这样考虑:...
  • ACM_10000h
  • ACM_10000h
  • 2015年08月24日 21:42
  • 2107

【hihocoder】1141 : 二分·归并排序之逆序对

题目链接:http://hihocoder.com/problemset/problem/1141 题目: 我们可以看到,船默认排序是以等级为参数。但实际上一个船的火力值和等级的关系并不大,所...
  • yeqiuzs
  • yeqiuzs
  • 2016年09月16日 19:37
  • 911

归并排序及利用归并排序求逆序对数

#include #include #include #include #include using namespace std; /* 用归并排序顺便完成统计逆序对数。 因为合并操作是从小...
  • Ramay7
  • Ramay7
  • 2016年02月27日 14:53
  • 253

hdu1394(暴力/线段树/归并排序求逆序对的个数)

题目链接:Minimum Inversion Number 题目大意
  • pmt123456
  • pmt123456
  • 2017年02月18日 00:08
  • 376

如何运用归并排序快速求得逆序对数目

逆序对数目可以直接穷举,但效率很低,O(n^2)级别. 可以用树状数组写. 这里介绍运用归并排序来求逆序对数目.归并排序过程中,针对两个内部有序的串, 实现插入排序,即两串开头的元素,小的进入目...
  • pku_Coder
  • pku_Coder
  • 2016年12月08日 03:12
  • 502

逆序对 (归并排序)

逆序对的nlogn方法,改进后的归并排序 给定排列P,求排列的逆序对数量。 P的长度 要求O(nlogn) 定义归并排序过程Merge(l,r) Merge(l,r) Me...
  • csuhoward
  • csuhoward
  • 2015年07月31日 14:39
  • 450

hiho 39 二分·归并排序之逆序对

问题寻找逆序数 http://hihocoder.com/contest/hiho39/problem/1解法归并排序,复杂度o(nlogn)#include using namespace st...
  • galaxy_wolf
  • galaxy_wolf
  • 2016年04月20日 11:37
  • 97

洛谷Oj-逆序对-分治(归并排序)

问题描述: 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这...
  • suntengnb
  • suntengnb
  • 2017年06月05日 17:10
  • 274

hihocoder #1141 : 二分·归并排序之逆序对

#include #include #include #include #include #include #include #include #include using namespace std...
  • u014779110
  • u014779110
  • 2015年12月14日 17:04
  • 176

关于逆序对的两种做法(归并排序+树状数组c++)

这些天来测试的时候遇到了几次逆序对的题目,但没有太在意,已经跪了好几次了,所以今天打算学习总结一下逆序对的两种做法。 首先是归并排序 归并排序的模板 #include using namesp...
  • qq_32624861
  • qq_32624861
  • 2016年10月27日 20:31
  • 200
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:归并排序与逆序对问题
举报原因:
原因补充:

(最多只允许输入30个字)