2009-02-01 5 views
52

Я прочитал здесь упражнение в интервью, известном как проверка двоичного дерева поиска.Как вы проверяете двоичное дерево поиска?

Как именно это работает? Что можно было бы искать при проверке двоичного дерева поиска? Я написал базовое дерево поиска, но никогда не слышал об этой концепции.

+23

Использовать обход по порядку и проверять, превышает ли каждый элемент, чем предыдущий элемент. – dalle

ответ

13

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

+0

@ j32: Страница, с которой вы связались, ничего не делает. Это просто doco ... –

+1

У этого есть апплет Java, который позволяет вам нарисовать двоичное дерево ... Во всяком случае, это был просто пример использования этого термина. – wj32

+7

сломанная страница, fyi – dotcomXY

104

На самом деле это ошибка, которую все делают в интервью.

LeftChild должен быть проверен против (minLimitof узла, node.value)

RightChild должен быть проверен против (node.value, MaxLimit узла)

IsValidBST(root,-infinity,infinity); 

bool IsValidBST(BinaryNode node, int MIN, int MAX) 
{ 
    if(node == null) 
     return true; 
    if(node.element > MIN 
     && node.element < MAX 
     && IsValidBST(node.left,MIN,node.element) 
     && IsValidBST(node.right,node.element,MAX)) 
     return true; 
    else 
     return false; 
} 

Другим решения (если пространство не является constraint): Проведите обход дерева по порядку и сохраните значения узлов в массиве. Если массив находится в отсортированном порядке, то его действительный BST в противном случае нет.

+28

«Другое решение (если пространство не является ограничением) Проведите обход дерева по порядку и сохраните значения узлов в массиве. Если массив находится в отсортированном порядке, то его действительный BST в противном случае нет». .. Ну, для этого вам не нужен _space_ или массив. Если вы можете сделать обход в первую очередь, и массив, который вы создадите, должен быть отсортирован, то каждый элемент, который вы посещаете во время обхода, должен быть больше (или в предельном случае равным) предыдущему, справа ? –

+0

Да. Я согласен с этим. но все же нам нужна одна глобальная переменная для назначения и доступа к предыдущему значению в рекурсивных вызовах. и его лучше, чем мой предыдущий пример, передавая (MIN, MAX) на каждый вызов и ешьте место на стеке. Спасибо – g0na

+0

Ваш алгоритм ошибочен ... как если бы у вас есть дерево с одним корнем значения: 2 и один правый ребенок со значением: 2, вы скажете, что это не BST, на самом деле это так. – Yarneo

5

Вот мое решение в Clojure:.

(defstruct BST :val :left :right) 

(defn in-order [bst] 
    (when-let [{:keys [val, left, right]} bst] 
    (lazy-seq 
     (concat (in-order left) (list val) (in-order right))))) 

(defn is-strictly-sorted? [col] 
    (every? 
    (fn [[a b]] (< a b)) 
    (partition 2 1 col))) 

(defn is-valid-BST [bst] 
    (is-strictly-sorted? (in-order bst))) 
1

«Это лучше определить инвариант первого Здесь инвариант - любые две последовательные элементы BST в обходе в заказ должен быть строго возрастающий порядок их появления (не может быть равным, всегда увеличиваться в обходном порядке). Таким образом, решение может быть просто простым обходным порядком с запоминанием последнего посещенного узла и сравнением текущего узла с последним посещенным до ' < '(или'> '). "

7

Итеративное решение с использованием обходного пути.

bool is_bst(Node *root) { 
    if (!root) 
    return true; 

    std::stack<Node*> stack; 
    bool started = false; 
    Node *node = root; 
    int prev_val; 

    while(true) { 
    if (node) { 
     stack.push(node); 
     node = node->left(); 
     continue; 
    } 
    if (stack.empty()) 
     break; 
    node = stack.top(); 
    stack.pop(); 

    /* beginning of bst check */ 
    if(!started) { 
     prev_val = node->val(); 
     started = true; 
    } else { 
     if (prev_val > node->val()) 
     return false; 
     prev_val = node->val(); 
    } 
    /* end of bst check */ 

    node = node->right(); 
    } 
    return true; 
} 
+0

Хорошо отметить, что рекурсивные решения иногда могут быть плохими новостями на экземпляре производства, если вы разбиваете стек – Grambot

