Коды Прюфера — различия между версиями
(→Алгоритм построения кодов Прюфера) |
Masha (обсуждение | вклад) (добавлен алгоритм декодирования) |
||
| Строка 49: | Строка 49: | ||
== Пример построения кода Прюфера == | == Пример построения кода Прюфера == | ||
[[Файл: Prufer.png|500px]] | [[Файл: Prufer.png|500px]] | ||
| + | |||
| + | == Алгоритм декодирования кодa Прюфера == | ||
| + | |||
| + | В массиве вершин исходного дерева <tex>V</tex> найдём вершину <tex>v_{min}</tex> с минимальным номером, не содержащуюся в массиве с кодом Прюфера <tex>P</tex>, т.е. такую, что она является листом или концом уже добавленного в граф ребра, т.е. она стала листом в процессе построения кода Прюфера (по первому пункту построения). Вершина <tex>p_1</tex> была добавлена в код Прюфера как инцидентная листу с минимальным номером (по второму пункту построения), поэтому в исходном дереве существует ребро {<tex>p_1</tex>, <tex>v_{min}</tex>}, добавим его в список ребер. Удалим первый элемент из массива <tex>Р</tex>, а вершину <tex>v_{min}</tex> - из массива <tex>V</tex> т.к. она больше не может являться листом (по третьему пункту построения). Будем выполнять вышеуказанные действия, пока массив <tex>P</tex> не станет пустым. В конце работы алгоритма в массиве <tex>V</tex> останутся две вершины, составляющие последнее ребро дерева (это следует из построения). | ||
| + | |||
| + | === Реализация === | ||
| + | # P - код Прюфера | ||
| + | # V - вершины | ||
| + | '''function''' buildTree(P, V): | ||
| + | '''while'' '''not'' P.empty(): | ||
| + | u = P[0] | ||
| + | v = min(x '''<tex>\in</tex>''' V: P.count(x) == 0) | ||
| + | G.push({u, v}) | ||
| + | P.erase(0) | ||
| + | V.erase(indexOf(v)) | ||
| + | G.push({v[0], v[1]}) | ||
| + | '''return''' G | ||
| + | |||
== Пример декодирования кода Прюфера == | == Пример декодирования кода Прюфера == | ||
Версия 19:39, 10 января 2021
Содержание
Алгоритм построения кодов Прюфера
Кодирование Прюфера переводит помеченные деревья порядка в последовательность чисел от до по алгоритму:
Пока количество вершин больше двух:
- Выбирается лист с минимальным номером.
- В код Прюфера добавляется номер вершины, смежной с .
- Вершина и инцидентное ей ребро удаляются из дерева.
Полученная последовательность называется кодом Прюфера (англ. Prüfer code) для заданного дерева.
| Лемма: |
Номер вершины встречается в коде Прюфера тогда и только тогда, когда не является листом, причём встречается этот номер к коде дерева в точности раз. |
| Доказательство: |
|
| Лемма: |
По любой последовательности длины из чисел от до можно построить помеченное дерево,
для которого эта последовательность является кодом Прюфера. |
| Доказательство: |
|
Доказательство проведем по индукции по числу верно. Индукционный переход: Пусть для числа верно, построим доказательство для : Пусть у нас есть последовательность: Выберем минимальное число не лежащее в . По предыдущей лемме вершина, которую мы удалили первой. Соединим и ребром. Выкинем из последовательности число . Перенумеруем вершины, для всех заменим на . А теперь мы можем применить предположение индукции. |
| Теорема: |
Кодирование Прюфера задаёт биекцию между множествами помеченных деревьев порядка и последовательностями длиной из чисел от до |
| Доказательство: |
|
Следствием из этой теоремы является формула Кэли.
Пример построения кода Прюфера
Алгоритм декодирования кодa Прюфера
В массиве вершин исходного дерева найдём вершину с минимальным номером, не содержащуюся в массиве с кодом Прюфера , т.е. такую, что она является листом или концом уже добавленного в граф ребра, т.е. она стала листом в процессе построения кода Прюфера (по первому пункту построения). Вершина была добавлена в код Прюфера как инцидентная листу с минимальным номером (по второму пункту построения), поэтому в исходном дереве существует ребро {, }, добавим его в список ребер. Удалим первый элемент из массива , а вершину - из массива т.к. она больше не может являться листом (по третьему пункту построения). Будем выполнять вышеуказанные действия, пока массив не станет пустым. В конце работы алгоритма в массиве останутся две вершины, составляющие последнее ребро дерева (это следует из построения).
Реализация
# P - код Прюфера
# V - вершины
function buildTree(P, V):
while not P.empty():
u = P[0]
v = min(x V: P.count(x) == 0)
G.push({u, v})
P.erase(0)
V.erase(indexOf(v))
G.push({v[0], v[1]})
return G
Пример декодирования кода Прюфера
См. также
- Связь матрицы Кирхгофа и матрицы инцидентности
- Матрица Кирхгофа
- Количество помеченных деревьев
- Подсчет числа остовных деревьев с помощью матрицы Кирхгофа