Проблема с наивным перемешиванием заключается в том, что значение, возможно, уже было поменяно местами, и вы можете поменять его снова позже. Допустим, у вас есть три карты, и вы выбираете одну наугад для первой карты. Если позже вы сможете случайным образом поменять местами эту карту на последнюю, то вы уберете случайность первого выбора.
Если сортировка является быстрой, она постоянно разбивает список пополам. Следующая итерация случайным образом разбивает каждую из этих групп на две группы. Это продолжается до тех пор, пока у вас не останутся отдельные карты, а затем вы объедините их все вместе. Разница в том, что вы никогда не берете карту из второй случайно выбранной группы и не перемещаете ее обратно в первую группу.
Тасование Кнута-Фишера-Йетса отличается от наивного тасования, потому что вы выбираете карту только один раз. Если бы вы выбирали случайные карты из колоды, вы бы положили карту обратно и выбрали бы снова? Нет, вы берете случайные карты по одной. Я впервые слышу об этом, но я делал нечто подобное еще в старшей школе, начиная с индекса 0 и выше. KFY, вероятно, быстрее, потому что у меня есть дополнительное добавление в случайном операторе.
for (int i = 0; i < cards.Length - 1; i++)
{
int n = rand.Next(cards.Length - i) + i; // (i to cards.Length - 1)
Swap(ref cards[i], ref cards[n]);
}
Не думайте об этом как об обмене местами, думайте об этом как о выборе случайных карт из колоды. Для каждого элемента в массиве (кроме последнего, потому что остался только один) вы выбираете случайную карту из всех оставшихся карт и кладете ее, формируя новую стопку карт, которые перемешиваются случайным образом. Не имеет значения, что ваши оставшиеся карты больше не в исходном порядке, если вы уже сделали какую-либо замену, вы все равно выбираете одну случайную карту из всех оставшихся карт.
Случайная быстрая сортировка похожа на то, как если взять стопку карточек и случайным образом разделить их на две группы, затем взять каждую группу и случайным образом разделить ее на две меньшие группы, и так далее, пока у вас не появятся отдельные карточки, а затем снова собрать их вместе.
person
Jason Goemaat
schedule
07.07.2011
n == i
в вашем первом алгоритме, тогда как есть 1/2 ^ 32 (я думаю, независимо от точности поплавка в JS), что не будет свопа с использованием.sort()
- person Mark Kahn   schedule 08.07.2011