Я прочитал вам вопрос, как это
«Учитывая ввод n чисел из домена D, какой самый быстрый способ записать отсортированный ввод этих n чисел, при условии, что вы можете хранить только k чисел (k
Обратите внимание, в своем вопросе вы говорите, что домен D находится в диапазоне от 1 до 10000. Я считаю, что это упрощение. При n = 10000 и вводе в качестве диапазона (без повторений) это становится тривиальным , поскольку вы будете точно знать, где каждое число должно быть записано в отсортированном файле. Кроме того, вы точно знаете, что содержится в этом файле, и вам совсем не нужно его писать, и вам не нужно читать вводные данные. : D
Теперь, если N (D) не равно n или если вы разрешаете повторение, тогда проблема становится немного более интересной.
Если память ограничена, я думаю, что интуитивный подход заключается в следующем:
1-й подход
Считывая ввод, вы сможете отсортировать не более k1 элементов перед тем, как записать их, где k1 - это число элементов, для которого потребуется сортировка k элементов в памяти.
В результате вы получите f = (n div k1) + 1 файлов, которые отсортированы внутри.
Затем вам нужно будет прочитать из f файлов и объединить частично отсортированные данные, записав их в окончательный файл.
Разные сортировки имеют разные требования к памяти и будут производить разное количество частично отсортированных файлов, которые необходимо объединить.
Объединение большего количества файлов потребует больше памяти, потому что вы не будете знать, в каком файле вы можете найти следующий номер.
2-й подход
Другой подход, как вы предлагаете, - узнать, в каком файле вы можете найти следующий номер. Это все равно что складывать их в группы по размеру (распределять сортировку по классификации), но проблема в том, что, если вы не знаете, как распределяются ваши данные, определить диапазон каждого сегмента будет нелегко.
Размер каждого сегмента должен быть снова k1 для наименьшего количества файлов.
Предполагая, что вы знаете что-то о распределении ваших данных, это можно сделать, в противном случае вам потребуется еще один проход по вашим данным, чтобы установить точки отсечения.
Для общих данных, где размер сегмента неизвестен, и вы не можете сначала передать все данные, которые вы (например, если вам нужно сохранить какую-то сортированную структуру для ваших данных, когда ввод поступает, и вы не знаете, что будет дальше) вам, в основном, придется хранить индекс, такой как дерево B +, но это не оптимально. Индексы оптимизированы для быстрого поиска и (некоторые из них) для вставки небольшого количества новых элементов.
3-й подход
Наличие такого небольшого домена позволяет просто считать числа и записывать их частоту. Если вы можете иметь произвольный доступ к выходным файлам, буферизация файловой системы может позаботиться об эффективности (буферизация - это алгоритм, который выполняет эффективную запись на диск, ограниченную использованием памяти, единственная проблема заключается в том, что размер буфера меньше k чисел и если выбранная структура, подобная растровому изображению, является наиболее эффективной).
Интуитивно я бы сказал, что лучше всего было бы сначала рассчитать распределение и рассчитать размер и пределы для каждого сегмента. Затем разделите файл на ведра. Затем сортируйте каждое ведро. Я предполагаю, что некоторую производительность можно снизить, хотя бы частично отсортировав данные при записи их в сегменты.