Балансировка двоичного дерева (AVL)

Хорошо, это еще один вопрос в области теории для парней CS.

В 90-х я довольно хорошо справлялся с реализацией BST. Единственное, что я никогда не мог разглядеть, - это сложность алгоритма балансировки двоичного дерева (AVL).

Можете ли вы, ребята, помочь мне в этом?

Ответы

Ответ 1

Дерево козла отпущения, возможно, имеет самый простой алгоритм определения баланса для понимания. Если какая-либо вставка приводит к тому, что новый node будет слишком глубоким, он найдет node, вокруг которого можно будет балансировать, глядя на баланс веса, а не на баланс по высоте. Правило для перебалансировки при удалении также прост. Он не хранит тайную информацию в узлах. Это сложнее доказать, что это правильно, но вам не нужно, чтобы понять алгоритм...

Однако, в отличие от AVL, он не всегда сбалансирован по высоте. Подобно красно-черному, его дисбаланс ограничен, но в отличие от красно-черных он настраивается с параметром, поэтому для большинства практических целей он выглядит сбалансированным, как вам нужно. Я подозреваю, что если вы настроите его слишком сильно, все равно это окажется хуже или хуже, чем AVL для вставки наихудшего случая.

Ответ на редактирование вопроса

Я расскажу о своем личном пути к пониманию деревьев AVL.

Сначала вам нужно понять, что такое ротация дерева, поэтому игнорируйте все остальное, что вы когда-либо слышали алгоритмы AVL, и понимаете это. Подойдите прямо к голове, которая является правильным вращением и которая является левым поворотом, и что каждый делает с деревом, или описания точных методов просто вас путают.

Затем поймите, что трюк для балансировки деревьев AVL заключается в том, что каждый node записывает в нем разницу между высотой его левого и правого поддеревьев. Определение "сбалансированный по высоте" состоит в том, что оно равно -1 и 1 включительно для каждого node в дереве.

Далее, поймите, что если вы добавили или удалили node, у вас может быть несбалансированное дерево. Но вы можете только изменить баланс узлов, которые являются предками node, которые вы добавили или удалили. Таким образом, то, что вы собираетесь делать, - это сделать свой путь обратно в дерево, используя повороты, чтобы сбалансировать любые неуравновешенные узлы, которые вы найдете, и обновить их баланс, пока дерево не будет сбалансировано снова.

Заключительная часть понимания заключается в том, чтобы найти достойную ссылку для конкретных поворотов, используемых для балансировки каждого node, который вы находите: это "техника" этого, а не высокая концепция. Вам нужно запомнить данные только при изменении кода дерева AVL или, возможно, во время экзаменов структур данных. Прошло много лет с тех пор, как я последний раз имел в дереве код AVL настолько, насколько он открыт в отладчике - реализации, как правило, доходят до того, что они работают, а затем продолжают работать. Поэтому я действительно не помню. Вы можете сортировать работу на столе с помощью нескольких покерных фишек, но вам нелегко убедиться, что у вас действительно есть все случаи (их немного). Лучше всего посмотреть его.

Тогда есть дело перевести все это в код.

Я не думаю, что просмотр списков кодов очень помогает на любом этапе, кроме последнего, поэтому игнорируйте их. Даже в лучшем случае, когда код явно написан, он будет выглядеть как учебное описание процесса, но без диаграмм. В более типичном случае это беспорядок манипуляции с C-структурой. Так что просто придерживайтесь книг.

Ответ 2

Я не думаю, что это хорошо, чтобы публиковать полные коды для node алгоритмов балансировки здесь, так как они становятся довольно большими. Тем не менее, статья Википедии о красно-черных деревьях содержит полную реализацию алгоритма и статью деревья AVL имеет несколько ссылок на высококачественные реализации.

Эти две реализации достаточны для большинства сценариев общего назначения.

Ответ 3

В последнее время я немного работаю с деревьями AVL.

Лучшая помощь, которую я смог найти, как сбалансировать их, - это поиск google.

Я просто кодировал этот псевдо-код (если вы понимаете, как делать вращения, его довольно легко реализовать).

IF tree is right heavy
{
  IF tree right subtree is left heavy
  {
     Perform Double Left rotation 
  }
  ELSE
  {
     Perform Single Left rotation
  }
}
ELSE IF tree is left heavy
{
  IF tree left subtree is right heavy
  {
     Perform Double Right rotation
  }
  ELSE
  {
     Perform Single Right rotation
  }
}

Ответ 4

Согласен, полная программа не подходит.

В то время как классическое дерево AVL и RB использует детерминированный подход, я бы предложил посмотреть " Рандомизированные деревья двоичного поиска", которые менее дорогостоящим, чтобы сбалансировать и гарантировать хорошую балансировку независимо от статистического распределения ключей.

Ответ 5

Дерево AVL неэффективно, потому что вы должны делать потенциально много поворотов на вставку/удаление.

Красно-черное дерево, вероятно, является лучшей альтернативой, потому что вставки/удаления намного эффективнее. Эта структура гарантирует самый длинный путь к листу, не более чем в два раза кратчайший путь. Поэтому, менее сбалансированный, чем дерево AVL, избегают худших несбалансированных случаев.

Если ваше дерево будет много раз читаться и не будет изменено после его создания, может оказаться полезным накладные расходы для полностью сбалансированного дерева AVL. Кроме того, для дерева Red-Black требуется один дополнительный бит памяти для каждого node, который дает цвет node ".

Ответ 6

Для балансировки дерева AVL я написал кучу функций, которые я думал об обмене со всеми здесь. Я предполагаю, что эта реализация безупречна. Запросы/questions/критика, конечно, приветствуются:

http://uploading.com/files/5883f1c7/AVL_Balance.cpp/

Будучи новичком в Stackoverflow, я попробовал опубликовать свой код здесь, но был застрял с плохими проблемами форматирования. Итак, загрузите файл по указанной выше ссылке.

Приветствия.

Ответ 7

существует полная реализация автономного балансирующего дерева avl @http://code.google.com/p/self-balancing-avl-tree/. он также реализует логарифмические операции конкатенации времени и разделения, а также коллекции карт/мультимапов