简体   繁体   中英

I can't figure out why I'm getting StackOverFlowError

So I'm attempting to quicksort a singly linked list. Since I can't traverse backward like the traditional quicksort, I made it traverse forward to partition the list... But, if anyone could tell me where I'm getting this StackOverflowError it would really be appreciated.

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);
    }

}

EDIT: So thanks to your guys help I am a little bit closer I think... But I am still stuck. I have changed my code based on suggestions. But now it is just not sorting correctly.. The issue is when I try to move current to the front of the list... It seems to disconnect it from the list. So, when I print out the list all I get back is the pivot and the values greater than the pivot.. All of the lesser than elements have disappeared..

    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
        }

    }
}

The main problem (the StackOverflowError you're getting) is, that you don't change pivot and hence the recursive call to quickSort(pivot, last); will be the same as quickSort(first, last); and thus first != last will always be true for any list of size > 1.

You should first set pivot to the middle element, then sort elements according to being greater or smaller than the pivot and then call quicksort recursively for the sublists. Here though, you shouldn't pass pivot twice, otherwise you'd still get a stack overflow.

Assume you end up with a sublist of only two elements and you pick one as the pivot. One recursive call would do nothing since first = last but the other would essentially be quicksort(first, last) , would select the same pivot and repeat with the very same sublist.

So either pass pivot +/- 1 to one of the recursive calls (since it's a linked list I'd suggest quicksort(pivot.next, last) ) or check whether the sublist has more than 2 elements before doing the recursion.

From a quick glance... you are looping quickSort too many times and therefor you get that error.

example

private void countUp(int x){
    System.out.println(x);
    countUp(++x);
}

this will count about 10541 times for me... before throwing that error.

With that in mind... you might have an infinite loop somewhere OR your array are too large.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM