Простой способ: как вывести бинарное дерево в таблице
Бинарное дерево — это структура данных, где каждый узел имеет не более двух потомков. Они часто используются для организации данных в программировании и алгоритмах. Один из способов визуализации бинарных деревьев — это таблица, где каждый узел представлен строкой.
Шаг 1: Подготовка данных
Для начала нужно иметь дерево, которое нужно отобразить в таблице. Будем считать, что у нас есть следующее дерево:
Шаг 2: Построение таблицы
Следующим шагом является построение таблицы бинарного дерева на основе данных из шага 1. Для этого мы можем определить несколько столбцов:
- Уровень узла: это уровень в дереве, на котором находится узел. Корень имеет уровень 0, потомки корня имеют уровень 1 и т. д.
- Значение узла: это значение, хранимое в узле.
- Родительский узел: это значение, хранимое в родительском узле.
Таблица будет иметь следующий вид:
| Уровень узла | Значение узла | Родительский узел | |--------------|---------------|-------------------| | 0 | 5 | - | | 1 | 3 | 5 | | 1 | 8 | 5 | | 2 | 1 | 3 | | 2 | 4 | 3 | | 2 | 10 | 8 |
Шаг 3: Размещение узлов
При размещении узлов мы можем использовать следующие правила:
- Для каждого узла размещаем его значение в соответствующей ячейке таблицы
- Если узел имеет потомков, то мы добавляем новые строки в таблицу для каждого потомка и размещаем их в следующих ячейках после узла.
Итоговая таблица будет иметь следующий вид:
| Уровень узла | Значение узла | Родительский узел | |--------------|---------------|-------------------| | 0 | 5 | - | | 1 | 3 | 5 | | 1 | 8 | 5 | | 2 | 1 | 3 | | 2 | 4 | 3 | | 2 | 10 | 8 |
Теперь мы можем легко сопоставить каждую ячейку таблицы с узлами в дереве и нарисовать его.
Вывод
Вывод бинарного дерева в таблице — это простой способ визуализации его структуры. Он позволяет легко представить дерево в виде таблицы, что может быть полезно при визуальном анализе и содержании структуры данных.
Источник
Построение таблиц идентификаторов по методу бинарного дерева.
Можно сократить время поиска искомого элемента в таблице идентификаторов, не увеличивая значительно время, необходимое на ее заполнение. Для этого надо отказаться от организации таблицы в виде непрерывного массива данных.
Существует метод построения таблиц, при котором таблица имеет форму бинарного дерева. Каждый узел дерева представляет собой элемент таблицы, причем корневой узел является первым элементом, встреченным при заполнении таблицы. Дерево называется бинарным, так как каждая вершина в нем может иметь не более двух ветвей (и, следовательно, не более двух нижележащих вершин). Для определенности будем называть две ветви «правая» и «левая».
Будем считать, что алгоритм заполнения бинарного дерева работает с потоком входных данных, содержащим идентификаторы (в компиляторе этот поток данных порождается в процессе разбора текста исходной программы). Первый идентификатор, как уже было сказано, помещается в вершину дерева. Все дальнейшие идентификаторы попадают в дерево по следующему алгоритму.
Шаг 1. Выбрать очередной идентификатор из входного потока данных. Если очередного идентификатора нет, то построение дерева закончено.
Шаг 2. Сделать текущим узлом дерева корневую вершину.
Шаг 3. Сравнить очередной идентификатор с идентификатором, содержащемся в текущем узле дерева.
Шаг 4. Если очередной идентификатор меньше, то перейти к шагу 5, если равен — сообщить об ошибке и прекратить выполнение алгоритма (двух одинаковых идентификаторов быть не должно!), иначе — перейти к шагу 7.
Шаг 5. Если у текущего узла существует левая вершина, то сделать ее текущим узлом и вернуться к шагу 3, иначе — перейти к шагу 6.
Шаг 6. Создать новую вершину, поместить в нее очередной идентификатор, сделать эту новую вершину левой вершиной текущего узла и вернуться к шагу 1.
Шаг 7. Если у текущего узла существует правая вершина, то сделать ее текущим узлом и вернуться к шагу 3, иначе — перейти к шагу 8.
Шаг 8. Создать новую вершину, поместить в нее очередной идентификатор, сделать эту новую вершину правой вершиной текущего узла и вернуться к шагу 1.
Рассмотрим в качестве примера последовательность идентификаторов GA, Dl, M22, Е, А12, ВС, F. На рис. 1 проиллюстрирован весь процесс построения бинарного дерева для этой последовательности идентификаторов.
Поиск нужного элемента в дереве выполняется по алгоритму, схожему с алгоритмом заполнения дерева.
Рис 1. Пошаговое заполнение бинарного дерева для последовательности идентификаторов GA, D1, M22, Е, А12, ВС, F
1. Выбрать очередной идентификатор из входного потока данных. Если очередного идентификатора нет, то построение дерева закончено.
2. Сделать текущим узлом дерева корневую вершину.
3. Сравнить имя очередного идентификатора с именем идентификатора, содержащегося в текущем узле дерева.
4. Если имя очередного идентификатора меньше, то перейти к шагу 5, если равно — прекратить выполнение алгоритма (двух одинаковых идентификаторов быть не должно!), иначе—перейти к шагу 7.
5. Если у текущего узла существует левая вершина, то сделать ее текущим узлом и вернуться к шагу 3, иначе — перейти к шагу 6.
6. Создать новую вершину, поместить в нее информацию об о черепном идентификатор е, сделать эту новую вершину левой вершиной текущего узла и вернуться к шагу 1.
7. Если у текущего узла существует правая вершина, то сделать ее текущим узлом и вернуться к шагу 3, иначе—перейти к шагу 8.
8. Создать новую вершину, поместить в нее информацию об очередном идентификаторе, сделать эту новую вершину правой вершиной текущего узла и вернуться к шагу 1.
Например, произведем поиск в дереве, изображенном на рис.1 (7), идентификатора А12. Берем корневую вершину (она становится текущим узлом), сравниваем идентификаторы GA и А12. Искомый идентификатор меньше — текущим узлом становится левая вершина D1. Опять сравниваем идентификаторы. Искомый идентификатор меньше — текущим узлом становится левая вершина А12. При следующем сравнении искомый идентификатор найден.
Если искать отсутствующий идентификатор — например, A11, — то поиск опять пойдет от корневой вершины. Сравниваем идентификаторы GA и АН. Искомый идентификатор меньше — текущим узлом становится левая вершина D1. Опять сравниваем идентификаторы. Искомый идентификатор меньше — текущим узлом становится левая вершина А12. Искомый идентификатор меньше, но левая вершина у узла А12 отсутствует, поэтому в данном случае искомый идентификатор не найден.
Для данного метода число требуемых сравнений и форма получившегося дерева во многом зависят от того порядка, в котором поступают идентификаторы. Например, если в рассмотренном выше примере вместо последовательности идентификаторов GA, 01, M22, E, A12, ВС, F взять последовательность А12, GA, D1, (22, E, ВС, F, то полученное дерево будет иметь иной вид. А если в качестве примера взять последовательность идентификаторов А, В, С, D, E, F, то дерево выродится в упорядоченный однонаправленный связный список. Эта особенность является недостатком данного метода организации таблиц идентификаторов. Другим недостатком является необходимость работы с динамическим выделением памяти при построении дерева.
Если предположить, что последовательность идентификаторов в исходной программе является статистически неупорядоченной (что в целом соответствует действительности), то можно считать, что построенное бинарное дерево будет невырожденным. Тогда среднее время на заполнение дерева (ТД) и на поиск элемента в нем (ТП) можно оценить следующим образом:
В целом метод бинарного дерева является довольно удачным механизмом для организации таблиц идентификаторов. Он нашел свое применение в ряде компиляторов. Иногда компиляторы строят несколько различных деревьев для идентификаторов разных типов и разной длины.
Источник