Нет способа сделать это с лучшей временной сложностью, чем O (n) .С данными примера, которые вы даете (4,4,4,4,4,4,4,3,4
), куча может, например, быть одной из этих двух:
4 4
/ \ / \
4 4 4 4
/ \ / \ / \ / \
4 4 4 4 4 4 3 4
/ \ / \
4 3 4 4
... 3 может быть в любом листовом узле, так как это зависит от порядкавставки.Когда вы начинаете обход из корня, нет никакого способа узнать, находится ли 3 слева или справа.
Если вы готовы использовать слегка альтернативную структуру данных, то это можно сделать в O (1) :
Сохранять уникальные значения в куче.Используйте хэш-карту для хранения информации о добавленном вами значении.В простом случае эта «информация» может быть счетчиком событий.Поэтому в следующий раз, когда вы захотите вставить в структуру то же самое значение , вы обнаружите, что оно уже есть в хэш-карте, и только увеличите соответствующий счетчик вхождений, а не коснетесь кучи.
Для приведенного выше примера структура данных будет выглядеть следующим образом:
heap hashmap
key | value (=frequency)
4 -----+-------------------
/ 4 | 8
3 3 | 1
Если ваши элементы данных представляют собой сложные структуры, объединяющие ключ с некоторыми связанными данными (свойствами), то вы все равнохранить только ключи в куче без дубликатов.Тогда в хэш-карте будет указан не счетчик для каждого ключа, а массив фактических элементов данных, которые совместно используют тот же ключ.
Итак, для ясности, реализация операций, таких как вставка, удаление и поиск, должнабыть настроеннымВот некоторый псевдокод, предполагающий существование двух переменных heap
и hashmap
, которые имеют соответствующее поведение:
function insert(element):
key = element.key
if key not in hashmap:
hashmap.set(key, new Array)
heap.insert(key)
arr = hashmap.get(key) # get a reference to the array
arr.append(element) # add element to array, affecting the hashmap-stored value
function extract(): # remove max element
if heap.size() == 0:
return # No more data
key = heap.peek() # look at root value
arr = hashmap.get(key) # get a reference to the array
element = arr.pop() # extract from array, affecting the hashmap-stored value
if arr.length() == 0:
heap.extract()
hashmap.delete(key)
return element
function peek(): # return element with max value
if heap.size() == 0:
return # No more data
key = heap.peek() # look at root value
arr = hashmap.get(key)
element = arr[-1] # last element in array
return element
Вы можете получить наибольшее значение, которое меньше максимального значения, следующим образом:
key = max(heap.root.children())
... и затем, в зависимости от того, что вы ожидаете в качестве возвращаемого значения, вы также можете получить соответствующий элемент данных из хеш-карты или даже все из них (при наличии дубликатов).