Ответ 1
Одним из возможных способов реализации этой структуры данных является использование гибридного дерева статистики и хеш-таблицы .
Дерево статистики заказов - это тип сбалансированного двоичного дерева поиска, который в дополнение к обычным операциям двоичного дерева поиска поддерживает еще две операции:
- Ранг (ключ), который возвращает количество элементов в дереве, меньшем, чем данный элемент, и
- Выберите (k), который возвращает наименьший элемент k в дереве.
Деревья статистики заказов можно построить, добавив нормальное сбалансированное двоичное дерево поиска (например, красное/черное дерево или Дерево AVL) с дополнительной информацией, которая сохраняется при поворотах. Таким образом, все обычные операции BST в дереве статистики заказов могут быть выполнены для выполнения в O (log n) времени, а дополнительные операции также выполняются в O (log n) времени.
Теперь предположим, что вы просто хранили значения, а не показатели key/percentile. В этом случае было бы очень просто реализовать поиск процентилей следующим образом. Сохраните все значения в дереве статистики заказа. Чтобы определить показатель процентиля для заданного значения, используйте операцию rank в дереве статистики заказов, чтобы посмотреть, какой индекс указывает значение. Это дает число в диапазоне от 0 до n - 1 (где n - количество элементов в дереве), обозначая положение этой оценки в дереве статистики заказа. Затем вы можете умножить это число на 99/(n - 1), чтобы получить оценку процентиля для значения, которое выполняется в диапазоне от 0 до 99, если требуется.
Чтобы определить наименьшее значение, большее некоторого процентиля, вы можете использовать операцию select следующим образом. Учитывая процентиль между 0 и 99, умножите процентиль на 99/(n - 1), чтобы получить реальное число между 0 и n - 1 включительно. Взятие потолка этого числа дает натуральное число в диапазоне от 0 до n - 1 включительно. Используя операцию select в дереве статистики заказов, можно использовать для поиска первого значения в диапазоне, который находится выше или ниже указанного процентиля.
Однако эти операции предполагают, что мы имеем чисто значения в структуре данных, а не пары ключ/значение. Чтобы эта операция работала для пар ключ/значение, мы будем дополнять нашу структуру данных следующим образом:
- Вместо сохранения значений мы будем хранить пары ключ/значение в каждом node. Дерево статистики заказов сортирует пары ключ/значение исключительно по их значению, причем ключ переносится как спутниковые данные.
- Мы будем хранить вторичную хеш-таблицу, которая отображает ключи в соответствующие значения.
Эти два изменения позволяют реализовать необходимые функции для нашей структуры данных. Чтобы получить структуру данных, чтобы выполнять поиск по процентилям по ключу, мы сначала запрашиваем хэш-таблицу с заданным ключом для поиска связанного с ней значения. Затем мы выполняем поиск процентиля по значению, как это делалось ранее. Чтобы получить структуру данных, чтобы сообщить нам ключ, значение которого является первым в данном процентиле или выше, мы выполняем обычную операцию поиска-процентиля в дереве статистики заказов, как описано выше, а затем просматриваем ключ, связанный с данным значением.
Если предположить, что в хеш-таблице используется цепное хеширование, тогда время, требуемое для каждой операции, приведено ниже:
- Вставить: время O (log n) для вставки пары значение/ключ в дерево статистики заказа, плюс O (1) амортизированное время для вставки пары ключ/значение в хэш-таблицу. Общее время O (log n) амортизировано.
- Удалить: время O (log n) для удаления пары значение/ключ из дерева статистики заказа, плюс (1) амортизированное время для удаления пары ключ/значение из хеш-таблицы. Общее время O (log n) амортизировано.
- Percentile: O (1) ожидаемое время для поиска значения, связанного с ключом, времени O (log n) для выполнения операции rank и O ( 1) дополнительное время, чтобы отобразить ранг в процентиль. Общее время ожидания O (log n).
- Найти-Percentile: O (1) время, необходимое для сопоставления процентиля с рангом и O (log n) времени, необходимого для выполнения операции select. Общее время O (log n) наихудший.
Надеюсь, это поможет!