💡 Во-первых, надо понимать отличие простого двоичного поискового дерева от сбалансированного.

Двоичное дерево поиска называется сбалансированным по высоте, если для каждой его вершины высоты левого и правого поддеревьев различаются не больше, чем на $1$.

➡ В теории структур данных такие деревья называют AVL-tree.

Сейчас я покажу $2$ сбалансированных по высоте двоичных дерева поиска.

сбалансированное по высоте двоичное дерево поиска

Рисунок — сбалансированное по высоте двоичное дерево поиска

идеально сбалансированное двоичное дерево поиска

Рисунок — идеально сбалансированное двоичное дерево поиска

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

💡 В-третьих, построение дерева не должно зависеть от количества элементов массива. Речь про четное или нечетное количество элементов массива. То есть алгоритм формирования дерева должен быть универсальным ( это одно из базовых свойств алгоритма — массовость ).

💡 В-четвертых, обязательно массив чисел, на основе которого получается дерево, должен быть отсортирован. Если это условие не выполняется, то полученное дерево не будет являться сбалансированным ( будут перекосы ).

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

$5$ $8$ $12$ $20$ $33$ $38$ $49$ $50$ $77$ $91$ $99$ значение
$0$ $1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$ $9$ $10$ индекс

Всего в массиве $11$ целых чисел. Они упорядочены по возрастанию! Эти числа образуют последовательность на отрезке от $0$ до $10$ ( беру значения по индексам ).

➡ Формирование дерева будет происходить рекурсивно, так как это максимально удобно.

На каждом этапе я буду выбирать «центральный» элемент. Его индекс легко рассчитать по формуле: $\frac{[левая\ граница]\ +\ [правая\ граница]}{2}$.

➡ Этап #$1$.

Находим индекс центрального элемента: $\frac{0\ +\ 10}{2} = 5$. Значение этого элемента равно $38$. Очевидно, что вершина с этим значением будет корнем двоичного сбалансированного по высоте дерева.

$5$ $8$ $12$ $20$ $33$ $38$ $49$ $50$ $77$ $91$ $99$ значение
$0$ $1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$ $9$ $10$ индекс

добавление первой вершины

Числа, которые меньше $38$ ( $5,\ 8,\ 12,\ 20,\ 33$ ), будут добавлены в левое поддерево относительно корня, большие ( $49,\ 50,\ 77,\ 91,\ 99$ ), будут добавлены в правое поддерево.

➡ Этап #$2$.

Находим индекс «центрального» элемента, расположенного в левой части, относительно значения $38$: $\frac{0\ +\ 4}{2} = 2$. Значение этого элемента равно $12$.

$5$ $8$ $12$ $20$ $33$ $38$ $49$ $50$ $77$ $91$ $99$ значение
$0$ $1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$ $9$ $10$ индекс

💡 Есть такой нюанс, связанный с поведением рекурсивной функции, которая формирует дерево. Дело в том, что сначала строятся узлы левого поддерева, а затем достраиваются вершины из правого поддерева. По этой причине на этапе #$3$ сначала будут добавляться вершины в левое поддерево относительно узла $12$.

➡ Этап #$3$.

Индекс центрального элемента: $\frac{0\ +\ 1}{2} = 0$. Значение этого элемента равно $5$.

$5$ $8$ $12$ $20$ $33$ $38$ $49$ $50$ $77$ $91$ $99$ значение
$0$ $1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$ $9$ $10$ индекс

➡ Этап #$4$.

Индекс центрального элемента: $\frac{1\ +\ 1}{2} = 1$. Значение этого элемента равно $8$.

$5$ $8$ $12$ $20$ $33$ $38$ $49$ $50$ $77$ $91$ $99$ значение
$0$ $1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$ $9$ $10$ индекс

➡ Этап #$5$.

Индекс центрального элемента: $\frac{3\ +\ 4}{2} = 3$. Значение этого элемента равно $20$.

$5$ $8$ $12$ $20$ $33$ $38$ $49$ $50$ $77$ $91$ $99$ значение
$0$ $1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$ $9$ $10$ индекс

➡ Этап #$6$.

Индекс центрального элемента: $\frac{4\ +\ 4}{2} = 4$. Значение этого элемента равно $33$.

$5$ $8$ $12$ $20$ $33$ $38$ $49$ $50$ $77$ $91$ $99$ значение
$0$ $1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$ $9$ $10$ индекс

➡ В результате левое поддерево относительно корня ( вершина с ключом $38$ ) отстроено. Аналогичным образом формируется и правое поддерево.

На следующей картинке показано конечное сбалансированное по высоте двоичное дерево поиска, построенное на основе данных из приведенного массива целых чисел:

 полностью построенное сбалансированное бинарное дерево поиска

Рисунок — полностью построенное сбалансированное бинарное дерево поиска

А вот программная реализация функции с подробными комментариями, которая формирует сбалансированное по высоте двоичное дерево из массива:

Пример вызова этой функции. В результате переменная root будет указывать на корень построенного сбалансированного двоичного дерева поиска.

 

 

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

В целом алгоритм состоит из $2$ этапов:

➡ Нахождение в массиве числа.

➡ Вставка вершины в дерево.

Первый этап имеет сложность $O( 1 )$, то есть выполняется мгновенно. Второй этап требует $O( log( n ) )$, причем как в лучшем, так в среднем или худшем случае, так как двоичное дерево поиска является сбалансированным по высоте. Количество вставок равно количеству элементов заданного массива, следовательно, общая вычислительная сложность алгоритма построения сбалансированного дерева из массива будет $O( n\ \cdot\ log( n ) )$, где $n$ — количество элементов массива.

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

ВНИМАНИЕ Для заказа программы на бинарное дерево ( поиска ) пишите на мой электронный адрес proglabs@mail.ru