【问题标题】:Java List/Recursion bugJava 列表/递归错误
【发布时间】:2014-07-20 01:49:37
【问题描述】:

Java 新手。我正在读一本书,并给出了一个关于快速排序的例子,它工作得很好。我了解该算法,但想在每次递归之前打印数组,以真正了解较低和较高数组的情况。

我想我只是声明一个单独的列表并用较低、枢轴和较高的值填充它,但它似乎抛弃了所有功能。递归似乎保持不变,但实际上并没有排序。因此,它溢出并退出。

我几乎可以肯定这里缺少一个基本的 Java 概念。

除了用 cmets 包裹的线条外,所有内容都取自书中。注释行之间的行是我自己的。

package quicksort;

import java.util.ArrayList;
import java.util.List;

public class App {

    public static List<Integer> quicksort(List<Integer> numbers){
        if (numbers.size() < 2){
            return numbers;
        }

        final Integer pivot = numbers.get(0);
        final List<Integer> lower = new ArrayList<>();
        final List<Integer> higher = new ArrayList<>();

        for (int i = 1; i < numbers.size(); i++){
            if (numbers.get(i) < pivot){
                lower.add(numbers.get(i));
            }
            else{
                    higher.add(numbers.get(i));
            }
        }

        // Makes things go all squirrrrrrrrely
        final List<Integer> notYetSorted = lower;
        notYetSorted.add(pivot);
        notYetSorted.addAll(higher);

        System.out.println("During: " + notYetSorted);
        // -------------

        final List<Integer> sorted = quicksort(lower);

        sorted.add(pivot);

        sorted.addAll(quicksort(higher));

        return sorted;
    }

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

        intList.add(5);
        intList.add(8);
        intList.add(2);
        intList.add(9);
        intList.add(10);
        intList.add(3);
        intList.add(4);
        intList.add(7);
        intList.add(1);
        intList.add(6);

        System.out.println("Before: " + intList);
        System.out.println("After: " + quicksort(intList).toString());
    }  

}

【问题讨论】:

  • 请在输出中提及所有错误。这给出了一个 - Exception in thread "main" java.lang.StackOverflowError 另外,请用文字说明步骤。
  • 您也可以intList.addAll(Arrays.asList(5,8,2,9,10,3,4,7,1,6));,而不是单独将每个数字添加到列表中
  • Borat - 我会牢记这一点。谢谢! vandle - 我想知道是否有这样的东西。非常感谢您的建议。

标签: java recursion quicksort


【解决方案1】:

你的问题是在这个块的开头:

final List<Integer> notYetSorted = lower;
notYetSorted.add(pivot);
notYetSorted.addAll(higher);

System.out.println("During: " + notYetSorted);
// -------------

final List<Integer> sorted = quicksort(lower);

与 C++ 不同,当您将新变量分配给现有变量时,Java 不会执行深层复制。所以notYetSortedlower 实际上指的是内存中完全相同的列表——然后您对notYetSorted 所做的任何更改也会对lower 进行。

因此,在该块的最后一行,您一直在对大小相同的List 调用快速排序。这就是它永远递归的原因。

将第一行改为:

final List<Integer> notYetSorted = new ArrayList<>(lower);

一切都会好起来的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 2020-02-23
    • 2012-11-19
    • 2016-02-05
    • 2014-04-28
    • 2015-12-08
    相关资源
    最近更新 更多