解决我制作两个方法的问题,迭代和递归,用于浏览链接列表,然后比较每个方法完成所需的时间。
我正在尝试打印一个包含指定范围(从0到10000)的随机整数(从0到99)的链接列表但是当我尝试使用printRecursively函数时出现Stack Overflow错误以递归方式打印出列表的编号。我的迭代工作正常,但我无法弄清楚为什么当我使用我的其他方法时,我不断收到Stack Overflow错误。救命?谢谢
public class Compare {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Please enter the number of integers you wish to have inside the LinkedList:");
Integer numberOfItems = input.nextInt();
while (numberOfItems > 1000000 || numberOfItems < 0){
System.out.println("Not valid number. Please re-enter a valid integer:");
numberOfItems = input.nextInt();
}
LinkedList<Integer> list = new LinkedList<Integer>();
int i = 0;
Random rand = new Random();
while(i < numberOfItems){
int randomNumber = rand.nextInt(99);
list.add(i, randomNumber);
i++;
}
System.out.println("Would you like to print iteratively or recursively? (Type i or r):");
char choice = input.next().charAt(0);
if (choice != 'i' && choice != 'r')
{
int h = 0;
while(h == 0){
System.out.println("Incorrect input. (Type i or r):");
choice = input.next().charAt(0);
if (choice == 'i' || choice == 'r'){
h = 1;
}
}
}
if (choice == 'i'){
double startTime = System.nanoTime();
Functions blah = new Functions();
blah.printIteratively(list);
double endTime = System.nanoTime();
double duration = ((endTime - startTime)/1000000000);
System.out.println("The method took " + duration + " seconds to complete.");
}
if (choice == 'r'){
double startTime = System.nanoTime();
Functions blah = new Functions();
blah.printRecursively(list);
double endTime = System.nanoTime();
double duration = ((endTime - startTime)/1000000000);
System.out.println("The method took " + duration + " seconds to complete.");
}
}
}
这是我的职能:
public void printIteratively(LinkedList<Integer> list)
{
int k = list.size();
for(int j = 0; j < k; j++){
System.out.println(list.get(j));
}
}
public void printRecursively(LinkedList<Integer> list)
{
while(!(list.peek() == null)){
System.out.println(list.pollLast());
printRecursively(list);
}
}
}
答案 0 :(得分:2)
简单的答案是,递归是用于迭代列表内容的错误工具。这是一个迭代顺序算法,当列表变得太大时,递归将失败。它不是调整递归算法的问题,它只是错误的并且总是失败以获得足够大的列表,其中简单的迭代将继续正常工作。
递归失败的具体原因是每次递归调用都会消耗堆栈帧的内存,其中包括一些内务处理信息和方法中所有局部变量的实例。最终,你的堆栈空间不足,导致StackOverflow异常。
递归解决方案总是有一个上限,它可以处理的列表大小几乎肯定会比你可以存储在内存中的列表大小小很多。您可以通过分配更多堆栈空间来增加限制(使用-Xss
命令行选项),但限制基本上是算法的一部分,并且递归的方式适用于Java等语言。
如果您有兴趣,请查看术语&#34;尾部递归&#34;。有一些一些语言,编译器(或解释器)会检测到它并将其转换为迭代(我认为Lisp会这样做)。