W jaki sposób sprawdzić poprawność wyszukiwanie binarne drzewo?

głosy
54

Czytałem tu o ćwiczeniu w wywiadach znanych jako walidacji przeszukiwanie binarne drzewo.

Jak dokładnie to działa? Co należałoby szukać w walidacji przeszukiwanie binarne drzewo? Pisałem podstawową drzewa wyszukiwania, ale nigdy nie słyszałem o tym pojęcia.

Utwórz 01/02/2009 o 02:41
źródło użytkownik
W innych językach...                            


30 odpowiedzi

głosy
13

„Użytkownik” wyszukiwanie binarne drzewo oznacza, że należy sprawdzić, czy rzeczywiście ma wszystkie mniejsze przedmioty na lewo i dużych przedmiotów po prawej stronie. Zasadniczo, to należy sprawdzić, czy binarne drzewo jest binarnym wyszukiwania drzewo.

Odpowiedział 01/02/2009 o 02:44
źródło użytkownik

głosy
106

Właściwie to jest każdy błąd ma w wywiadzie.

Leftchild muszą być sprawdzone przed (węzeł minLimitof, node.value)

Rightchild muszą być sprawdzone przed (node.value, MaxLimit węzła)

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;
}

Innym rozwiązaniem (jeśli przestrzeń nie jest przeszkodą): Czy jest przechodzenie inorder drzewa i przechowywać wartości węzłów w tablicy. Jeśli tablica jest posortowanych, jego prawidłowym BST inaczej nie.

Odpowiedział 17/04/2009 o 11:11
źródło użytkownik

głosy
5

Oto moje rozwiązanie w 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)))
Odpowiedział 08/01/2010 o 08:30
źródło użytkownik

głosy
1

„Lepiej, aby zdefiniować pierwszy niezmiennik Tutaj jest niezmienna. - każde dwa kolejne elementy BST w przechodzenie na zamówienie musi być w ściśle porządku rosnącym od ich wyglądu (częstość nie może być równe, zawsze rośnie w rzędu przechodzenie). Tak więc rozwiązanie może być tylko proste przechodzenie na zamówienie z pamiętając ostatnio odwiedzone węzeł i porównania bieżący węzeł przed ostatni odwiedził jeden do „<” (lub „>”).”

Odpowiedział 30/03/2010 o 09:07
źródło użytkownik

głosy
7

Rozwiązanie z wykorzystaniem iteracyjnego Inorder przechodzenia.

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;
}
Odpowiedział 29/04/2011 o 22:35
źródło użytkownik

głosy
0

Rekurencyjne rozwiązanie:

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)

    }
Odpowiedział 05/09/2011 o 16:36
źródło użytkownik

głosy
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;
}
Odpowiedział 13/02/2012 o 21:08
źródło użytkownik

głosy
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;
}
Odpowiedział 14/02/2012 o 10:34
źródło użytkownik

głosy
-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));
}
Odpowiedział 05/03/2012 o 23:45
źródło użytkownik

głosy
-1

Oto iteracyjny rozwiązanie bez użycia dodatkowego miejsca.

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;
    }
}
Odpowiedział 07/04/2012 o 02:07
źródło użytkownik

głosy
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)
            )
        )
    );
}
Odpowiedział 20/05/2012 o 03:33
źródło użytkownik

głosy
12

Najlepszym rozwiązaniem I znaleziono O (n) i nie korzysta z dodatkowej przestrzeni. Jest ona podobna do Inorder przechodzenie ale zamiast zapisywania go do tablicy, a następnie sprawdzenie, czy jest ono klasyfikowane możemy zmienną statyczną i sprawdzić podczas Inorder przejeżdżające czy tablica jest posortowana.

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;
}
Odpowiedział 06/06/2012 o 08:14
źródło użytkownik

głosy
0

Aby dowiedzieć się, czy dany BT jest dla każdego typu danych BST, trzeba iść z poniższej podejścia. 1. wywołanie funkcji rekurencyjnej do końca węzła liścia używając Inorder przechodzenie 2. Zbuduj swój min i max wartości siebie.

Element drzewa musi być mniejszy niż / większe niż określonymi przez operatora.

#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;
}
Odpowiedział 13/06/2012 o 18:16
źródło użytkownik

głosy
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;
}

Działa w porządku :)

Odpowiedział 28/06/2012 o 11:24
źródło użytkownik

