zoukankan      html  css  js  c++  java
  • BST construction

    BST construction

    refer to : https://www.algoexpert.io/questions/BST%20Construction


    1. 什么是二叉搜索树?

    二叉搜索树是二叉树的一种特殊形式,而二叉树的特性在于每个节点包含最多两个子节点。

    二叉搜索树的特性:每个节点的值都大于或等于它的左子树的值,小于或等于它的右子树的值,左子树和右子树分别也应该是BST。

    Let x be a node in a bst, if y is a node in the left subtree of x, then y.key <= x.key. If y is a node in the right subtree of x, then y.key >= x.key.

    --From 《Introduction to Algorithms. Third Edition》

    2. Insertion && Search && Deletion (iterative method)


     

    插入: 从根部开始遍历,比较当前节点的值和待插入的值,充分利用BST的特性,逐步eliminate half subtree(剪枝)直到找到没有子节点的适当位置(check if currNode.left/currNode.right == null or not),if it is, 直接插入该值, if not, continue eliminating half subtree。

    Two big cases considered: 

    currNode.value > value &&
    currNode.value <= value

    
    

    查找: 从根部开始查找,比较当前节点的值和目标值,充分利用BST的特性,逐步eliminate half subtree(剪枝),找到之后(currNode.value == value), return true.

    Three big cases considered: 

    currNode.value > value &&
    currNode.value < value &&
    currNode.value == value


    删除: 主要分为两大步: step 1. 查找待删除的元素。 step 2.删除该元素
    删除的时候有很多情况:
    • currNode has two children
    1. reassign the smallest value of the right subtree to currNode
    currNode.value = currNode.right.getMinValue(); 2. remove the smallest value of the right subtree (currNode.value == leftmost value of the right subtree))
    • currNode is at the root node and only has one child,

            5.     only has left child , 假如要删除5, currNode = 5,

         /

        3                  3

          \               /  \

           4.           2     4

        /

       2


    5      only has right child.  假如要删除5, currNode = 5,

     \

        8.            8

      /            /   \

    6.           6       7 

    \

     7      

       

    一步步更新各个节点(记住)

                                 if(currNode.left != null){
     77                             currNode.value = currNode.left.value; //把left.value挪到currNode 
     78                             currNode.right = currNode.left.right;//大的值挪到右子树
     79                             currNode.left = currNode.left.left;//小的挪到左子树
     80                         }else if(currNode.right != null){
     81                             currNode.value = currNode.right.value;
     82                             currNode.left = currNode.right.left;   //right.left must be less than right.value
     83                             currNode.right = currNode.right.right;  //right.right must be larger than right.value
     84                         }else{
     85                             //currNode = null;
     86                             //this is a single-node tree; need to discuss with the interviewer
     87                         }
    • currNode has one children, but the parentNode is not None,套用例子理解
     5   假如要删除3,3 is currNode, 5 is the parentNode,4被挪到5的左子树,而根据bst的特性,它一定小于5
    /
    3
    \
    4

    5 假如要删除7,7 is currNode, 5 is the parentNode,6会被挪到右子树,它一定大于5
     \
    7
    /
    6

    充分利用parentNode
    88                      if(parentNode.left == currNode){ //parentNode != null
     89                         parentNode.left = (currNode.left != null ? currNode.left: currNode.right);
     90                     }if(parentNode.right == currNode){
     91                         parentNode.right = (currNode.left != null ? currNode.left: currNode.right);
     92                     }

    
    

    In these cases, we allow the duplicate values, if any duplicates, let the value being the right child.

    On average: O(logn) time complexity | O(1) space complexity

    Worst case: O(n) time complexity | O(1) space complexity

      1 import java.util.*;
      2 
      3 class Program {
      4   static class BST {
      5     public int value;
      6     public BST left;
      7     public BST right;
      8 
      9     public BST(int value) {
     10       this.value = value;
     11     }
     12 
     13     public BST insert(int value) {
     14             BST currNode = this;
     15             while(true){
     16                 if(currNode.value > value){
     17                     if(currNode.left == null){
     18                         BST newNode = new BST(value);
     19                         currNode.left = newNode;
     20                         break; // successfully inserted
     21                     }else{
     22                         currNode = currNode.left;
     23                     }
     24                 }else{ //currNode.right <= value !!!notes
     25                     if(currNode.right == null){
     26                         BST newNode = new BST(value);
     27                         currNode.right = newNode;
     28                         break; //successfully inserted
     29                     }else{
     30                         currNode = currNode.right;
     31                     }
     32                 }
     33             }
     34       return this;
     35     }
     36 
     37     public boolean contains(int value) {
     38       BST currNode = this;
     39             while(currNode != null){
     40                 if(currNode.value > value){
     41                     currNode = currNode.left;
     42                 }else if(currNode.value < value){
     43                     currNode = currNode.right;
     44                 }else{  //currNode.value == value
     45                     return true;
     46                 }
     47             }
     48             
     49       return false;
     50     }
     51 
     52     public BST remove(int value) {
     53       remove(value,null);
     54       return this;
     55     }
     56         
     57         public void remove(int value, BST parentNode){
     58             BST currNode = this;
     59             //step 1. find the value
     60             while(currNode != null){
     61                 if(currNode.value > value){
     62                     parentNode = currNode; //reassign the parentNode firstly.
     63                     currNode = currNode.left;            
     64                 }else if(currNode.value < value){
     65                     parentNode = currNode;
     66                     currNode = currNode.right;
     67                 }else{ //we find the value, the next step is to remove this value
     68                     if(currNode.left != null && currNode.right != null){
     69                         //currNode has two children 
     70                         //1. reassign the smallest value of the right subtree to currNode
     71                         currNode.value = currNode.right.getMinValue();
     72                         //2. remove the smallest value of the right subtree
     73                         //(currNode.value == leftmost value of the right subtree))
     74                         currNode.right.remove(currNode.value, currNode);
     75                     }else if(parentNode == null){
     76                         if(currNode.left != null){
     77                             currNode.value = currNode.left.value;
     78                             currNode.right = currNode.left.right;
     79                             currNode.left = currNode.left.left;
     80                         }else if(currNode.right != null){
     81                             currNode.value = currNode.right.value;
     82                             currNode.left = currNode.right.left;
     83                             currNode.right = currNode.right.right;
     84                         }else{
     85                             //currNode = null;
     86                             //this is a single-node tree; need to discuss with the interviewer
     87                         }
     88                     }else if(parentNode.left == currNode){ //parentNode != null
     89                         parentNode.left = currNode.left != null ? currNode.left: currNode.right;
     90                     }else if(parentNode.right == currNode){
     91                         parentNode.right = currNode.left != null ? currNode.left: currNode.right;
     92                     }
     93                     break;
     94                 }
     95             }
     96         }
     97         
     98         public int getMinValue(){
     99             if (left == null){
    100                 return value;
    101             }else{
    102                 return left.getMinValue();
    103             }
    104         }
    105   }
    106 }
     1 class BST:
     2     def __init__(self, value):
     3         self.value = value
     4         self.left = None
     5         self.right = None
     6 
     7     def insert(self, value):
     8         currNode = self
     9         while True:    #True, uppercase
    10             if currNode.value > value:
    11                 if currNode.left is None:
    12                     currNode.left = BST(value)
    13                     break # do not forget break!!!
    14                 else:
    15                     currNode = currNode.left
    16             else:
    17                 if currNode.right is None:
    18                     currNode.right = BST(value)
    19                     break  # do not forget break!!!
    20                 else:
    21                     currNode = currNode.right
    22         return self
    23 
    24     def contains(self, value):
    25         currNode = self
    26         while currNode is not None: # is not while True in this case!!!
    27             if currNode.value > value:
    28                 currNode = currNode.left
    29             elif currNode.value < value:
    30                 currNode = currNode.right
    31             else:
    32                 return True
    33         return False # never found the value
    34         
    35 
    36     def remove(self, value, parentNode = None):
    37         # step 1. find the value you want to remove
    38         currNode = self
    39         while currNode is not None:
    40             if currNode.value > value:
    41                 parentNode = currNode # trace the parentNode
    42                 currNode = currNode.left
    43             elif currNode.value < value:
    44                 parentNode = currNode
    45                 currNode = currNode.right
    46         # step 2. remove this value
    47         
    48             else: # find the value
    49                 # case 1, the currNode has two children
    50                 if currNode.left is not None and currNode.right is not None:
    51                     #resign the currNode value to the smallest value
    52                     currNode.value = currNode.right.getMinValue()
    53                     # remove the smallest value
    54                     currNode.right.remove(currNode.value, currNode)
    55                 elif parentNode is None: # at the root node and only has one child
    56                     if currNode.left is not None:
    57                         currNode.value = currNode.left.value
    58                         currNode.right = currNode.left.right
    59                         currNode.left = currNode.left.left #ressign the currNode.left at last
    60                     elif currNode.right is not None:
    61                         currNode.value = currNode.right.value
    62                         currNode.left = currNode.right.left
    63                         currNode.right = currNode.right.right#ressign the currNode.right at last
    64                     else:
    65                         # this is a single-node; do nothing
    66                         # discuss with the interviewer
    67                         # currNode.value = None
    68                         pass
    69                 # case 2, the node has one children, but the parentNode is not None
    70                 elif parentNode.left == currNode: # the currNode is the left child
    71                     parentNode.left = currNode.left if currNode.left is not None else currNode.right
    72                 elif parentNode.right == currNode:
    73                     parentNode.right = currNode.left if currNode.left is not None else currNode.right
    74                 # 5
    75                 #/
    76                #3
    77                 #\
    78                  #4
    79                 break    
    80         
    81         return self
    82     
    83     def getMinValue(self):
    84         currNode = self
    85         while currNode.left is not None:
    86             currNode = currNode.left
    87         return currNode.value # currNode.left is None

     

     

  • 相关阅读:
    Inno Setup命令行安装卸载参数
    Fragment生命周期
    ubuntu 64位系统下加速Android模拟器
    Java中对SQLite数据库操作 操作db文件
    系统权限管理设计
    java 中的序列化是什么意思?有什么好处?
    js实现定时调用的函数setInterval()
    tomcat 并发配置优化
    centOS下 JDK的三种安装方式
    Linux 配置静态Ip地址
  • 原文地址:https://www.cnblogs.com/LilyLiya/p/14228677.html
Copyright © 2011-2022 走看看