Cum vă validați un arbore binar de căutare?

voturi
54

Am citit pe aici de un exercițiu în interviuri cunoscute sub numele de validare a unui arbore binar de căutare.

Cum anume face acest lucru? Care ar fi unul în căutarea pentru validarea unui arbore binar de căutare? Am scris un copac de căutare de bază, dar nu au auzit de acest concept.

Întrebat 01/02/2009 la 02:41
sursa de către utilizator
În alte limbi...                            


30 răspunsuri

voturi
13

„Validarea“ un arbore binar de căutare înseamnă să verificați că acesta are într - adevăr toate articolele mai mici de pe elementele de stânga și mari pe dreapta. În esență, este o verificare pentru a vedea dacă un arbore binar este un binar de căutare copac.

Publicat 01/02/2009 la 02:44
sursa de către utilizator

voturi
106

De fapt, asta este greșeala fiecare face într-un interviu.

Leftchild trebuie să fie verificate împotriva (nod minLimitof, node.value)

Rightchild trebuie să fie verificate împotriva (node.value, MaxLimit de nod)

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

O altă soluție (dacă spațiul nu este o constrângere): Faceți o parcurgeri inordine a arborelui și a stoca valorile nod într-o matrice. În cazul în care matricea este în ordine sortată, sa o BST validă altfel nu.

Publicat 17/04/2009 la 11:11
sursa de către utilizator

voturi
5

Aici este soluția mea în 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)))
Publicat 08/01/2010 la 08:30
sursa de către utilizator

voturi
1

„Este mai bine să se definească un invariant primul aici invariantul e. - oricare două elemente secvențiale ale BST în traversal în ordine trebuie să fie în ordine crescătoare strict de aspectul lor (nu poate fi egal, mereu în creștere în ordine traversal). Deci, o soluție poate fi doar un simplu traversal în ordine cu amintindu ultimul nod și compararea au vizitat nodul curent față de vizitat ultima dată unul la „<“ (sau „>“).“

Publicat 30/03/2010 la 09:07
sursa de către utilizator

voturi
7

iterativ folosind inordine traversal.

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;
}
Publicat 29/04/2011 la 22:35
sursa de către utilizator

voturi
0

Soluție recursiv:

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)

    }
Publicat 05/09/2011 la 16:36
sursa de către utilizator

voturi
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;
}
Publicat 13/02/2012 la 21:08
sursa de către utilizator

voturi
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;
}
Publicat 14/02/2012 la 10:34
sursa de către utilizator

voturi
-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));
}
Publicat 05/03/2012 la 23:45
sursa de către utilizator

voturi
-1

Aici este soluția iterativ fără a utiliza spațiu suplimentar.

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;
    }
}
Publicat 07/04/2012 la 02:07
sursa de către utilizator

voturi
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)
            )
        )
    );
}
Publicat 20/05/2012 la 03:33
sursa de către utilizator

voturi
12

Cea mai bună soluție am găsit este O (n) și utilizează nici un spațiu suplimentar. Este similar cu traversal inorder, dar în loc de a depozita la matrice și apoi verifica dacă acesta este sortata putem lua o variabilă statică și verificați în timp ce inordine dacă dipozitive matrice este sortat.

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;
}
Publicat 06/06/2012 la 08:14
sursa de către utilizator

voturi
0

Pentru a afla dacă este dat BT BST pentru orice tip de date, aveți nevoie de du-te cu abordarea de mai jos. 1. functie recursiva pana la sfarsitul nodului frunzei, folosind inordine parcurgeri 2. Construiți-vă valorile minimă și maximă tine.

Element copac trebuie să aibă mai puțin de / mai mare decât operatorul definit.

#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;
}
Publicat 13/06/2012 la 18:16
sursa de către utilizator

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

Merge bine :)

Publicat 28/06/2012 la 11:24
sursa de către utilizator

voturi
0

Recursivitatea este ușor , dar abordare iterativă este mai bine, există o versiune iterativ de mai sus , dar este mult prea complexă decât este necesar. Aici este cea mai bună soluție în care c++le veți găsi vreodată oriunde:

Acest algoritm se execută în O(N)timp și are nevoie de O(lgN)spațiu.

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;
}
Publicat 04/11/2012 la 07:20
sursa de către utilizator

voturi
0

Am scris o soluție pentru a utiliza inorder Traversare BST și se verifică dacă nodurile este comanda în creștere pentru spațiu O(1)și de timp O(n). TreeNode predecessoreste prev nod. Nu sunt sigur că soluția este corect sau nu. Deoarece Inorder Traversare nu se poate defini un arbore întreg.

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;

}
Publicat 16/02/2013 la 03:25
sursa de către utilizator

