所以我试图快速排序单链表。因为我不能像传统的快速排序那样向后遍历,所以我让它遍历分区列表...但是,如果有人能告诉我在哪里得到这个StackOverflowError,我真的很感激。
public static <E extends Comparable<E>> void quickSort(MyNode<E> first, MyNode<E> last) {
if(first != last) {
MyNode<E> pivot = first;
MyNode<E> currentNode = first.next;
MyNode<E> previousNode = first;
while(currentNode.next != last && currentNode.next != null) {
if (currentNode.element.compareTo(pivot.element) < 0) {
MyNode<E> temp = new MyNode<E>(currentNode.element);
previousNode.next = currentNode.next;
temp.next = first;
first = currentNode;
}
previousNode = previousNode.next;
currentNode = currentNode.next;
}
quickSort(first, pivot);
quickSort(pivot, last);
}
}
编辑: 所以,多亏你们的帮助,我觉得我更接近......但我仍然被困住了。我根据建议改变了我的代码。但现在它只是没有正确排序..问题是当我尝试将当前移动到列表的前面...它似乎将它从列表中断开。因此,当我打印出列表时,所有我回来的是枢轴和大于枢轴的值。所有小于元素都消失了..
public static <E extends Comparable<E>> void quickSort(MyNode<E> first, MyNode<E> last) {
if(first != last && first != null) {
E pivot = first.element;
MyNode<E> current = first.next;
MyNode<E> previous = first;
while(previous != last && current != null) {
if (current.element.compareTo(pivot) < 0) {
previous.next = current.next;
first = current;
first.next = previous;
current = previous.next;
}
else {
previous = previous.next;
current = current.next;
}
//recursive calls will go here... Just want to get the logic right first
}
}
}
答案 0 :(得分:2)
主要问题(您获得的StackOverflowError)是,您不会更改pivot
,因此对quickSort(pivot, last);
的递归调用将与{{1}相同对于任何大小&gt;列表,quickSort(first, last);
总是如此1。
首先应将first != last
设置为中间元素,然后根据大于或小于数据透视表对元素进行排序,然后为子列表递归调用quicksort。但是,你不应该两次通过枢轴,否则你仍会得到堆栈溢出。
假设您最终只有两个元素的子列表,并选择一个作为数据透视表。一个递归调用自pivot
起无效,但另一个基本上是first = last
,将选择相同的数据透视表并重复使用相同的子列表。
所以要么将quicksort(first, last)
传递给其中一个递归调用(因为它是链接列表我建议pivot +/- 1
)或者在执行之前检查子列表是否包含多于2个元素递归。
答案 1 :(得分:0)
快速浏览一下......你正在循环quickSort太多次,因此你会得到那个错误。
例如
private void countUp(int x){
System.out.println(x);
countUp(++x);
}
这对我来说将大约10541次...然后抛出那个错误。
考虑到这一点......你可能在某处有一个无限循环或者你的数组太大了。