使用分而治之的反转计数

时间:2015-07-01 18:06:56

标签: java algorithm

我正在尝试实现一个计算反转次数的程序,但它不能用于大输入大小(100,000)。

从txt文件中挑选未分类的数字。该程序适用于小输入大小,如10或15甚至20。

但是当我从这个链接复制输入时:http://spark-public.s3.amazonaws.com/algo1/programming_prob/IntegerArray.txt程序只是运行了几秒而没有产生任何输出。

我使用了基于合并排序的分治算法和BlueJ中的Implemented。

这是代码。

import java.util.*;
import java.io.*;
class INVERSION
{
 private static LinkedList<Integer>arr;
 private static Scanner s;
 private static long count=0;
 public static void count_inv(int low,int high)
 {
     if(high<=low)
      return ;
     else
     {
         int mid= low + (high-low)/2;
         count_inv(low,mid);
         count_inv(mid+1,high);
         split_inv(low,high);

     }
 }
 public static void split_inv(int low,int high)
 {
     int mid=low+ (high-low)/2;
     int i=low,j=mid+1;
     int k=0;
     int []aa=new int[high-low+1];
     while(i<=mid&&j<=high)
     {
         if(arr.get(i)<=arr.get(j))
          aa[k++]=arr.get(i++);
         else {count+=mid-i+1; aa[k++]=arr.get(j++);}
     }
     while(i<=mid)
      aa[k++]=arr.get(i++);
     while(j<=high)
      aa[k++]=arr.get(j++);
     for(int e:aa)
      arr.set(low++,e);

 }
 public static void main(String []args)throws IOException
 {
  BufferedReader br=new BufferedReader(new FileReader("JJ.txt"));
  arr=new LinkedList<Integer>();
  String s="";
  while((s=br.readLine())!=null)
   arr.add(Integer.parseInt(s));                
  count_inv(0,arr.size()-1);
  System.out.println("the number of inversions is "+count);   
 }
}

1 个答案:

答案 0 :(得分:1)

我认为问题可能是您使用的是LinkedList。

这将有O(n)随机访问的访问时间。

你进行O(nlogn)访问,总的来说你的时间将是O(n ^ 2logn)。

尝试仅使用普通数组或其他具有O(1)访问时间的数据结构,例如ArrayList。