0

Рекурсивный решение:

isBinary(root) 
    { 
     if root == null 
      return true 
     else if(root.left == NULL and root.right == NULL) 
      return true 
     else if(root.left == NULL) 
      if(root.right.element > root.element) 
       rerturn isBInary(root.right) 
     else if (root.left.element < root.element) 
       return isBinary(root.left) 
     else 
       return isBInary(root.left) and isBinary(root.right) 

    } 
+0

Когда он вернет false? – user2517839

+0

Это даже не вернет 'true', если синтаксис был проверен перед выполнением:' rerturn' и 'isBInary' должны это предотвратить. Никакой язык не упоминается, отступ несовместим, кажется, что пути к концу блока/функции не имеют явного возврата (это означает, что функция python без явного возврата вернет «None», интерпретируется как «False» в « boolean context ".) Вероятно, хуже, он показывает наиболее распространенную ошибку: ((.1 (.3.)) 2.) является * не * допустимым деревом поиска, но будет проходить тесты *, если есть левая (правая) поддерево, это корневой элемент должен быть меньше (больше), чем этот *, рассмотренный выше. – greybeard

+0

что, если левый -> правый элемент больше, чем корень. В этом случае указанная выше функция возвращает true, где она должна быть ложной. –

1
bool BinarySearchTree::validate() { 
    int minVal = -1; 
    int maxVal = -1; 
    return ValidateImpl(root, minVal, maxVal); 
} 

bool BinarySearchTree::ValidateImpl(Node *currRoot, int &minVal, int &maxVal) 
{ 
    int leftMin = -1; 
    int leftMax = -1; 
    int rightMin = -1; 
    int rightMax = -1; 

    if (currRoot == NULL) return true; 

    if (currRoot->left) { 
     if (currRoot->left->value < currRoot->value) { 
      if (!ValidateImpl(currRoot->left, leftMin, leftMax)) return false; 
      if (leftMax != currRoot->left->value && currRoot->value < leftMax) return false; 
     } 
     else 
      return false; 
    } else { 
     leftMin = leftMax = currRoot->value; 
    } 

    if (currRoot->right) { 
     if (currRoot->right->value > currRoot->value) { 
      if(!ValidateImpl(currRoot->right, rightMin, rightMax)) return false; 
      if (rightMin != currRoot->right->value && currRoot->value > rightMin) return false; 
     } 
     else return false; 
    } else { 
     rightMin = rightMax = currRoot->value; 
    } 

    minVal = leftMin < rightMin ? leftMin : rightMin; 
    maxVal = leftMax > rightMax ? leftMax : rightMax; 

    return true; 
} 
0
// using inorder traverse based Impl 
bool BinarySearchTree::validate() { 
    int val = -1; 
    return ValidateImpl(root, val); 
} 

// inorder traverse based Impl 
bool BinarySearchTree::ValidateImpl(Node *currRoot, int &val) { 
    if (currRoot == NULL) return true; 

    if (currRoot->left) { 
     if (currRoot->left->value > currRoot->value) return false; 
     if(!ValidateImpl(currRoot->left, val)) return false; 
    } 

    if (val > currRoot->value) return false; 
    val = currRoot->value; 

    if (currRoot->right) { 
     if (currRoot->right->value < currRoot->value) return false; 
     if(!ValidateImpl(currRoot->right, val)) return false; 
    } 
    return true; 
} 
-3
boolean isBST(Node root) { 
    if (root == null) { return true; } 
    return (isBST(root.left) && (isBST(root.right) && (root.left == null || root.left.data <= root.data) && (root.right == null || root.right.data > root.data)); 
} 
+0

Это неправильно. См. Ответ Скотта. – st0le

-1

Вот итерационный решение без использования дополнительного пространства.

Node{ 
    int value; 
    Node right, left 
    } 

    public boolean ValidateBST(Node root){ 
    Node currNode = root; 
    Node prevNode = null; 
    Stack<Node> stack = new Stack<Node>(); 
    while(true){ 
     if(currNode != null){ 
      stack.push(currNode); 
      currNode = currNode.left; 
      continue; 
     } 
     if(stack.empty()){ 
      return; 
     } 
     currNode = stack.pop(); 
     if(prevNode != null){ 
      if(currNode.value < prevNode.value){ 
       return false; 
      } 
     } 
     prevNode = currNode; 
     currNode = currNode.right; 
    } 
} 
+3

Итеративное решение без лишнего пространства? Но вы используете стек здесь и делаете 'stack.push()'! –

1
bool ValidateBST(Node *pCurrentNode, int nMin = INT_MIN, int nMax = INT_MAX) 
{ 
    return 
    (
     pCurrentNode == NULL 
    ) 
    || 
    (
     (
      !pCurrentNode->pLeftNode || 
      (
       pCurrentNode->pLeftNode->value < pCurrentNode->value && 
       pCurrentNode->pLeftNode->value < nMax && 
       ValidateBST(pCurrentNode->pLeftNode, nMin, pCurrentNode->value) 
      ) 
     ) 
     && 
     (
      !pCurrentNode->pRightNode || 
      (
       pCurrentNode->pRightNode->value > pCurrentNode->value && 
       pCurrentNode->pRightNode->value > nMin && 
       ValidateBST(pCurrentNode->pRightNode, pCurrentNode->value, nMax) 
      ) 
     ) 
    ); 
} 
+0

Мое намерение - показать другое решение, в котором рекурсия _doesn't_ переходит в ветвь, если она не действительна. Текущий верхний ответ _must_ перейдите в ветку, чтобы проверить ее достоверность ... –

+0

* Если * «2-й проверит 3», где было изменено на «nMin pLeftNode-> value» и «pCurrentNode-> pRightNode-> значение greybeard

12

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

static struct node *prev = NULL; 

bool isBST(struct node* root) 
{ 
    // traverse the tree in inorder fashion and keep track of prev node 
    if (root) 
    { 
     if (!isBST(root->left)) 
      return false; 

     // Allows only distinct valued nodes 
     if (prev != NULL && root->data <= prev->data) 
      return false; 

     prev = root; 

     return isBST(root->right); 
    } 

    return true; 
} 
+0

Спасибо, что поделились этим. Вопрос: если я не ошибаюсь, ваш алгоритм фактически занимает O (n) пространство из-за стека вызовов из-за рекурсивности. Я что-то упустил? Тем не менее, это очень просто! – andrew

+0

На самом деле, сложность пространства вашего алгоритма может быть O (log n) для сбалансированного дерева [как указано здесь] (http://stackoverflow.com/questions/21546611/space-complexity-of-validation-of-a- двоично-поиск-дерево/21546734 # 21546734). – andrew

+0

Я пробовал модифицировать это без использования статической переменной, но не смог! Как вы думаете ? Спасибо –

0

Чтобы узнать, является ли данный BT BST для любого типа данных, вам нужно пойти с подходом ниже. 1. вызвать рекурсивную функцию до конца листового узла с использованием обходного порядка 2. Создайте свои минимальные и максимальные значения самостоятельно.

Элемент дерева должен иметь меньше или больше заданного оператора.

#define MIN (FirstVal, SecondVal) ((FirstVal) < (SecondVal)) ? (FirstVal):(SecondVal) 
#define MAX (FirstVal, SecondVal) ((FirstVal) > (SecondVal)) ? (FirstVal):(SecondVal) 

template <class T> 
bool IsValidBST (treeNode &root) 
{ 

    T min, max; 
    return IsValidBST (root, &min, &max); 
} 

template <class T> 
bool IsValidBST (treeNode *root, T *MIN , T *MAX) 
{ 
    T leftMin, leftMax, rightMin, rightMax; 
    bool isValidBST; 

    if (root->leftNode == NULL && root->rightNode == NULL) 
    { 
     *MIN = root->element; 
     *MAX = root->element; 
     return true; 
    } 

    isValidBST = IsValidBST (root->leftNode, &leftMin, &leftMax); 

    if (isValidBST) 
    isValidBST = IsValidBST (root->rightNode, &rightMin, &rightMax); 

    if (isValidBST) 
    { 
    *MIN = MIN (leftMIN, rightMIN); 
    *Max = MAX (rightMax, leftMax); 
    } 

    return isValidBST; 
} 
+0

Возможно, вам необходимо исправить ваш код - вы сделали предварительные макросы MIN и MAX, но затем попытайтесь использовать MIN и MAX в качестве переменных (параметров). – MikeB

+0

'вам нужно пойти с подходом к подходу' - нет: для восходящего подхода см.' IsBSTDivideAndConquer() 'в [ответе Lei Cao] (https://stackoverflow.com/a/32984413/3789665). – greybeard

0
bool isBST(struct node* root) 
{ 
    static struct node *prev = NULL; 
    // traverse the tree in inorder fashion and keep track of prev node 
    if (root) 
    { 
     if (!isBST(root->left)) 
      return false; 
     // Allows only distinct valued nodes 
     if (prev != NULL && root->data <= prev->data) 
      return false; 
     prev = root; 
     return isBST(root->right); 
    } 
    return true; 
} 

работает отлично :)

+1

Это не работает, если вы вызываете его более одного раза, а также не потокобезопасны. – Andrey

0

рекурсии легко, но итерационный подход лучше, есть один итерационный вариант выше, но это слишком сложно, чем это необходимо. Вот решение лучше в c++ вы когда-нибудь где-нибудь:

Этот алгоритм работает в O(N) времени и нуждается в O(lgN) пространство.

struct TreeNode 
{ 
    int value; 
    TreeNode* left; 
    TreeNode* right; 
}; 

bool isBST(TreeNode* root) { 
    vector<TreeNode*> stack; 
    TreeNode* prev = nullptr; 
    while (root || stack.size()) { 
     if (root) { 
      stack.push_back(root); 
      root = root->left; 
     } else { 
      if (prev && stack.back()->value <= prev->value) 
       return false; 
      prev = stack.back(); 
      root = prev->right;      
      stack.pop_back(); 
     } 
    } 
    return true; 
} 
+0

Этот код, похоже, не обнаруживает повторяющиеся значения. – MikeB

+0

Я думаю, что да, вы можете построить встречный пример? – shuais

+0

Тривиально: дерево двух узлов, которое имеет одно и то же целое число в «значении» обоих узлов, все равно будет иметь функцию isBST(), возвращающую «true». Поскольку вы возвращаете false только при значении <значение, вы никогда не обнаружите его. Почему вы думаете, что тест работает, чтобы найти дубликаты? – MikeB

0

Я написал решение использовать Симметричный Traversal BST и проверить, является ли узлы в порядке возрастания для пространства O(1) и времени O(n). TreeNode predecessor - это предыдущий узел. Я не уверен, что это правильно или нет. Поскольку обход границы не может определить целое дерево.

public boolean isValidBST(TreeNode root, TreeNode predecessor) { 
    boolean left = true, right = true; 
    if (root.left != null) { 
     left = isValidBST(root.left, predecessor); 
    } 
    if (!left) 
     return false; 

    if (predecessor.val > root.val) 
     return false; 

    predecessor.val = root.val; 
    if (root.right != null) { 
     right = isValidBST(root.right, predecessor); 
    } 

    if (!right) 
     return false; 

    return true; 

} 
+0

'space O (1)' игнорирование стека вызовов - для «правильного решения O (1)» «см. [Использование ответа 36805] (https://stackoverflow.com/a/26443551/3789665). – greybeard

0

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

static class BSTValidator { 
    private boolean lastNumberInitialized = false; 
    private int lastNumber = -1; 

    boolean isValidBST(TreeNode node) { 
    if (node.left != null && !isValidBST(node.left)) return false; 

    // In-order visiting should never see number less than previous 
    // in valid BST. 
    if (lastNumberInitialized && (lastNumber > node.getData())) return false; 
    if (!lastNumberInitialized) lastNumberInitialized = true; 

    lastNumber = node.getData(); 

    if (node.right != null && !isValidBST(node.right)) return false; 

    return true; 
    } 
} 
+0

('private Integer lastNumber;' будет казаться жизнеспособной, но не полностью эквивалентной альтернативой.) – greybeard

3

Поскольку в заказе обход из BST не является снижение последовательности, мы можем использовать это свойство, чтобы судить о том, бинарное дерево BST или нет. Используя Morris traversal и поддерживая узел pre, мы могли бы получить решение в O (n) времени и O (1) пространстве сложности. Вот мой код

public boolean isValidBST(TreeNode root) { 
    TreeNode pre = null, cur = root, tmp; 
    while(cur != null) { 
     if(cur.left == null) { 
      if(pre != null && pre.val >= cur.val) 
       return false; 
      pre = cur; 
      cur = cur.right; 
     } 
     else { 
      tmp = cur.left; 
      while(tmp.right != null && tmp.right != cur) 
       tmp = tmp.right; 
      if(tmp.right == null) { // left child has not been visited 
       tmp.right = cur; 
       cur = cur.left; 
      } 
      else { // left child has been visited already 
       tmp.right = null; 
       if(pre != null && pre.val >= cur.val) 
        return false; 
       pre = cur; 
       cur = cur.right; 
      } 
     } 
    } 
    return true; 
} 
+0

(Быть 'public',' boolean isValidBST() '* необходимо * комментарий, что он временно * аннулирует * структуру дерева - возможно, даже усталость и объяснение, когда все в порядке, чтобы использовать его.) – greybeard

1

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

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

public <T extends Comparable<T>> boolean isBst(TreeNode<T> root) { 
    return isBst(root, null); 
} 

private <T extends Comparable<T>> boolean isBst(TreeNode<T> node, TreeNode<T> prev) { 
    if (node == null) 
     return true; 

    if (isBst(node.left, prev) && (prev == null || prev.compareTo(node) < 0)) 
     return isBst(node.right, node); 

    return false; 
} 
+0

Только «половина права»: ловит «низкие узлы» в правых поддеревах, пропускает «высокие узлы» слева (даже не пытается и не распространяет «самый правый»/высшие "значения). Для успешной реализации, хотя и с использованием «глобальной» переменной, см. Ответ [Aayush Bahuguna] (https://stackoverflow.com/a/10909724/3789665), – greybeard

0

Итерационное решение.

private static boolean checkBst(bst node) { 

    Stack<bst> s = new Stack<bst>(); 
    bst temp; 
    while(node!=null){ 
     s.push(node); 
     node=node.left; 
    } 
    while (!s.isEmpty()){ 
     node = s.pop(); 
     System.out.println(node.val); 
     temp = node; 
     if(node.right!=null){ 
      node = node.right; 
      while(node!=null) 
      { 
       //Checking if the current value is lesser than the previous value and ancestor. 
       if(node.val < temp.val) 
        return false; 
       if(!s.isEmpty()) 
        if(node.val>s.peek().val) 
         return false; 
       s.push(node); 
       if(node!=null) 
       node=node.left; 
      } 
     } 
    } 
    return true; 
} 
0

Это работает для дубликатов.

// time O(n), space O(logn) 
// pseudocode 
is-bst(node, min = int.min, max = int.max): 
    if node == null: 
     return true 
    if node.value <= min || max < node.value: 
     return false 
    return is-bst(node.left, min, node.value) 
     && is-bst(node.right, node.value, max) 

Это работает даже для int.min и int.max значений с помощью Nullable типов.

// time O(n), space O(logn) 
// pseudocode 
is-bst(node, min = null, max = null): 
    if node == null: 
     return true 
    if min != null && node.value <= min 
     return false 
    if max != null && max < node.value: 
     return false 
    return is-bst(node.left, min, node.value) 
     && is-bst(node.right, node.value, max) 
0

Вдохновленный http://www.jiuzhang.com/solutions/validate-binary-search-tree/

Есть два основных решения: обход и разделить & & властвуй.

public class validateBinarySearchTree { 
    public boolean isValidBST(TreeNode root) { 
     return isBSTTraversal(root) && isBSTDivideAndConquer(root); 
    } 

    // Solution 1: Traversal 
    // The inorder sequence of a BST is a sorted ascending list 
    private int lastValue = 0; // the init value of it doesn't matter. 
    private boolean firstNode = true; 
    public boolean isBSTTraversal(TreeNode root) { 
     if (root == null) { 
      return true; 
     } 

     if (!isValidBST(root.left)) { 
      return false; 
     } 

     // firstNode is needed because of if firstNode is Integer.MIN_VALUE, 
     // even if we set lastValue to Integer.MIN_VALUE, it will still return false 
     if (!firstNode && lastValue >= root.val) { 
      return false; 
     } 

     firstNode = false; 
     lastValue = root.val; 

     if (!isValidBST(root.right)) { 
      return false; 
     } 

     return true; 

    } 

    // Solution 2: divide && conquer 
    private class Result { 
     int min; 
     int max; 
     boolean isBST; 
     Result(int min, int max, boolean isBST) { 
      this.min = min; 
      this.max = max; 
      this.isBST = isBST; 
     } 
    } 

    public boolean isBSTDivideAndConquer(TreeNode root) { 
     return isBSTHelper(root).isBST; 
    } 

    public Result isBSTHelper(TreeNode root) { 
     // For leaf node's left or right 
     if (root == null) { 
      // we set min to Integer.MAX_VALUE and max to Integer.MIN_VALUE 
      // because of in the previous level which is the leaf level, 
      // we want to set the min or max to that leaf node's val (in the last return line) 
      return new Result(Integer.MAX_VALUE, Integer.MIN_VALUE, true); 
     } 

     Result left = isBSTHelper(root.left); 
     Result right = isBSTHelper(root.right); 

     if (!left.isBST || !right.isBST) { 
      return new Result(0,0, false); 
     } 

     // For non-leaf node 
     if (root.left != null && left.max >= root.val 
       && root.right != null && right.min <= root.val) { 
      return new Result(0, 0, false); 
     } 

     return new Result(Math.min(left.min, root.val), 
       Math.max(right.max, root.val), true); 
    } 
} 
+0

Последние два утверждения 'boolean isBSTTraversal()' могут быть объединены для 'return isValidBST (root.right);'. В 'Result isBSTHelper()', требуя, чтобы 'root.val' был * оба * не больше, чем' left.max' * и * не меньше, чем 'right.min' для« false 'Result'» не кажется Совершенно верно. – greybeard

-3

Вот мое рекурсивное решение написано в JavaScript

function isBST(tree) { 
    if (tree === null) return true; 

    if (tree.left != undefined && tree.left.value > tree.value) { 
    return false; 
    } 

    if (tree.right != undefined && tree.right.value <= tree.value) { 
    return false; 
    } 

    return isBST(tree.left) && isBST(tree.right); 
} 
1

В Java и позволяет узлы с одинаковым значением в любом поддереве:

public boolean isValid(Node node) { 
    return isValid(node, Integer.MIN_VALUE, Integer.MAX_VALUE); 
} 

private boolean isValid(Node node, int minLimit, int maxLimit) { 
    if (node == null) 
     return true; 
    return minLimit <= node.value && node.value <= maxLimit 
      && isValid(node.left, minLimit, node.value) 
      && isValid(node.right, node.value, maxLimit); 
} 
0
private void validateBinarySearchTree(Node node) { 
    if (node == null) return; 

    Node left = node.getLeft(); 
    if (left != null) { 
     if (left.getData() < node.getData()) { 
      validateBinarySearchTree(left); 
     } else { 
      throw new IllegalStateException("Not a valid Binary Search tree"); 
     } 
    } 

    Node right = node.getRight(); 
    if (right != null) { 
     if (right.getData() > node.getData()) { 
      validateBinarySearchTree(right); 
     } else { 
      throw new IllegalStateException("Not a valid Binary Search tree"); 
     } 
    } 
} 
2

Вот мой ответ в python, он имеет все угловые случаи, адресованные и хорошо протестированные в сайт hackerrank

""" Node is defined as 
class node: 
    def __init__(self, data): 
     self.data = data 
     self.left = None 
     self.right = None 
""" 

def checkBST(root): 
    return checkLeftSubTree(root, root.left) and checkRightSubTree(root, root.right) 

def checkLeftSubTree(root, subTree): 
    if not subTree: 
     return True 
    else: 
     return root.data > subTree.data \ 
     and checkLeftSubTree(root, subTree.left) \ 
     and checkLeftSubTree(root, subTree.right) \ 
     and checkLeftSubTree(subTree, subTree.left) \ 
     and checkRightSubTree(subTree, subTree.right) 

def checkRightSubTree(root, subTree): 
    if not subTree: 
     return True 
    else: 
     return root.data < subTree.data \ 
     and checkRightSubTree(root, subTree.left) \ 
     and checkRightSubTree(root, subTree.right) \ 
     and checkRightSubTree(subTree, subTree.right) \ 
     and checkLeftSubTree(subTree, subTree.left) 
0

Один лайнер

bool is_bst(Node *root, int from, int to) { 
    return (root == NULL) ? true : 
    root->val >= from && root->val <= to && 
    is_bst(root->left, from, root->val) && 
    is_bst(root->right, root->val, to); 
} 

Довольно длинная линия, хотя.

Смежные вопросы