Служат ли двоичные деревья конкретной цели для хранения иерархических данных? Каково их каноническое использование?

12

Я понимаю структуру бинарных деревьев и как их пройти. Тем не менее, я изо всех сил пытаюсь понять их фактическое использование, цели в программах и программировании. Когда я думаю о «реальных» примерах иерархических данных, они почти наверняка имеют более двух детей. Например, в родословной у матери часто может быть более двух детей.

Действительно ли «двоичные деревья» полезны только для хранения линейно связанных данных из-за более быстрого времени обработки массивов и списков? Или же они служат определенной цели для хранения иерархических данных? Если да, то какие есть примеры применения бинарных деревьев? Какие данные таковы, что узел имеет не более 2 дочерних элементов?

sw123456
источник
Я думаю, что основное использование двоичного дерева - это упорядочение данных. https://en.wikipedia.org/wiki/Binary_search_tree
Mandrill

Ответы:

25

Нет, двоичные деревья не предназначены для хранения иерархических данных в том смысле, о котором вы думаете. Основным вариантом использования n-арных деревьев, где nзадано фиксированное число, является возможность быстрого поиска , а не семантическая иерархия.

Вспомните старую игру, в которой один человек думает о числе от 1 до 100, а другой должен угадать его, используя как можно меньше догадок, и, если вы ошибаетесь, человек, думающий о числе, должен сказать вам, слишком ли вы высокий или слишком низкий? Через некоторое время становится скучно, потому что вы быстро понимаете, что всегда следует начинать с 50, затем переходить к 25 или 75 и продолжать делить диапазон для поиска пополам с каждым новым предположением после этого, и в конечном итоге вы можете угадать любое число в большинстве 7 догадок, гарантировано.

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

Мейсон Уилер
источник
Отличный ответ, большое спасибо. Итак, двоичное дерево - это просто еще одна структура для хранения данных, как если бы вы были в массиве или списке, но с дополнительным преимуществом возможностей быстрого поиска?
sw123456
1
@ sw123456: Это верно. Как и в любой другой разработке, она идет с компромиссами (использует больше - и более фрагментировано - памяти, чем массив с тем же числом элементов, O (n) доступ к элементу #n набора данных, а не O (1) доступ и т. д.), но быстрый поиск, безусловно, является основным преимуществом бинарных деревьев.
Мейсон Уилер
@ sw123456 Рад, что смог помочь объяснить это :)
Мейсон Уилер
3
Доступ к элементам O (log (n)), когда дерево сбалансировано. O (n) будет худшим случаем, когда он вырожден (большинство узлов только с одной скобкой).
Мандрил
@ sw123456 Сетевая маршрутизация использует небольшую модификацию двоичного дерева, которое называется Trie (созданное для большей эффективности проблемной области). На самом деле он хранит информацию об иерархии, поскольку маршрутизаторы перебирают дерево побитно при поиске IP-адреса, чтобы найти, куда он должен переслать пакет. IP-адреса также по своей природе являются иерархическими, поэтому при обходе IP-адреса для нахождения наибольшего совпадения префикса маршрутизатор пересекает иерархию IP-адресов, IP-адреса подсетей и т. Д. Семантически не очевидно, но связь существует. Маршрутизаторы используют эту структуру для эффективности поиска, как ответил Мейсон.
Крис Cirefice
3

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

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

Ваше сложное n-арное дерево стало простым бинарным деревом.

Я уверен, что это в Кнуте, Vol. 1 где-то

Justsalt
источник
Это действительно интересная реализация. Правильно ли я считаю, что поскольку каждый дочерний узел был началом связанного списка, дерево больше не будет O (log) n), если сбалансировано, или O (n), если нет, из-за того, что посещение каждого узла начнется от линейного поиска? Эта реализация приведет к гораздо более медленному времени поиска? Но с другой стороны, время поиска будет быстрее, чем у стандартной линейной структуры? Правильно ли я понял это?
sw123456
@ sw123456, если исходное дерево было сбалансировано, результирующее двоичное дерево почти наверняка не было бы. Я полагаю, что все остальное будет зависеть от веера из дерева, от того, сколько детей имеет какой-либо узел. Линейный поиск будет происходить только при выяснении, кому из дочерних узлов данного узла следовать. Но я не уверен, что вы могли бы избежать этого в любой другой реализации n-арного дерева.
Justsalt
2

Бинарные деревья зачем их использовать?

В программировании вы много работаете с коллекциями однотипных данных.

Два основных способа хранения этих данных: связанные списки и массивы.

Оба они имеют свои плюсы и минусы: в связанный список легко добавлять элементы в любую позицию или удалять элементы. Но доступ к определенному элементу сложнее, потому что вам нужно пройти по списку, пока вы не достигнете нужного элемента.

  • Он не выполняет эффективный поиск, но вставлять и удалять легко.

С массивом получить доступ к определенному элементу легко, но сложнее вставить или удалить элемент, потому что вставка означает: расширить массив на один, сдвинуть все элементы до позиции 1 вставки вправо и вставить элемент.

  • Он выполняет эффективный поиск (если отсортирован), но вставка и удаление затруднены.

Таким образом, и связанный список, и массив имеют недостатки.

Двоичные деревья созданы для решения как проблем массива, так и связанного списка:

  1. Легко вставлять и удалять
  2. Легкий поиск

Таким образом, двоичное дерево создано для случаев, когда у вас много данных, которые регулярно меняются.

Питер Б
источник