Алгоритм нахождения высоты дерева

Найдите высоту бинарного дерева, представленного родительским массивом

Учитывая массив, представляющий отношения родитель-потомок в двоичном дереве, найдите высоту дерева, не строя его. Отношения между родителями и детьми определяются (A[i], i) для каждого индекса i в массиве A . Значение корневого узла будет i если -1 присутствует в индексе i в массиве.

Глубина “узла” — это общее количество ребер от узла до корневого узла дерева. Корень — это единственный узел, глубина которого равна 0.

Высота “узла” — это общее количество ребер на самом длинном пути от узла до листа. Высота “дерева” будет высотой его корневого узла или, что то же самое, глубиной его самого глубокого узла. Листовой узел будет иметь высоту 0.

  • -1 присутствует в индексе 0, что означает, что корень бинарного дерева является узлом 0.
  • 0 присутствует в индексах 1 и 2, что означает, что левый и правый потомки узла 0 — это 1 и 2.
  • 1 присутствует в индексе 3, что означает, что левый или правый дочерний элемент узла 1 равен 3.
  • 2 присутствует в индексах 4 и 5, что означает, что левый и правый потомки узла 2 — это 4 и 5.
  • 4 присутствует в индексах 6 и 7, что означает, что левый и правый потомки узла 4 — это 6 и 7.

Соответствующее бинарное дерево:

Build Binary Tree from Parent Array

Связанный пост:

Простым решением было бы построить двоичное дерево с использованием родительского массива, как показано в сообщении выше. После того, как дерево построено, рассчитайте его высоту. Временная сложность приведенного выше решения равна O(n) и требует O(n) дополнительное пространство, где n размер родительского массива. Однако, согласно ограничениям задачи, высота должна рассчитываться без построения дерева.

Идея состоит в том, чтобы вычислить глубину каждого узла, используя рекурсия и вернуть максимальную найденную глубину. Поскольку глубина узла — это общее количество ребер от узла к корню, нам нужно проследить путь узла к корневому узлу, используя отношение родитель-потомок. Мы можем сделать это, рекурсивно обходя родительский массив. Алгоритм может быть реализован следующим образом на C, Java и Python:

C

результат:

The height of the binary tree is 3

Java

результат:

The height of the binary tree is 3

Python

результат:

The height of the binary tree is 3

Временная сложность приведенного выше решения равна O(n 2 ) , куда n это общее количество узлов в бинарном дереве. Вспомогательное пространство, необходимое программе, равно O(h) для стека вызовов, где h это высота дерева.

Читайте также:  Часть дерева покрытая листьями

Обратите внимание, что findDepth() рутина имеет оптимальное основание поскольку его можно рекурсивно разбить на более мелкие подпрограммы, т.е. findDepth(i) = 1 + findDepth(parent[i]) . Он также демонстрирует перекрывающиеся подзадачи так как одна и та же подзадача решается снова и снова.

Мы знаем, что задачи, имеющие оптимальную подструктуру и перекрывающиеся подзадачи, могут быть решены с помощью динамического программирования. Ниже приведена реализация динамического программирования на C, Java и Python, где решения подзадач памятка, а не вычисляется повторно. Решение использует вспомогательный массив для хранения глубины каждого узла.

Источник

how to find the height of a node in binary tree recursively

this is my sample code for find the Height, is defined as the length of the longest path by number of nodes from self to a leaf. The height of a leaf node is 1. it doesn’t work.

Actually, I just need an algorithm. Because, my code doesn’t work. And if you know the solution, maybe pseudo code 😛

@thg435 My guess is: «why doesn’t it work?» The poster seems to be struggling with English, so I would give him a break here. That being said, I wouldn’t give the code (since it looks like a homework to me), but explain some of the more blatant mistakes that he made.

@TGulmammadov: two options. Option 1: draw a tree on a piece of paper and try to find the height for any given node manually. Note your steps. Try to describe what you’re doing first in pseudocode and then in python. Option 2: sit back and wait for some nice guy to post the codez for you.

Do you have an example where it fails? How does it fail? Let me guess: it always counts the depth of the leftmost path, not of arbitrary paths?

6 Answers 6

What you’re doing isn’t recursive, it’s iterative. Recursive would be something like:

def height(node): if node is None: return 0 else: return max(height(node.left), height(node.right)) + 1 

return max(height(node.left), height(node.right)) + 1 returns a value >= 1 however leaf nodes have height zero. @mata Could you please clarify. Thanks.

