List.Sort
на самом деле задокументировано использование QuickSort (без дополнительных подробностей), но я проигнорирую это в пользу разговора о сортировке в целом ...
Я подозреваю, что для любой разумной сортировкиВ алгоритме этот компаратор приводит к завершению операции с вероятностью 1 в том смысле, что вероятность его продолжительного N шага стремится к 0, так как N стремится к бесконечности.На самом деле, я думаю, что во многих случаях существует жесткий верхний предел.
Причина в том, что вполне возможно (происходит с ненулевой вероятностью), что случайный компаратор может так и получиться, чтобы вернуть согласованные результаты для достаточного количества сравненийв ряду (O (n log n) из них, возможно, или O (n ^ 2) для сортировки вставки), что алгоритм «думает», что он закончен.Пока это в конце концов случится, я бы ожидал, что это прекратит сортировку.
Однако я не могу быть уверен в этом, потому что отнюдь не невозможно, чтобы алгоритм попал в неисправимоесостояние до этого краткого периода согласованности.У меня просто есть догадка, что для практических алгоритмов сортировки этого не произойдет.И действительно, для многих алгоритмов эта проблема неизбежно становится меньше, независимо от того, насколько бессмысленным является компаратор, что приводит к жесткому ограничению.В частности, QuickSort работает путем многократного разбиения массива - если компаратор случайный, то это приведет к бессмысленным разбиениям, но до тех пор, пока из-за несогласованности не произойдет никаких реальных ошибок, массив все равно будет разделен на две части для рекурсии.Тот факт, что элементы в «верхней» части не будут сравниваться больше, чем точка поворота во второй раз, скорее всего, не имеет значения, поскольку их никогда не будут сравнивать с этим снова.
В любом случае, это может занять очень много времени, достаточно долго, чтобы составить «опасность» для большинства практических целей.Например, пузырьковая сортировка будет просто продолжать перемешивать, пока не получит n
отрицательных результатов подряд, чтобы завершить цикл, ничего не двигая.Это займет ожидаемое время 2^n
или около того (не то, что List.Sort
в частности может быть пузырьковой сортировкой, я использую его только для иллюстрации того, что может случиться для сортировки в целом).И в зависимости от деталей реализации, вы можете обнаружить, что вы получаете доступ за пределами, потому что «невозможное» происходит чаще, чем вы «заканчиваете».
Операция, безусловно, не Обязательно рандомизируйте коллекцию с равной вероятностью всех перестановок.Опять же, обратите внимание, что QuickSort выбирает стержень, а затем разделяет его.Учитывая этот случайный компаратор (и, опять же, не принимая фактических ошибок, таких как за пределами доступа), вероятность того, что первый выбранный стержень окажется в крайней правой части массива, равна 1 в 2 ^ (n-1) (поскольку все остальные элементы должны быть отсортированы слева от него, половина вероятности для каждого), тогда как при равномерно-случайно выбранной перестановке эта вероятность должна быть 1 на n.Первый выбранный стержень распределяется в массиве по кривой колокола, когда он «должен» быть равномерным.