Java 快速分类分而治之

Java 快速分类分而治之,java,algorithm,sorting,quicksort,Java,Algorithm,Sorting,Quicksort,我正在尝试使用分治技术实现快速排序。我在递归调用中遇到堆栈溢出错误。这是我的密码: public static void main(String[] args) { ArrayList<Integer> unsorted = new ArrayList<Integer>(); unsorted.add(23); unsorted.add(5); unsorted.add(1); unsorted.add(-8); unso

我正在尝试使用分治技术实现快速排序。我在递归调用中遇到堆栈溢出错误。这是我的密码:

public static void main(String[] args) {
    ArrayList<Integer> unsorted = new ArrayList<Integer>();

    unsorted.add(23);
    unsorted.add(5);
    unsorted.add(1);
    unsorted.add(-8);
    unsorted.add(101);
    unsorted.add(21);
    unsorted.add(10);
    unsorted.add(10);
    unsorted.add(0);
    unsorted.add(50);

    ArrayList<Integer> sorted = Quicksort(unsorted);
    System.out.println(sorted.toString());
}

public static ArrayList<Integer> Quicksort(ArrayList<Integer> unsorted) {

    if (unsorted.size() <= 1)
        return unsorted;

    ArrayList<Integer> less = new ArrayList<Integer>();
    ArrayList<Integer> more = new ArrayList<Integer>();

    int pivotindex = unsorted.size()/2;

    for (int i = 0; i < unsorted.size(); i++) {
        if (unsorted.get(i) < unsorted.get(pivotindex))
            less.add(unsorted.get(i));
        else
            more.add(unsorted.get(i));
    }

    ArrayList<Integer> sorted = Quicksort(less);
    sorted.add(unsorted.get(pivotindex));
    sorted.addAll(Quicksort(more));

    return sorted;
}
publicstaticvoidmain(字符串[]args){
ArrayList unsorted=新的ArrayList();
未分类。添加(23);
未排序。添加(5);
未排序。添加(1);
未排序。添加(-8);
未排序。添加(101);
未排序。添加(21);
未排序。添加(10);
未排序。添加(10);
未排序。添加(0);
未排序。添加(50);
ArrayList排序=快速排序(未排序);
System.out.println(sorted.toString());
}
公共静态ArrayList快速排序(ArrayList未排序){

如果(unsorted.size(),则应将
值与
more
less
列表分开放置

将条件更改为:

else if(unsorted.get(i) > unsorted.get(pivotindex))
        more.add(unsorted.get(i));    
它应该很好用。希望这有帮助

编辑:正如Josh在评论中提到的,如果有多个元素具有与枢轴相同的值,则此操作将不起作用。为此,您可以定义另一个名为
equal
的ArrayList并添加以下行:

else
    equal.add(unsorted.get(i));
然后在合并回数组时,将此列表与
pivot
元素一起追加

谢谢你指出这一点。:)


注意:这种排序不能保证是稳定的(因为具有相同值的元素可能不会按照它们在原始数组中的相对位置来放置)。

这似乎是一种容易理解的解决方案

ArrayList<Integer> less = new ArrayList<Integer>();
ArrayList<Integer> equal = new ArrayList<Integer>();
ArrayList<Integer> more = new ArrayList<Integer>();

int pivotindex = unsorted.size()/2;

for (int i = 0; i < unsorted.size(); i++) {
    if (unsorted.get(i) < unsorted.get(pivotindex)) //Put whatever is less to the left
        less.add(unsorted.get(i));
    else if (unsorted.get(i) == unsorted.get(pivotindex)) //Put whatever is equal in the middle
        equal.add(unsorted.get(i));
    else //Put everything else to the right (everything greater)
        more.add(unsorted.get(i));
}

ArrayList<Integer> sorted = Quicksort(less); //Sort the left, then add
sorted.addAll(equal); //Middle is already sorted (all equal), add
sorted.addAll(Quicksort(more)); //Sort the right, then add

return sorted;
ArrayList less=新的ArrayList();
ArrayList equal=新的ArrayList();
ArrayList more=新的ArrayList();
int pivotindex=unsorted.size()/2;
对于(int i=0;i
以下操作非常有效

public static void main(String[] args) {
         ArrayList<Integer> unsorted = new ArrayList<Integer>();

            unsorted.add(23);
            unsorted.add(5);
            unsorted.add(1);
            unsorted.add(-8);
            unsorted.add(101);
            unsorted.add(21);
            unsorted.add(10);
            unsorted.add(10);
            unsorted.add(0);
            unsorted.add(50);

            ArrayList<Integer> sorted = Quicksort(unsorted);
            System.out.println(sorted.toString());
        }

        public static ArrayList<Integer> Quicksort(ArrayList<Integer> unsorted) {
                System.out.println(unsorted.size());
            if (unsorted.size() <= 1)
                return unsorted;

            ArrayList<Integer> less = new ArrayList<Integer>();
            ArrayList<Integer> more = new ArrayList<Integer>();

            int pivotindex = unsorted.size()/2;

            for (int i = 0; i < unsorted.size(); i++) {
                if (unsorted.get(i) < unsorted.get(pivotindex))
                    less.add(unsorted.get(i));
                else
                    more.add(unsorted.get(i));
            }
            if(less.isEmpty()) {
                less.add(more.remove(more.size() - 1));
            }

            ArrayList<Integer> sorted = Quicksort(less);
            //sorted.add(unsorted.get(pivotindex));
            sorted.addAll(Quicksort(more));

            return sorted;
        }
publicstaticvoidmain(字符串[]args){
ArrayList unsorted=新的ArrayList();
未分类。添加(23);
未排序。添加(5);
未排序。添加(1);
未排序。添加(-8);
未排序。添加(101);
未排序。添加(21);
未排序。添加(10);
未排序。添加(10);
未排序。添加(0);
未排序。添加(50);
ArrayList排序=快速排序(未排序);
System.out.println(sorted.toString());
}
公共静态ArrayList快速排序(ArrayList未排序){
System.out.println(unsorted.size());

如果(原样为unsorted.size(),则为等于轴的任何值(包括轴本身)将添加到
more
列表中。错误似乎在于,每次运行该方法时,您都会添加一个重复的
pivotindex
。在未排序的情况下进行迭代时,不会检查该值是否等于pivotindex,因此会将其添加到
more
arraylist中。然后在处再次添加它e> 已排序的.add(未排序的.get(数据透视索引))
因此数组将永远增长,这将导致stackoverflow错误。在for循环中,您将枢轴索引处的元素与自身进行比较,并最终将其作为less或more部分以及枢轴索引处的元素添加到排序列表中。因此,在每次递归调用中,您都会增加列表的大小,即如果是这样的话,我要指出的是,您仍然应该针对接口而不是类进行编程:声明
未排序的
更少的
更多的
列表
(如果你不坚持从中间开始透视,甚至是
Collection
,这提醒我:对透视使用局部变量,而不是索引)。使用构造函数对提供此类信息的
集合
s的大小进行合理估计。如果有多个元素与枢轴元素具有相同的值,这仍然有效吗…?使用此方法,这些元素将丢失,因为您没有将其添加到排序列表中。请参阅下面我的答案,我将保留它们,并将它们添加到t我想对于这个问题,聪明的解决方案是定义另一个名为
equal
的arraylist,然后将它与枢轴一起放回数组。