Бинарная древовидная структура

Я пытаюсь решить эту проблему, когда новому присоединяющемуся одноранговому узлу будет присвоен индекс [0,1,2,... n-1] в зависимости от того, сколько одноранговых объектов уже существует (например, 8 существует -> новый одноранговый узел получит индекс 8).

Я хочу добавить эти одноранговые объекты в двоичное дерево на основе их индекса. Например, узел 0 присоединяется, и он будет корнем, тогда узел 1 и узел 2 будут левым и правым потомками узла 0.

Мне нужно только, чтобы бинарное дерево соответствовало правилу, согласно которому у него должно быть два потомка.

Вот пример:

    0 

   / \

  1   2

 / \ / \

3  4 5  6

Моя проблема в том, что я не уверен, как на самом деле сделать эту вставку, чтобы сохранить правило двух детей. Сначала я предположил, что нормальное правило вставки BST будет работать, но как только я на самом деле закодировал его, я понял проблему поворота / ключа - я вставляю на основе индекса. Все просто станет правильным ребенком

Я действительно застрял в этом, но я думаю, что решение должно быть тривиальным, которое я просто не вижу. Любой совет?

Редактировать: Спасибо за помощь! Я думаю, что нашел что-то, что удовлетворит мои потребности, поэтому я оставлю это здесь. У меня будет неявная структура двоичного дерева. Присоединяющиеся одноранговые узлы помещаются в приоритетную очередь на основе их индекса. Это будет означать, могут ли они иметь назначенных им дочерних элементов, и одноранговый узел будет удален из этой очереди, как только у него будет 2 дочерних элемента.


person JerryFox    schedule 07.08.2014    source источник
comment
Если вы хотите добавить на основе индекса, который вы ему уже дали, вам не нужно двоичное дерево, вам нужен массив.   -  person Dave Zych    schedule 07.08.2014
comment
@DaveZych Вы можете индексировать двоичное дерево ... вы даже можете использовать массив для хранения двоичного дерева ...   -  person progrenhard    schedule 07.08.2014
comment
@progenhard Я хорошо знаю об этом. Но он присваивает индекс каждому элементу перед добавлением его в BT и хочет использовать этот индекс при его добавлении в BT. По сути, он строит связанный список. Просто добавьте элементы в BT и позвольте ему построить себя.   -  person Dave Zych    schedule 07.08.2014
comment
@DaveZych Изначально у меня была структура массива, но потенциально у меня будет до 10 тысяч одноранговых узлов. При удалении и добавлении новых пиров это сильно повлияет на производительность.   -  person JerryFox    schedule 07.08.2014
comment
@JerryFox Какова ваша цель после того, как они будут добавлены в любую структуру данных, с которой вы в конечном итоге столкнетесь? Нужно ли их искать? Пройтись по каждому и выполнить какое-то действие?   -  person Dave Zych    schedule 07.08.2014
comment
Наличие массива длины 10000 совершенно нормально. Если вы назначаете идентификатор пользователя каждому пользователю, вы будете использовать его в качестве индекса для массива, поэтому ваш поиск будет постоянным. В качестве альтернативы, если вы не будете назначать идентификаторы пользователей последовательно или хотите использовать какой-либо другой нецелочисленный тип данных в качестве уникального идентификатора, используйте хэш-таблицу.   -  person Ryan Chipman    schedule 07.08.2014
comment
Мне нужно иметь доступ к одному в случае, когда он удален. Например, если 2 будут удалены, 5 и 6 будут в некотором смысле повторно вставлены в дерево с новым индексом, с обновленным родительским элементом.   -  person JerryFox    schedule 07.08.2014
comment
@DaveZych Но даже если вам нужно их искать, нет случаев, когда вам нужно искать по uuid. Как я уже сказал в своем ответе, единственный раз, когда подобная структура данных была бы полезна, было бы, если бы вы использовали какое-то другое значение, такое как оценка или возраст, в качестве ключа.   -  person Ryan Chipman    schedule 07.08.2014
comment
@RyanChipman проблема с использованием хеш-таблицы заключается в том, что, скажем, одноранговый узел 2 удален, все, что ниже него, необходимо обновить и повторно вставить в древовидную структуру, поэтому хеш-таблица не дает многого.   -  person JerryFox    schedule 07.08.2014
comment
@JerryFox звучит так, будто вы смотрите на что-то вроде связанных списков. Зачем вам нужно это понятие родителя?   -  person Ryan Chipman    schedule 07.08.2014
comment
@JerryFox Что вам на самом деле нужно делать с этими пользователями. Дайте нам представление о том, какие операции вы планируете выполнять, для которых, по вашему мнению, вам нужен BST. Потому что сейчас я не понимаю, что вы получаете от использования BST.   -  person Ryan Chipman    schedule 07.08.2014
comment
@RyanChipman Родитель отправляет информацию 2 дочерним элементам, и аналогичным образом 2 дочерних элемента также отправляют информацию родителю.   -  person JerryFox    schedule 07.08.2014
comment
Давайте продолжим обсуждение в чате.   -  person Ryan Chipman    schedule 07.08.2014
comment
Я думаю, что нашел что-то, что удовлетворит мои потребности, поэтому я оставлю это здесь. У меня будет неявная структура двоичного дерева. Пиры, которые присоединяются к ним, помещаются в приоритетную очередь на основе их индекса. Это будет означать, могут ли они иметь назначенных им дочерних элементов, и одноранговый узел будет удален из этой очереди, как только у него будет 2 дочерних элемента.   -  person JerryFox    schedule 07.08.2014


