Мне нужно перенести N первых элементов односвязного списка длины n, случайным образом. Каждый элемент определяется как:
typedef struct E_s
{
struct E_s *next;
}E_t;
У меня есть корневой элемент, и я могу пересечь весь связанный список размером n. Каков наиболее эффективный метод, чтобы случайным образом перенять только N первых элементов (начиная с root)?
Итак, учитывая a- > b- > c- > d- > e- > f → ... x- > y- > z, мне нужно сделать что-л. как f- > a- > e- > c- > b → ... x- > y- > z
Мой конкретный случай:
- n-N составляет около 20% относительно n
- У меня ограниченные ресурсы ОЗУ, лучший алгоритм должен сделать его на месте.
- Я должен делать это в цикле, во многих итерациях, поэтому скорость имеет значение
- Идеальная случайность (равномерное распределение) не требуется, это нормально, если она "почти" случайна
- Перед выполнением перестановок я уже пересекаю N элементов (для других нужд), поэтому, возможно, я мог бы использовать это и для перестановок.
UPDATE: я нашел этот документ. Он утверждает, что он представляет собой алгоритм пространства стека O (log n) и ожидаемого времени O (n log n).