我无法弄清楚为什么我得到StackOverFlowError

时间:2014-11-11 16:22:50

标签: java quicksort

所以我试图快速排序单链表。因为我不能像传统的快速排序那样向后遍历,所以我让它遍历分区列表...但是,如果有人能告诉我在哪里得到这个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
        }

    }
}

2 个答案:

答案 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次...然后抛出那个错误。

考虑到这一点......你可能在某处有一个无限循环或者你的数组太大了。