@harishvc — Looking at the edit history, I had return -1 , which means a leaf would have a height of 0 (which is usually how the hight of a tree is defined), but the OP specified «The height of a leaf node is 1», so that’s probably why I changed it.

Читайте также:  Ингаляции при простуде чайное дерево

A leaf node will have None for node.left and node.right , therefore ending the recursion there, there’s no need to treat leaf or inner or root nodes differently.

@Illusionist — for any node the height ist the height of it’s largest child tree (that’s what the max function does) + 1. For a leaf node where both node.left and node.right are None heigh will return 0 for both and the recursion ends there.

You were given the solution by mata, but I suggest you also look at your code and understand what it is doing:

 while self.right != None: self = self.right path = path +1 

What will this do? it will find the right child, then its right child, and so on. So this checks only one path of the «rightmost» leaf.

This does the same for the left:

 while self.left != None: self = self.left path = path +1 

The idea in recursion is that for each subproblem, you solve it using the exact same recipe for all other subproblems. So if you would apply your algorithm only to a subtree or a leaf, it would still work.

Also, a recursive definition calls itself (although you can implement this with a loop, but that is beyond the scope here).

Recursion: see definition of Recursion.

Источник

Высота двоичного дерева в C/C++

Высота бинарного дерева определяется как максимальная глубина любого конечного узла от корневого узла. То есть это длина самого длинного пути от корневого узла до любого конечного узла.

Давайте рассмотрим приведенное ниже двоичное дерево.

Поскольку листовые узлы, соответствующие максимальной глубине, равны 40 и 50, чтобы найти высоту, мы просто находим количество ребер от корневого узла до любого из этих двух узлов, что равно 3.

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

Логика для нахождения высоты двоичного дерева в C++

Давайте теперь решим логику определения высоты и сначала напишем наш псевдокод.

Мы будем использовать рекурсию по дереву, чтобы найти высоту. (Концепции см. в статье Википедии)

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

Теперь мы можем применить определение высоты к поддеревьям.

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

Читайте также:  Грунтовка дерева эпоксидной смолой

Поскольку высота дерева равна максимальной высоте поддерева + 1, мы продолжаем делать это, пока поддерево не станет NULL , а его высота равна 0.

В этот момент наша функция окончательно завершится, и

Давайте напишем функцию tree_height() , которая вычисляет высоту.

// Find height of a tree, defined by the root node int tree_height(Node* root) < if (root == NULL) return 0; else < // Find the height of left, right subtrees left_height = tree_height(root->left); right_height = tree_height(root->right); // Find max(subtree_height) + 1 to get the height of the tree return max(left_height, right_height) + 1; > 

Строка №3 оценивает условие завершения, когда размер поддерева равен 0 или когда корневой узел имеет значение NULL .

Строки 7 и 8 рекурсивно находят высоту левого и правого поддеревьев.

И, наконец, строка 11 возвращает максимальное значение из двух, возвращая высоту дерева.

Реализация на С/С++

Ниже приведена полная программа, показывающая, как строится двоичное дерево, а затем показана логика определения высоты в tree_height() .

#include #include typedef struct Node Node; // Define the Tree Node here struct Node < int value; // Pointers to the left and right children Node* left, *right; >; Node* init_tree(int data) < // Creates the tree and returns the // root node Node* root = (Node*) malloc (sizeof(Node)); root->left = root->right = NULL; root->value = data; return root; > Node* create_node(int data) < // Creates a new node Node* node = (Node*) malloc (sizeof(Node)); node->value = data; node->left = node->right = NULL; return node; > void free_tree(Node* root) < // Deallocates memory corresponding // to every node in the tree. Node* temp = root; if (!temp) return; free_tree(temp->left); free_tree(temp->right); if (!temp->left && !temp->right) < free(temp); return; >> int tree_height(Node* root) < // Get the height of the tree if (!root) return 0; else < // Find the height of both subtrees // and use the larger one int left_height = tree_height(root->left); int right_height = tree_height(root->right); if (left_height >= right_height) return left_height + 1; else return right_height + 1; > > int main() < // Program to demonstrate finding the height of a Binary Tree // Create the root node having a value of 10 Node* root = init_tree(10); // Insert nodes onto the tree root->left = create_node(20); root->right = create_node(30); root->left->left = create_node(40); root->left->right = create_node(50); // Find the height of the tree int height = tree_height(root); printf("Height of the Binary Tree: %d\n", height); // Free the tree! free_tree(root); return 0; > 

Все права защищены. © Linux-Console.net • 2019-2023

Источник

Оцените статью