MergeSort 求逆序数

逆序数,定义为一对元素,其大小关系不符合顺序。比如a[0]=1;a[1]=0,这两个元素就为一对逆序。


求逆序数最直接的方法就是一组一组的判断,给一个长度为n的数组,使用两个for循环判断每一组数是不是逆序。因此,该方法复杂度为O(N^2).


若要使用更快的算法,可基于merge sort来求。


mergesort通过把数组一层一层的分割,在合并的方法对数组排序。在每一次merge时,如果我们是从后一个子数组中merge一个元素,证明该元素是一个逆序的元素,因此前面每一个元素和该元素构成一个逆序。累加即可得到数组的逆序数。即count+=mid-i+1;其中mid+1为前一个subarray的长度,减去i表示前一个subarray还有多少个元素没有被merge.


该方法的复杂度等同于mergesort,为O(N*logN);


代码如下:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;


public class InversionCount {
	public static ArrayList
   
   
    
     copy=new ArrayList
    
    
     
     ();
	public static ArrayList
     
     
      
       test=new ArrayList
      
      
       
       (1024);
	public static int count=0;
	public static void readData(String fileName) throws IOException{//read data from files
		File file=new File(fileName);
		String temp;
		int tempInt;
		BufferedReader reader = null;
		try{
			reader=new BufferedReader(new FileReader(file));
			while((temp=reader.readLine())!=null){
				tempInt=Integer.parseInt(temp);
				test.add(tempInt);
			}
		reader.close();
		}catch(FileNotFoundException e){
			e.printStackTrace();
		}
		

	}
	public static void counting(){
		for(int i=0;i
       
       
         test.get(j)){ count++; } } } } public static void mergeArray(ArrayList 
        
          a, int low,int mid,int high){ int k=low,l=mid+1; for(int i=low;i<=high;i++){ copy.set(i,a.get(i)); } for(int j=low;j<=high;j++){ if(k>mid){ a.set(j, copy.get(l++)); } else if(l>high){ a.set(j, copy.get(k++)); } else if(copy.get(k)<=copy.get(l)){ a.set(j, copy.get(k++)); } else{ a.set(j, copy.get(l++)); count=count+mid-k+1;//accumulation of count } } } public static void mergeSort(int low,int high){ if(high<=low) return; int mid=low+(high-low)/2; mergeSort(low,mid); mergeSort(mid+1,high); mergeArray(test,low,mid,high); } public static void main(String[] args) throws IOException{ readData("data1.4096"); double time; for(int i=0;i<4096;i++){//initialize the copy array copy.add(0); } Stopwatch timer=new Stopwatch(); mergeSort(0,test.size()-1); //counting();//compare two methods time=timer.elapsedTime(); System.out.println("Result:"+count+"\nRuntime "+time+" ms"); } } 
         
       
      
      
     
     
    
    
   
   

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值