Обычный подход для быстрой сортировки в связанных списках состоит в том, чтобы создать два (или лучше три, средний из которых является всеми элементами, равными элементу pivot) новых списков на этапе разделения, отсортировать первый и последний рекурсивно, а затем объединить их вместе.
Ваш код заменяет данные внутри узлов ... интересно. Я попробовал это со следующим (под) списком:
first last
[ 5 ]-->[ 3 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
Посмотрите, что делает ваш алгоритм:
[ 5 ]-->[ 3 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
p
ptr
3<5? (yes) {
pivot=5
[ 3 ]-->[ 3 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
p ptr
[ 3 ]-->[ 7 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
p ptr
[ 3 ]-->[ 7 ]-->[ 5 ]-->[ 9 ]-->[ 2 ]
p ptr
[ 3 ]-->[ 7 ]-->[ 5 ]-->[ 9 ]-->[ 2 ]
p
ptr
}
[ 3 ]-->[ 7 ]-->[ 5 ]-->[ 9 ]-->[ 2 ]
p
ptr
Это состояние после первой итерации. Начиная с ptr != null
, мы теперь переходим к следующей итерации, но я думаю, что вы уже здесь можете увидеть проблему. После следующей итерации это выглядит так:
[ 3 ]-->[ 5 ]-->[ 9 ]-->[ 7 ]-->[ 2 ]
p
ptr
В следующей итерации перестановок не происходит:
[ 3 ]-->[ 5 ]-->[ 9 ]-->[ 7 ]-->[ 2 ]
p
ptr
И теперь мы получим исключение NullPointerException, начиная с ptr.next == null
(или если это подсписок из большего списка, мы бы поменялись местами за пределами).
Итак, некоторые идеи:
- На шаге обмена вы должны убедиться, что впоследствии
p
указывает на узел, который теперь содержит элемент pivot.
- вам следует остановиться при достижении элемента
last
и убедиться, что вы не поменялись местами после него (но все же сам элемент поменялся местами при необходимости).