voturi
0

În urma este implementarea Java de validare BST, în cazul în care călătorim copac în ordine DFS și returnează false dacă vom obține orice număr care este mai mare decât ultimul număr.

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;
  }
}
Publicat 18/01/2014 la 06:58
sursa de către utilizator

voturi
3

Având în vedere că în ordinea traversal unui BST este o secvență non-scădere, am putea folosi această proprietate pentru a judeca dacă un arbore binar este BST sau nu. Folosind Morris traversal și menținerea prenodul, am putea obține o soluție în O (n) și O (1) spațiu de complexitate. Aici este codul meu

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;
}
Publicat 18/10/2014 la 20:13
sursa de către utilizator

voturi
1

Am această întrebare într-un interviu telefonic recent și luptat cu ea mai mult decât ar fi trebuit. Am fost încercarea de a ține evidența și minime în nodurile copil maxime și nu am putut încadra creierul meu în jurul valorii de diferitele cazuri sub presiunea unui interviu.

Dupa ce sa gandit la asta in timp ce adormi noaptea trecută, am dat seama că este la fel de simplu ca și păstrarea evidența ultimului nod care le-ați vizitat în timpul unei parcurgeri inordine. În 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;
}
Publicat 10/12/2014 la 05:21
sursa de către utilizator

voturi
0

iterativ.

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;
}
Publicat 15/12/2014 la 14:44
sursa de către utilizator

voturi
0

Acest lucru funcționează pentru duplicate.

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

Aceasta funcționează chiar și pentru int.minși int.maxvalori , utilizând Nullabletipuri.

// 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)
Publicat 25/03/2015 la 08:16
sursa de către utilizator

voturi
0

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

Există două soluții generale: parcurgeri și diviza && cuceri.

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);
    }
}
Publicat 07/10/2015 la 05:24
sursa de către utilizator

voturi
-3

Aici este soluția mea recursiv scris în 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);
}
Publicat 19/10/2015 la 03:29
sursa de către utilizator

voturi
1

În Java și care permit noduri cu aceeași valoare, fie 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);
}
Publicat 10/09/2016 la 05:03
sursa de către utilizator

voturi
-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");
        }
    }
}
Publicat 20/11/2017 la 20:30
sursa de către utilizator

voturi
2

Iată răspunsul meu în Python, are toate cazurile de colț abordate și bine testate în site - ul 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)
Publicat 26/12/2017 la 18:04
sursa de către utilizator

voturi
0

O linie

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

Destul de linie lungă, totuși.

Publicat 15/01/2018 la 19:12
sursa de către utilizator

voturi
0

Iată o soluție în java din clasa algoritmul lui Sedgewick. Verificați punerea în aplicare completă BST aici

Am adăugat câteva comentarii explicative

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

}
Publicat 30/10/2018 la 23:02
sursa de către utilizator

voturi
0
  • iterativeFuncție verifică iterativ dacă arborele dat este un arbore binar de căutare.
  • recurseFuncție verifică recursiv dacă arborele dat este un arbore binar de căutare sau nu.
  • În iterativefuncție Eu folosesc pentru verificarea BST BFS.
  • În recursefuncție Eu folosesc DFS pentru verificarea BST.
  • Ambele soluții au o complexitate timp de O(n)
  • iterativesoluție are un avantaj față de recursesoluție și că este o iterativesoluție de oprire nu mai devreme.
  • Chiar și recursefuncția poate fi optimizată pentru oprirea timpurie de valoare pavilion la nivel mondial.
  • Ideea atât a soluției este că copilul stânga ar trebui să fie în intervalul de -infinity la valoarea nodului părinte whihch este nodul rădăcină
  • Copilul drept ar trebui să fie în intervalul de la + infinit la valoarea nodului părinte whihch este nodul rădăcină
  • Și du-te pe compararea valorii nodului curent în intervalul. În cazul în care valoarea oricărui nod nu este în intervalul de atunci 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)
    
Publicat 01/11/2018 la 03:22
sursa de către utilizator

voturi
0

implementare Python exemplu. Acest exemplu utilizează tip adnotări. Cu toate acestea, deoarece clasa Node se folosește trebuie să includă ca o primă linie a modulului:

from __future__ import annotations

În caz contrar, veți primi name 'Node' is not definederoare. Acest exemplu folosește dataclass ca exemplu. Pentru a verifica dacă este BST - l folosește recursivitate pentru verificarea valorilor noduri din stânga și din dreapta.

"""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))
Publicat 16/01/2019 la 00:10
sursa de către utilizator

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