逆序数,定义为一对元素,其大小关系不符合顺序。比如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"); } }