Ответы (2)


Несколько вещей, которые вы хотите рассмотреть:

Зачем вам нужен BST?

BST, как следует из названия, в первую очередь предназначены для поиска. Но если вы назначаете каждому новому пользователю, который присоединяется, уникальный идентификатор, то вам не нужно использовать BST для их поиска, потому что вы можете получить к ним доступ из массива по индексу.

BST был бы более полезен, если бы, скажем, каждый пользователь играл в игру и зарабатывал определенный балл. Чтобы организовать пользователей в структуру данных, которая сделает их доступными для поиска/упорядочивания по счету, вы можете добавить игрока в BST с его счетом в качестве ключа, когда он закончил игру. Но для таких уникальных идентификаторов нет смысла использовать BST. На самом деле структура данных, которую вы там показываете, не является BST. BST будет выглядеть так:

   3 

  / \

 1   5

/ \ / \

0 2 4  6

Подходит ли другая структура данных?

Если вы лучше понимаете, почему BST не является полезной структурой для организации идентификаторов пользователей, вам следует подумать о том, что вы на самом деле пытались сделать. Если вы просто пытаетесь сохранить всех пользователей в структуре данных, вполне подойдет список (массив), где индекс списка соответствует идентификатору пользователя.

Если вместо этого вы хотите добавить какую-то группу для этих пользователей, рассмотрите возможность использования хеш-таблицы. Например, если вы хотите иметь возможность искать друзей пользователя, вы должны создать хеш-таблицу, в которой идентификатор пользователя (ключ) сопоставляется со списком идентификаторов пользователей друзей (значение).

Надеюсь, это было полезно. Если я могу чем-то еще помочь, или если я не совсем понял, чего вы пытаетесь достичь, просто дайте мне знать.


ОБНОВЛЕНИЕ

Итак, основываясь на приведенных выше комментариях, кажется, что вы запутались в различии между двоичным деревом и BST. Бинарное дерево — это любое дерево, в котором каждый узел имеет ‹= 2 дочерних элемента, тогда как бинарное поисковое дерево накладывает дополнительные ограничения на значения ключей узлов. Двоичная древовидная структура — это то, что вам нужно, но она вам не нужна для поиска, и вы не хотите сравнивать эти значения.

person Ryan Chipman    schedule 07.08.2014
comment
На самом деле мне не нужен BST, а просто двоичное дерево. Я понимаю, что это, вероятно, моя проблема, хотя - person JerryFox; 07.08.2014
comment
@ColonelThirtyTwo это неправда. BST — это бинарное дерево, но бинарное дерево — это не BST. Бинарное дерево — это структура, в которой каждый узел имеет не более двух дочерних элементов. BST - это когда все левые дочерние элементы меньше текущего узла, а все правые дочерние элементы больше текущего узла. - person Dave Zych; 07.08.2014
comment
извините, я знаю разницу, но я не понял, что оставил в одной ссылке на BST - person JerryFox; 07.08.2014

Для любого заданного индекса i родительский узел получил бы индекс (i + 1 >> 1) - 1, а дочерние узлы получили бы индексы (i << 1) + 1 и i + 1 << 1. Я не знаю, поможет ли это, поскольку я не уверен в цели вашего усилия. Но это, по крайней мере, означает, что вы можете сохранить всех своих пиров в простом массиве и использовать этот простой массив в качестве структуры двоичного дерева, получая доступ к дочерним элементам узла, просто используя индекс узла.

person Fors    schedule 07.08.2014