2017-03-17 62 views
0

我在Java中遇到了一个非常简单的问题。我已经在java中实现了快速排序,可以处理arraylist,并且可以带来任何价值。问题是它只适用于低于8000的大小的数组列表。 任何人都可以告诉我我的程序有什么问题吗?我认为它可能与递归深度限制有关,但我不确定(因为它有时适用于较大的尺寸,有时不适用)。我怎样才能改进我的快速排序实现,以便它能像100000这样的更大规模的Arraylist工作?Quicksort java arraylist实现

import java.util.ArrayList; 
import java.util.Random; 


public class QuickSort { 
Random gener; 
int temporary,genertype,NInts,flag; 
ArrayList<Integer> mylist; 

public QuickSort(int type,int ilosc){ 
    gener = new Random(); 
    mylist= new ArrayList<>(); 
    this.genertype=type; 
    this.NInts=ilosc; 

} 

void generate(){ 
    if(genertype==0){ 
     for(int i=0;i<NInts;i++){ 
      mylist.add(gener.nextInt(100000)); 
     } 
    }else { 
     for(int i=0;i<NInts;i++){ 
      mylist.add(NInts-i); 
     } 
    } 
} 

int count1(ArrayList<Integer> list,int counter1,int counter2){ 
    while(list.get(0)<list.get(counter1)){ 

     if(counter1==counter2){ 
      flag=1; 
      return counter1; 
     } 
     counter1++; 
    } 
    flag=0; 
    return counter1; 
} 
int count2(ArrayList<Integer> list,int counter1,int counter2){ 
    while(list.get(0)>list.get(counter2)){ 
     if(counter1==counter2){ 
      flag=1; 
      return counter2; 
     } 
     counter2--; 
    } 
    flag=0; 
    return counter2; 
} 


public ArrayList<Integer> sorting(ArrayList<Integer> list) { 
    ArrayList<Integer> left = new ArrayList<Integer>(); 
    ArrayList<Integer> right = new ArrayList<Integer>(); 
    int counter1,counter2; 

    if (list.size() == 1) { 
     return list; 
    }else { 
     counter1=1; 
     counter2=list.size()-1; 

     while(counter1!=counter2) { 

      counter1=count1(list,counter1,counter2); 
      if(flag==1) 
       break; 
      counter2=count2(list,counter1,counter2); 
      if(flag==1) 
       break; 

      temporary = list.get(counter1); 
      list.set(counter1, list.get(counter2)); 
      list.set(counter2, temporary); 
     } 

     for (int i = 0; i < counter1; i++) { 
      left.add(list.get(i)); 
     } 

     for (int i = counter1; i < list.size(); i++) { 
      right.add(list.get(i)); 
     } 

     left = sorting(left); 
     right = sorting(right); 
     list=merge(left, right); 
    } 
    return list; 
} 

ArrayList<Integer> merge(ArrayList<Integer> left, ArrayList<Integer> right) { 

    if(left.get(0)>right.get(right.size()-1)){ 
    right.addAll(left); 
     return right; 
    } 
    else{ 
     left.addAll(right); 
     return left; 
    } 

} 

void printing(){ 
    for(int k=0;k<NInts;k++){ 
     System.out.print(" "+mylist.get(k)); 
    } 
} 

public static void main(String[] args){ 

    QuickSort instance = new QuickSort(1,1000); 
    instance.generate(); 
    instance.mylist=instance.sorting(instance.mylist); 
    instance.printing(); 
    } 
} 

Ps.If你看到什么错在我的代码,让我知道这样我就可以改善它:)

+0

请定义*仅适用于低于大约8000大小*的ArrayLists。你得到一个错误?如果是这样,请分享 – CraigR8806

+1

足够高的数字(大约8000)您的递归调用溢出堆栈限制。看到这个问题的详细解释http://stackoverflow.com/questions/4734108/what-is-the-maximum-depth-of-the-java-call-stack – JuniorDev

+0

线程“主”的异常java.lang.StackOverflowError – SigKillMe

回答

0

可能有很多原因,你的代码不能用于大量投入运行。大多数情况下,这可能是因为为应用程序指定的堆大小容量溢出了。这可以通过增加应用程序的堆大小来解决(请查看stackoverflow link关于如何增加应用程序的堆大小)

+0

这是处理这个问题的错误方法......应该不惜一切代价避免堆大小的增加,并且排序8000个元素的列表不是必须保证增加的东西,更应该是优化 – CraigR8806

+0

。如果你的应用程序超过了指定的堆大小,将大量数据从应用程序加载到内存中,那么应用程序很快就会进入内存不足。在JVM调优中检查此[链接](https://dzone.com/articles/java-performance-tuning),更改JVM参数将是其中一种方法。 –

+0

OP没有收到一个OOM错误...这是一个SO错误....这个算法应该优化,不给一个创可贴...... – CraigR8806