Ваш код имеет несколько серьезных проблем. Давайте рассмотрим их индивидуально.
Во-первых, если элемент, который вы выбираете как стержень, оказывается самым маленьким в коллекции, вы получите бесконечную рекурсию - он поместит все элементы в верхний раздел, но когда он попытается отсортировать верхний раздел, он получит одинаковые элементы в одном порядке, поместит их все в верхний раздел и повторит бесконечно.
Наиболее распространенным способом устранения этого является использование медианы из трех вариантов поворота. Это (почти) гарантирует, что по крайней мере один элемент будет меньше, чем точка поворота, и один элемент больше, чем точка поворота, поэтому даже в худшем случае вы поместите хотя бы один элемент в каждый раздел. Единственным исключением является то, что три элемента, которые вы выберете, одинаковы (в этом случае вам обычно нужно/нужно повторно выбрать значение поворота).
Во-вторых, как и почти все, что использует итераторы, std::partition
предполагает полуоткрытый диапазон - то есть, что первые точки итераторов на начало диапазона, а вторые очки итераторов просто мимо конца диапазон. Это означает, что вы хотите, чтобы ваши рекурсивные вызовы быть:
quicksort(lowerIt, pIt);
quicksort(pIt, upperIt);
В теории, пропуская элемент поворота на самом деле не что-то больно (и может быть использовано для предотвращения предыдущей задачи), но оставляя элемент из обработки, когда вы рекурсируете достаточно необычно, что я бы вообще избегать этого.Чтобы это работало как способ избежать бесконечной рекурсии, вам нужно поменять свод на первое место в верхнем разделе, так что это тот, который вы упускаете из того, что вы передаете в своих рекурсивных вызовах. Если вы оставите какой-то другой элемент, у вас возникнут проблемы, потому что вы не будете сортировать все элементы.
Для «серьезной» реализации Quicksort есть несколько других деталей вы, вероятно, хотите изменить, а, например, останавливая рекурсию, когда размер раздела получает вниз на что-то вроде 20 пунктов, а затем, когда вы закончите таким образом, сделайте сортировку вставки по всей коллекции, чтобы все было в ее конечном месте отдыха (так сказать).
Аналогичным образом, чтобы избежать переполнения стека, вы обычно хотите отсортировать меньшее из двух разделов. Это гарантирует, что пространство стека никогда не будет превышать O (log N). Как и в настоящее время, пространство стека может быть наихудшим случаем O (N).
Hi. Просить людей обнаружить ошибки в коде не особенно продуктивно. Вы должны использовать отладчик (или добавить заявления печати), чтобы изолировать проблему, отслеживая ход вашей программы и сравнивая ее с тем, что вы ожидаете. Как только двое расходятся, вы нашли свою проблему. (И затем, если необходимо, вы должны построить [минимальный тестовый сценарий] (http://sscce.org).) –