Я не могу понять, почему я получаю StackOverFlowError

Поэтому я пытаюсь быстро отсортировать односвязный список. Поскольку я не могу перемещаться в обратном направлении, как в традиционной быстрой сортировке, я сделал так, чтобы он перемещался вперед, чтобы разделить список... Но, если кто-нибудь может сказать мне, где я получаю эту StackruError, это действительно будет оценено.

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 ответа

Основная проблема (полученная ошибка StackruError) заключается в том, что вы не меняете pivot и, следовательно, рекурсивный вызов quickSort(pivot, last); будет так же, как quickSort(first, last); и поэтому first != last всегда будет верно для любого списка размером> 1.

Вы должны сначала установить pivot к среднему элементу, затем сортируйте элементы в соответствии с тем, больше или меньше, чем сводная, а затем рекурсивно вызывайте быструю сортировку для подсписков. Здесь, однако, вы не должны проходить pivot дважды, иначе вы все равно получите переполнение стека.

Предположим, вы в конечном итоге с подсписка только из двух элементов и вы выбираете один как стержень. Один рекурсивный вызов ничего не сделает, так как first = last но другой по существу будет quicksort(first, last), выбрал бы ту же точку и повторить с тем же подсписком.

Так что либо пройти pivot +/- 1 на один из рекурсивных вызовов (так как это связанный список, я бы предложил quicksort(pivot.next, last)) или проверьте, есть ли в подсписке более 2 элементов перед выполнением рекурсии.

С первого взгляда... вы слишком быстро повторяете цикл сортировки, и вы получаете эту ошибку.

пример

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

для меня это будет примерно 10541 раз... перед тем как выдать эту ошибку.

Имея это в виду... у вас может быть где-то бесконечный цикл ИЛИ ваш массив слишком велик.

Другие вопросы по тегам