głosy
0

Rekurencja jest łatwe, ale iteracyjne podejście jest lepsze, gdy jest jedna wersja iteracyjna powyżej, ale to zbyt skomplikowane, niż to konieczne. Oto najlepsze rozwiązanie w c++jakie kiedykolwiek znaleźć wszędzie:

Ten algorytm działa w O(N)czasie i wymaga O(lgN)przestrzeni.

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;
}
Odpowiedział 04/11/2012 o 07:20
źródło użytkownik

głosy
0

Napisałem rozwiązanie używać Inorder Traversal BST i sprawdzić, czy węzły zwiększa zamówienie na przestrzeni O(1)I czasu O(n). TreeNode predecessorprev jest węzeł. Nie jestem pewien, że rozwiązanie jest słuszne czy nie. Ponieważ Inorder Traversal nie można zdefiniować całe drzewo.

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;

}
Odpowiedział 16/02/2013 o 03:25
źródło użytkownik

głosy
0

Poniżej znajduje się implementacja Java walidacji BST, gdzie jedziemy drzewie DFS na zamówienie i zwraca fałsz jeśli mamy dowolną liczbę, która jest większa niż w poprzednim numerze.

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;
  }
}
Odpowiedział 18/01/2014 o 06:58
źródło użytkownik

głosy
3

Ponieważ przechodzenie na zamówienie z BST jest sekwencją non-spadek, mogliśmy wykorzystać tę właściwość, aby ocenić, czy binarne drzewo BST, czy nie. Korzystanie Morris przechodzenie i utrzymywanie prewęzeł, możemy uzyskać rozwiązanie w O (n) czasu i O (1) przestrzeni złożoności. Tu jest mój kodu

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;
}
Odpowiedział 18/10/2014 o 20:13
źródło użytkownik

głosy
1

Mam na to pytanie w rozmowie telefonicznej niedawno i walczył z nim więcej niż powinienem. Starałem się śledzić minima i maksima w węzłach potomnych, a ja po prostu nie mógł owinąć mój mózg wokół różnych przypadkach pod presją wywiadzie.

Po tym myśleć podczas zasypiania w nocy, zdałem sobie sprawę, że jest to tak proste, jak śledzenie ostatnich odwiedzonych podczas przechodzenia Inorder węzła. W języku 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;
}
Odpowiedział 10/12/2014 o 05:21
źródło użytkownik

głosy
0

Iteracyjny rozwiązanie.

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;
}
Odpowiedział 15/12/2014 o 14:44
źródło użytkownik

głosy
0

Działa to dla duplikatów.

// 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)

Działa to nawet dla int.mini int.maxwartości za pomocą Nullabletypów.

// 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)
Odpowiedział 25/03/2015 o 08:16
źródło użytkownik

głosy
0

Zainspirowany http://www.jiuzhang.com/solutions/validate-binary-search-tree/

Istnieją dwa główne rozwiązania: przejścia i podzielić && przejęcie.

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);
    }
}
Odpowiedział 07/10/2015 o 05:24
źródło użytkownik

głosy
-3

Tu jest moja rekurencyjne rozwiązanie napisane w 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);
}
Odpowiedział 19/10/2015 o 03:29
źródło użytkownik

głosy
1

W Javie i pozwalając węzłów o tej samej wartości w obu sub-tree:

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);
}
Odpowiedział 10/09/2016 o 05:03
źródło użytkownik

głosy
-1
 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");
        }
    }
}
Odpowiedział 20/11/2017 o 20:30
źródło użytkownik

głosy
2

Oto moja odpowiedź w Pythonie, posiada wszystkie przypadki narożne zająć i dobrze przetestowane w hackerrank stronie

