Иногда мне приходится проверять заданное двоичное дерево на то, что оно является поисковым деревом. То есть нужно четко понимать разницу между простым двоичным деревом и двоичным деревом поиска. Это не одно и то же!

На этом рисунке показано стандартное, ничем не примечательное бинарное поисковое дерево:

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

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

А теперь я покажу просто двоичное дерево, которое не является поисковым, хотя структурно оно выглядит идентично поисковому двоичному дереву:

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

Рисунок — бинарное дерево ( не поиска )

💡 Почему это двоичное дерево не является деревом поиска? Потому что для ряда узлов не выполняются главные свойства дерева поиска:

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

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

пример бинарного дерева, которое не является деревом поиска

Рисунок — выделенные ( красные ) узлы нарушают «поисковость» двоичного дерева

➡ Например, чем не угодил узел с ключом $32$? Дело в том, что эта вершина является правым сыном родительской вершины с ключом $83$, а правые сыновья должны иметь значение ключа больше родительского, а не меньше.

➡ А чем не угодил узел с ключом $99$? Прямым родителем этого узла является узел с ключом $81$. Пока все в порядке, так как правый сын имеет значение ключа больше родительского. Но косвенным родителем вершины с ключом $99$ также является и вершина ( кстати, эта вершина является корневой в данном двоичном дереве ) с ключом $88$. Значение $99$ больше, чем $88$, поэтому анализируемый узел с ключом $99$ должен оказаться в правом поддереве относительно вершины с ключом $88$, а по факту оказался в левом поддереве — ошибка.

➡ А что не так с целой группой вершин, имеющих ключи $28$, $36$, $78$, $80$? Дело в том, что все эти значения меньше, чем $88$, поэтому все эти вершины в бинарном дереве поиска оказались бы в левом поддереве относительно вершины с ключом $88$, а не в правом.

Я хочу запрограммировать на языке «чистый» Си функцию, которая бы проверяла заданное бинарное дерево на бинарное поисковое дерево! Это сделать сложнее, чем кажется с первого взгляда. Существует достаточно много алгоритмов этой идеи. Я предлагаю, как мне кажется, один из эффективнейших способов такой проверки.

При первом вызове этой рекурсивно-каскадной функции Is_bst() следует передать указатель на корень проверяемого двоичного дерева, а также границы ключей. В языке Си есть встроенные целочисленные лимитные константы, поэтому в своих программах эту функцию я вызываю так:

Пишите в комментариях, что непонятно по проверке двоичного дерева на «поисковость». Расскажите, какие алгоритмы проверки применяли на практике вы, а также оцените вычислительную сложность этих алгоритмов.

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