繁体   English   中英

Yaroslavsky Dual-pivot Quicksort Java实现

[英]Yaroslavsky Dual-pivot Quicksort Java implementation

我想问你是否可以告诉我我的代码是什么样子,所以在100000 int排序期间,我可能不会得到java.lang.StackOverflowError(我的实现很好,但只能处理20000个数字,而表的大小要大一些。排序会产生该错误)。 我试图在InteliJ中更改堆的大小,但是这种方式似乎不起作用。我也花了大约2个小时尝试修改它并通过网络阅读它,但我无法克服这个问题。 这就是为什么我要你们,向我展示在我的实现中可以在哪里更改代码,所以我不会再看到该错误。

这是代码:

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

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

public YaroslawskiSort(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);
        }
    }
}

void sortingI(int left,int right) {
    for (int i=left+1;i<=right;i++)
    {
        int value = mylist.get(i);
        int j =i-1;
        while (j >= left && mylist.get(j)>value)
        {
            mylist.set(j+1,mylist.get(j));
            j--;
        }
        mylist.set(j+1,value);
    }

}
private void sorting( int left, int right) {

    if((right-left)>=17) {
        int[] index=new int[2];
        index = partition(left, right);
        if (left < index[0]) {
            sorting(left, index[0]);
        }
        if(index[0]<index[1]){
            sorting(index[0], index[1]);
        }
        if (index[1] < right) {
           sorting(index[1], right);
        }


    }

    if((right-left)<17 && (right-left)!=0){
    sortingI(left,right);                               //INSERTION SORT!
    }
}

private int[] partition( int left, int right) {

    int pivot1 = mylist.get(left);
    int pivot2 = mylist.get(right);
    if(pivot1>pivot2){
       mylist.set(left,pivot2);
        mylist.set(right,pivot1);
        temporary=pivot1;
        pivot1=pivot2;
        pivot2=temporary;
    }
    int L=left+1;
    while(mylist.get(L)<pivot1 && L<right){
        L++;
    }
    int K=L;
    while( K<=right&& mylist.get(K)>=pivot1 && mylist.get(K)<=pivot2 ){
        K++;
    }
    int G=right-1;
    while(mylist.get(G)>pivot2 && G>left){
        G--;
    }


    while (K <= G) {
        if(mylist.get(K)<pivot1){
            mylist.add(left+1,mylist.remove(K));
            L++;
            K++;
        }
        if(mylist.get(K)>=pivot1 && mylist.get(K)<=pivot2){
            mylist.add(L,mylist.remove(K));
            K++;
        }
        if(mylist.get(K)>pivot2){
            mylist.add(right,mylist.remove(K));
            G--;
        }

    }

    mylist.set(left,mylist.get(L-1));
    mylist.set(L-1,pivot1);

    mylist.set(right,mylist.get(G+1));
    mylist.set(G+1,pivot2);
    int[] table=new int[2];
    table[0]=L;
    table[1]=G;

    return table;
}

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

public static void main(String[] args){

            YaroslawskiSort instance = new YaroslawskiSort(1,100000);
            instance.generate();
            instance.sorting(0, instance.mylist.size() - 1);

            instance.printing();

    }
}

感谢您的帮助:)

您的代码运行良好,可以增加堆栈大小,并在intellij IDEA(右上角)中和字段VM选项中键入-Xss16m,打开项目的Edit configuration...。 如果这样做,您将不会收到StackOverflowError。

在我看来,您得到StackOverflow的原因是您递归地调用排序方法,而在依次调用分区方法中,它总是创建一个新的int [2]并且所有这些数组都在堆栈上。

如果您可以重写分区方法,以便它(例如)返回int并分别为左右绑定调用它,那么我认为这将解决问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM