Вот лишь краткое изложение идеи:
В BST левое поддерево узла Tсодержит только элементы, меньшие, чем значение, хранящееся в T. Если kменьше, чем количество элементов в левом поддереве, kнаименьший элемент должен принадлежать левому поддереву. В противном случае, если kбольше, то kнаименьший элемент находится в правом поддереве.
Мы можем дополнить BST, чтобы каждый узел в нем сохранял количество элементов в своем левом поддереве (предположим, что левое поддерево данного узла включает этот узел). С помощью этой части информации легко пройти по дереву, неоднократно запрашивая количество элементов в левом поддереве, чтобы решить, делать ли рекурсию в левое или правое поддерево.
Теперь предположим, что мы находимся в узле T:
- Если k == num_elements (левое поддерево T) , то ответ, который мы ищем, - это значение в node
T.
- Если k> num_elements (левое поддерево T) , то, очевидно, мы можем игнорировать левое поддерево, потому что эти элементы также будут меньше
kth наименьшего. Итак, мы сводим задачу к поиску k - num_elements(left subtree of T)наименьшего элемента правого поддерева.
- Если k <num_elements (левое поддерево T) , то
kнаименьший по kразмеру элемент находится где-то в левом поддереве, поэтому мы сводим проблему к поиску th наименьшего элемента в левом поддереве.
Анализ сложности:
Это требует O(depth of node)времени, что O(log n)в худшем случае для сбалансированного BST или O(log n)в среднем для случайного BST.
Для BST требуется O(n)хранилище, а O(n)для хранения информации о количестве элементов требуется другое . Все операции BST требуют O(depth of node)времени, и требуется O(depth of node)дополнительное время для поддержания информации о «количестве элементов» для вставки, удаления или вращения узлов. Следовательно, хранение информации о количестве элементов в левом поддереве сохраняет пространственную и временную сложность BST.