归并排序与逆序对问题

原创 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;
}

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

哈理工OJ 2224 逆序对问题(利用归并排序求逆序数对数)

题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2224逆序对问题 Time Limit:...

【算法】逆序对问题的四种解法(归并排序,BST,树状数组,线段树)及变形

引发我对逆序对这个问题思考的源自这道题:315. Count of Smaller Numbers After Self 以前我以为求一个序列逆序对个数的解法就是归并排序的改版

归并排序与逆序对问题---(解题报告)POJ1804---Brainman

归并排序,主要是以分治思想进行组合排序,先分再和,在和的过程中排序,排序的思路如下:先给你两组同向有序数组,首先判断两组数的首位的大小,并将较小的数保留到一个新数组中,接下来再比较较小组数的第二位和另...

归并排序&&数组中逆序对问题

题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如在数组{7,5,6,4}中,一共存在5个逆序对,分别是{7,5}、{...

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

#include using namespace std; //二路排序算法,书p17 正确性证明见p18-19 void merge(int *b,int p,int q,int r) ...

利用归并排序求逆序对

在逆序对的问题中,如果采用暴力求解的方法,一般也是有效的,但是O(n2)时间复杂度实在是难以接受的。但是对于逆序对问题,却有一个看似不想关的算法来解决–归并排序。时间复杂度和空间复杂度完全与归并排序一...

归并排序求逆序对

排序都用Qsort了,别的排序算法不怎么用,但有些排序的思想很重要。碰到一道求逆序对的题,要用到归并排序,学习了一下归并排序。 归并排序是用分治思想,分治模式在每一层递归上有三个步骤:  ...

归并排序求逆序对

转载自归并排序求逆序对详解 希望此大犇不要生气。 联赛之前发现自己好多都忘记了,于是开始方,于是开始到处乱搞,想起以前的离散化+归并排序求逆序对NOIP水题火柴排队现在都不会了,于是在网上狂找归并...

算法竞赛入门经典:第八章 高效算法设计 8.3归并排序应用之逆序对数

/* 逆序对数: 给出一列数a1,a2,...,an,求它的逆序对数,即有多少个有序对(i,j),使得iaj。n可以高达10^6 思路: 分解成前后两个序列,统计后序列中每个元素与前面中每个元素的逆...

归并排序-逆序对-hdu3743

归并排序方法:分治法 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。 解决:使用归并排序递归的排序两个子序列。 合并:合并两个已...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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