""" 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)
Odpowiedział 26/12/2017 o 18:04
źródło użytkownik

głosy
0

One liner

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);
}

Dość długa linia chociaż.

Odpowiedział 15/01/2018 o 19:12
źródło użytkownik

głosy
0

Oto rozwiązanie w Javie z klasy algorytmu Sedgewick użytkownika. Sprawdź pełną realizację BST tutaj

Dodałem kilka uwag wyjaśniających

private boolean isBST() {
    return isBST(root, null, null);

}

private boolean isBST(Node x, Key min, Key max) {
    if (x == null) return true;
    // when checking right subtree min is key of x's parent
    if (min != null && x.key.compareTo(min) <= 0) return false;
    // when checking left subtree, max is key of x's parent
    if (max != null && x.key.compareTo(max) >= 0) return false;
    // check left subtree and right subtree
    return isBST(x.left, min, x.key) && isBST(x.right, x.key, max);

}
Odpowiedział 30/10/2018 o 23:02
źródło użytkownik

głosy
0
  • iterativeFunkcja sprawdza, czy dana iteracyjnie drzewo to drzewo binarne wyszukiwania.
  • recurseFunkcja sprawdza, czy dana rekurencyjnie drzewo jest wyszukiwanie binarne drzewo, czy nie.
  • W iterativefunkcji używam BFS sprawdzania BST.
  • W recursefunkcji używam DFS sprawdzania BST.
  • Oba rozwiązania mają złożoność czasową O(n)
  • iterativerozwiązanie ma przewagę nad recurseroztworem i to iterativerozwiązanie ma wczesne zatrzymanie.
  • Nawet recursefunkcja może być zoptymalizowana pod kątem wczesnego zatrzymanie globalnego wartości flagi.
  • Pomysł zarówno rozwiązania jest to, że lewa dziecko powinno być w zakresie od + infinity do wartości jego węzła nadrzędnego whihch jest węzeł główny
  • Prawo dziecka powinna mieścić się w przedziale od + nieskończoności do wartości jego węzła nadrzędnego whihch jest węzeł główny
  • I iść na porównywaniu wartości bieżący węzeł jest w zasięgu. Jeżeli jest to wartość dowolnego węzła nie mieści się w zakresie następnie return false

    class Solution:
        def isValidBST(self, root):
            """
            :type root: TreeNode
            :rtype: bool
            """
            return self.iterative(root)
            # return self.recurse(root, float("inf"), float("-inf"))
    
        def iterative(self, root):
            if not root:
                return True
    
            level = [[root, -float("inf"), float("inf")]]
    
            while level:
                next_level = []
    
                for element in level:
                    node, min_val, max_val = element
                    if min_val<node.val<max_val:
                        if node.left:
                            next_level.append([node.left, min_val, node.val])
                        if node.right:
                            next_level.append([node.right, node.val, max_val])
                    else:
                        return False
                level = next_level
    
            return True
    
        def recurse(self, root, maxi, mini):
            if root is None:
                return True
    
            if root.val < mini or root.val > maxi:
                return False
    
            return self.recurse(root.left, root.val-1, mini) and self.recurse(root.right, maxi, root.val+1)
    
Odpowiedział 01/11/2018 o 03:22
źródło użytkownik

głosy
0

implementacja Pythona przykładem. W tym przykładzie użyto wpisać adnotacje. Jednak ponieważ klasa Node używa się musimy to jako pierwsza linia modułu:

from __future__ import annotations

W przeciwnym razie, otrzymasz name 'Node' is not definedbłąd. Przykład ten również wykorzystuje dataclass jako przykład. Aby sprawdzić, czy to BST używa rekursji do sprawdzania wartości lewy i prawy węzłów.

"""Checks if Binary Search Tree (BST) is balanced"""

from __future__ import annotations
import sys
from dataclasses import dataclass

MAX_KEY = sys.maxsize
MIN_KEY = -sys.maxsize - 1


@dataclass
class Node:
    value: int
    left: Node
    right: Node

    @property
    def is_leaf(self) -> bool:
        """Check if node is a leaf"""
        return not self.left and not self.right


def is_bst(node: Node, min_value: int, max_value: int) -> bool:
    if node.value < min_value or max_value < node.value:
        return False
    elif node.is_leaf:
        return True

    return is_bst(node.left, min_value, node.value) and is_bst(
        node.right, node.value, max_value
    )


if __name__ == "__main__":
    node5 = Node(5, None, None)
    node25 = Node(25, None, None)
    node40 = Node(40, None, None)
    node10 = Node(10, None, None)

    # balanced tree
    node30 = Node(30, node25, node40)
    root = Node(20, node10, node30)
    print(is_bst(root, MIN_KEY, MAX_KEY))

    # unbalanced tree
    node30 = Node(30, node5, node40)
    root = Node(20, node10, node30)
    print(is_bst(root, MIN_KEY, MAX_KEY))
Odpowiedział 16/01/2019 o 00:10
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more