归并排序同时计算逆序对数

归并排序同时求逆序对数

c++11:

#include <iostream>
#include <algorithm>
#include <vector>
#include <initializer_list>
using namespace std;

vector<int> v({5,4,3,2,7,6});
int reverse_pairs=0;
void merge(vector<int> &v, int start, int step, vector<int> &temp){
	const int n=v.size();
	int s1=start;
	int e1=start+step;
	int s2=e1;
	int e2= s2+step<n ? s2+step : n;
	int i=start;
	while(s1<e1&&s2<e2){
		if(v[s1]<=v[s2]){
			temp[i]=v[s1];
			--step;//复用step,用于计算逆序数
			++s1;
		}
		else{
			temp[i]=v[s2];
			reverse_pairs+=step;
			++s2;
		}
		++i;
	}
	if(s1<e1){
		copy(v.begin()+s1,v.begin()+e1,temp.begin()+i);
	}
	if(s2<e2){
		copy(v.begin()+s2,v.begin()+e2,temp.begin()+i);
	}
}
void msort(vector<int> &v){
	reverse_pairs=0;
	const int n=v.size();
	vector<int> temp(n); //临时空间
	int step=1;
	for(;step<n;step*=2){
		int i=0;
		for(;i<n-step;i+=2*step){
			merge(v,i,step,temp);
		}
		if(i<n)
			copy(v.begin()+i, v.end(), temp.begin()+i);
		swap(v,temp);
	}
}

int main() {
	for_each(v.begin(),v.end(),[&](int & x){cout<<x<<"  ";});
	cout<<endl<<endl;
	
	msort(v);
	
	cout<<reverse_pairs<<endl;
	for(int x: v){
		cout<<x<<"  ";
	}
	cout<<endl;
}


scala (每次merge时计数)

object Main extends App {
	var reverse_pairs=0  //逆序数
	def msort[T](cmp:(T,T)=>Boolean)(l:List[T]):List[T]={
		def merge(l1:List[T],l2:List[T]):List[T] = (l1,l2) match{
				case(Nil,_) => l2
				case(_,Nil) => l1
				case(x::left1,y::left2) => 
				if(cmp(x,y))
					x::merge(left1,l2)  
				else{
					reverse_pairs+=l1.length  //增加逆序数
					y::merge(l1,left2)
				}
		}
		val n=l.length/2
		if(n==0)
			return l
		else{
			val (l1,l2)=l.splitAt(n)
			merge(msort(cmp)(l1),msort(cmp)(l2))
		}
	}
	println(msort((x:Int,y:Int)=>x<y)(List(5,4,3,2,7,6)))
	println(reverse_pairs)
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值