• 二叉查找树(五)


      接上一篇,继续讲二叉查找树的操作,之前的博客都讲得差不多了,本篇就讲一下删除操作,以及求最矮公共父结点(LCA:lowest common ancestor)的操作吧。

    • 删除

      将一个结点从二叉查找树中删除之后,剩下的结点可能会不满足二叉查找树的性质,因此,在删除结点之后要对树进行调整,使其满足二叉查找树的性质。根据结点的孩子的数量,将删除操作分为三种情况,我们记要删除的结点为z,实际上删除的结点为y。

      1. z结点没有孩子。

      如下图a所示,我们要删除值为13的结点,因为结点没有孩子,所以删除之后不会影响到二叉树的整体性质,也就是说,直接将13这个结点删除即可,如图a所示,从左边的二叉树删除13这个点之后变到右边的二叉树。

       2. z结点有一个孩子。

      如下图b所示,要删除的值为16的结点有一个孩子,而且是右孩子,那么从图上来看,如果,我们将16去掉,然后把以20为结点的子树作为15的右子树,那么整棵树还是符合二叉查找树的性质的,因此,有一个孩子的结点的删除操作,就是要将其孩子作为其父结点的孩子即可。如图b所示。

       3. z结点有两个孩子。

      如下图c所示,要删除的值为5的结点,有两个孩子,删除之后肯定整棵树就不符合二叉查找树的性质了,因此要进行调整,我们发现,将5的后继,值为6的结点来放到5的位置,然后将6的孩子7作为6的父结点10的孩子,如下图c所示,我们要删除的是z结点,而我们实际要删除y结点,并替换z结点。这里需要注意的一点是,如果一个结点有右孩子,则该结点的后继,至多有一个子女,而且是右孩子。因为假如该结点的后继有左孩子和右孩子,那么其左孩子的值肯定是介于该结点和其后继之间的,那么按照二叉查找树的性质,这个左孩子就应该是该结点的后继,所以,这与原先的后继相互矛盾,因此,结论成立。

      好了,分析完了删除的三种情况,我们来完成我们的程序吧。

     1 /**
     2      * 删除二叉查找树中的结点z
     3      * @author Alfred
     4      * @param z 要删除的结点
     5      * @return 删除或者替换的结点
     6      */
     7     public TreeNode treeDelete(TreeNode z){
     8         TreeNode x = null, y = null;
     9         if(z.getLeft() == null || z.getRight() == null){
    10             //对应第1和第2种情况
    11             y = z;
    12         }else{
    13             //对应第3种情况
    14             y = treeSuccessor(z);
    15         }
    16         //将x置为y的非null子女,或者当y无子女时置为null
    17         if(y.getLeft() != null){
    18             x = y.getLeft();
    19         }else{
    20             x = y.getRight();
    21         }
    22         //通过修改x和y的父结点的引用,将y删除
    23         if(x != null){
    24             x.setParent(y.getParent());
    25         }
    26         if(y.getParent() == null){
    27             //x成为树根
    28             rootNode = x;
    29         }else if(y == y.getParent().getLeft()){
    30             //y是其父结点的左孩子
    31             y.getParent().setLeft(x);
    32         }else{
    33             //y是其父结点的右孩子
    34             y.getParent().setRight(x);
    35         }
    36         //如果y和z不是同一个结点,说明是第3种情况
    37         if(y != z){
    38             //内容替换
    39             z.setKey(y.getKey());
    40             z.setDataNum(y.getDataNum());
    41         }
    42         return y;
    43     }

      上面的程序完整的搞定了上面分析的三种情况。

    • LCA

      LCA问题对于二叉查找树来说是非常简单的。因为二叉查找树满足其特有的性质。给定树中的两个结点x和y,求其最低公共父结点。我们把这个算法分为三种情况。对于一棵二叉查找树来说:

      1. 如果x和y分别位于某结点z的左右子树上,那么结点z就是x和y的lca。

      2. 如果x和y位于某结点z的左子树或者右子树上,那么x和y的lca也必然位于其所处的左子树或者右子树上。

      3. 如果x或者y中,有一个结点是另外一个结点的父结点,那么lca就是它们中的父结点。即如果有一个点和某结点重合,则重合的点就是lca。

      那么,我们就从根结点开始,按照从上往下的顺序查找lca吧,比较根结点与两结点的关系,然后再进行下一步的操作。代码如下:

     1 /**
     2      * 求两个结点的最低公共父结点
     3      * @author Alfred
     4      * @param x 结点
     5      * @param y 结点
     6      * @return 最低公共父结点
     7      */
     8     public TreeNode lca(TreeNode x, TreeNode y){
     9         TreeNode tmpNode = rootNode;
    10         //获取两个key值
    11         int xKey = x.getKey();
    12         int yKey = y.getKey();
    13         //给两个元素按从小到大排下序,使得x<y
    14         if(xKey > yKey){
    15             int tmpKey = xKey;
    16             xKey = yKey;
    17             yKey = tmpKey;
    18         }
    19         while(true){
    20             if(tmpNode.getKey() < xKey){
    21                 //这种情况下,lca在其右子树上
    22                 tmpNode = tmpNode.getRight();
    23             }else if(tmpNode.getKey() > yKey){
    24                 //这种情况下,lca在其左子树上
    25                 tmpNode = tmpNode.getLeft();
    26             }else{
    27                 return tmpNode;
    28             }
    29         }
    30     }

      代码比较简单,就是按照上面的三种情况按照从上到下的顺序来分类处理的。其他还有一些lca算法,如离线算法(Tarjan)和在线算法(RMQ)等,暂时先不讨论了,以后有时间了再补上吧。为了方便想学习的童鞋来测试,我把整个代码就贴到下面了(木有找到更好地方法来分享。。)。

    TreeNode.java
     1 package com.alfred.bstree;
     2 
     3 /**
     4  * 二叉查找树结点
     5  * @author Alfred
     6  */
     7 public class TreeNode {
     8     //key值
     9     private int key;
    10     //记录相同的key值的结点个数
    11     private int dataNum;
    12     //下面三个大家都懂得!
    13     private TreeNode parent;
    14     private TreeNode left;
    15     private TreeNode right;
    16     public TreeNode(int key){
    17         this.key = key;
    18         this.dataNum = 1;
    19     }
    20     public String toString(){
    21         return ""+key+"*"+dataNum+"  ";
    22     }
    23     /**
    24      * 偷个懒...自加方法
    25      * @author Alfred
    26      */
    27     public void incNumByOne(){
    28         this.dataNum++;
    29     }
    30     
    31     /**
    32      * @return the key
    33      */
    34     public int getKey() {
    35         return key;
    36     }
    37     /**
    38      * @param key the key to set
    39      */
    40     public void setKey(int key) {
    41         this.key = key;
    42     }
    43     /**
    44      * @return the dataNum
    45      */
    46     public int getDataNum() {
    47         return dataNum;
    48     }
    49     /**
    50      * @param dataNum the dataNum to set
    51      */
    52     public void setDataNum(int dataNum) {
    53         this.dataNum = dataNum;
    54     }
    55     /**
    56      * @return the parent
    57      */
    58     public TreeNode getParent() {
    59         return parent;
    60     }
    61     /**
    62      * @param parent the parent to set
    63      */
    64     public void setParent(TreeNode parent) {
    65         this.parent = parent;
    66     }
    67     /**
    68      * @return the left
    69      */
    70     public TreeNode getLeft() {
    71         return left;
    72     }
    73     /**
    74      * @param left the left to set
    75      */
    76     public void setLeft(TreeNode left) {
    77         this.left = left;
    78     }
    79     /**
    80      * @return the right
    81      */
    82     public TreeNode getRight() {
    83         return right;
    84     }
    85     /**
    86      * @param right the right to set
    87      */
    88     public void setRight(TreeNode right) {
    89         this.right = right;
    90     }
    91 }
    BSTree.java
      1 package com.alfred.bstree;
      2 
      3 import java.util.LinkedList;
      4 import java.util.List;
      5 import java.util.Queue;
      6 import java.util.Random;
      7 import java.util.Stack;
      8 
      9 /**
     10  * 二叉查找树
     11  * @author Alfred
     12  */
     13 public class BSTree {
     14     //随机化的构造二叉查找树
     15     private Random rand = null;
     16     //根结点
     17     private TreeNode rootNode = null;
     18     
     19     /**
     20      * 以int数组A来创建二叉查找树
     21      * @param A int数组
     22      */
     23     public BSTree(int[] A){
     24         rand = new Random();
     25         createBSTree(A);
     26     }
     27     
     28     /**
     29      * 创建二叉查找树
     30      * @param A int数组
     31      */
     32     private void createBSTree(int[] A){
     33         //先构建一个存储数组下标的List
     34         List<Integer> index = new LinkedList<Integer>();
     35         int i = 0;
     36         for(i = 0; i < A.length; i++){
     37             index.add(i);
     38         }
     39         //随机构造二叉树
     40         for(i = 0; i < A.length; i++){
     41             int j = 0;
     42             if(index.size() > 1){
     43                 //随机产生一个数组下标值
     44                 j = rand.nextInt(index.size() - 1);
     45             }
     46             //插入二叉树
     47             TreeInsert(A[index.get(j)]);
     48             //移除下标
     49             index.remove(j);
     50         }
     51     }
     52     
     53     /**
     54      * 插入一个整数
     55      * @param z 整数
     56      */
     57     public void TreeInsert(int z){
     58         TreeNode parentNode = null;
     59         TreeNode searchNode = rootNode;
     60         TreeNode insertNode = new TreeNode(z);
     61         //while循环找到要插入的点的父结点
     62         while(searchNode != null){
     63             parentNode = searchNode;
     64             if(insertNode.getKey() < searchNode.getKey()){
     65                 searchNode = searchNode.getLeft();
     66             }else if(insertNode.getKey() == searchNode.getKey()){
     67                 //如果是key值相同的话,直接插入,偷懒在这里...
     68                 searchNode.incNumByOne();
     69                 return;
     70             }else{
     71                 searchNode = searchNode.getRight();
     72             }
     73         }
     74         
     75         insertNode.setParent(parentNode);
     76         if(parentNode == null){
     77             rootNode = insertNode;
     78         }else if(insertNode.getKey() < parentNode.getKey()){
     79             //插入左结点
     80             parentNode.setLeft(insertNode);
     81         }else if(insertNode.getKey() == parentNode.getKey()){
     82             //因为上面插入了,所以这里就不会执行了。
     83             parentNode.incNumByOne();
     84             System.out.println("this is not supposed to be executed.");
     85         }else{
     86             //插入右结点
     87             parentNode.setRight(insertNode);
     88         }
     89     }
     90     
     91     /**
     92      * 递归前序遍历以x为根的二叉树
     93      * @author Alfred
     94      * @param x 根结点
     95      */
     96     public void preOrderTreeWalk(TreeNode x){
     97         if(x != null){
     98             System.out.print(x);//访问形式为打印输出一下
     99             preOrderTreeWalk(x.getLeft());
    100             preOrderTreeWalk(x.getRight());
    101         }
    102     }
    103     
    104     public void preOrderTreeWalk(){
    105         preOrderTreeWalk(rootNode);
    106     }
    107     
    108     /**
    109      * 非递归前序遍历以x为根结点的二叉树
    110      * @author Alfred
    111      * @param x 根结点
    112      */
    113     public void preOrderTreeWalkNonrecursive1(TreeNode x){
    114         //借助栈来实现。
    115         Stack<TreeNode> stack = new Stack<TreeNode>();
    116         while(x != null || !stack.empty()){
    117             if(x != null){
    118                 System.out.print(x);//遍历输出
    119                 stack.push(x);//压栈
    120                 x = x.getLeft();
    121             }else{
    122                 x = stack.pop();//出栈
    123                 x = x.getRight();
    124             }
    125         }
    126     }
    127     
    128     /**
    129      * 非递归前序遍历以x为根结点的二叉树
    130      * @author Alfred
    131      * @param x 根结点
    132      */
    133     public void preOrderTreeWalkNonrecursive2(TreeNode x){
    134         Stack<TreeNode> stack = new Stack<TreeNode>();
    135         if(x != null){
    136             stack.push(x);
    137             while(!stack.empty()){
    138                 TreeNode tmpNode = stack.pop();
    139                 System.out.print(tmpNode);//遍历输出
    140                 if(tmpNode.getRight() != null){
    141                     stack.push(tmpNode.getRight());
    142                 }
    143                 if(tmpNode.getLeft() != null){
    144                     stack.push(tmpNode.getLeft());
    145                 }
    146             }
    147         }
    148     }
    149     
    150     public void preOrderTreeWalkNonrecursive(){
    151         System.out.println("方法1:");
    152         preOrderTreeWalkNonrecursive1(rootNode);
    153         System.out.println("\n方法2:");
    154         preOrderTreeWalkNonrecursive2(rootNode);
    155     }
    156     
    157     /**
    158      * 递归中序遍历以x为根的二叉树
    159      * @author Alfred
    160      * @param x 根结点
    161      */
    162     public void inOrderTreeWalk(TreeNode x){
    163         if(x != null){
    164             inOrderTreeWalk(x.getLeft());
    165             System.out.print(x);
    166             inOrderTreeWalk(x.getRight());
    167         }
    168     }
    169     
    170     public void inOrderTreeWalk(){
    171         inOrderTreeWalk(rootNode);
    172     }
    173     
    174     /**
    175      * 非递归中序遍历以x为根结点的二叉树
    176      * @author Alfred
    177      * @param x 根结点
    178      */
    179     public void inOrderTreeWalkNonrecursive(TreeNode x){
    180         Stack<TreeNode> stack = new Stack<TreeNode>();
    181         while(x != null || !stack.empty()){
    182             if(x != null){
    183                 stack.push(x);
    184                 x = x.getLeft();
    185             }else{
    186                 x = stack.pop();
    187                 System.out.print(x);//遍历输出
    188                 x = x.getRight();
    189             }
    190         }
    191     }
    192     
    193     public void inOrderTreeWalkNonrecursive(){
    194         inOrderTreeWalkNonrecursive(rootNode);
    195     }
    196     
    197     /**
    198      * 递归后序遍历以x为根的二叉树
    199      * @author Alfred
    200      * @param x 根结点
    201      */
    202     public void postOrderTreeWalk(TreeNode x){
    203         if(x != null){
    204             postOrderTreeWalk(x.getLeft());
    205             postOrderTreeWalk(x.getRight());
    206             System.out.print(x);
    207         }
    208     }
    209     
    210     public void postOrderTreeWalk(){
    211         postOrderTreeWalk(rootNode);
    212     }
    213     /**
    214      * 非递归后序遍历以x为根结点的二叉树
    215      * @author Alfred
    216      * @param x 根结点
    217      */
    218     public void postOrderTreeWalkNonrecursive1(TreeNode x){
    219         Stack<TreeNode> stack = new Stack<TreeNode>();
    220         TreeNode prev = null;
    221         TreeNode curr = null;
    222         if(x != null){
    223             stack.push(x);
    224         }
    225         while(!stack.empty()){
    226             curr = stack.peek();
    227             if(prev == null || prev.getLeft() == curr || prev.getRight() == curr){
    228                 if(curr.getLeft() != null){
    229                     stack.push(curr.getLeft());//压左孩子
    230                 }else if(curr.getRight() != null){
    231                     stack.push(curr.getRight());//压右孩子
    232                 }
    233             }else if(curr.getLeft() == prev){
    234                 if(curr.getRight() != null){
    235                     stack.push(curr.getRight());//压右孩子
    236                 }
    237             }else{
    238                 System.out.print(curr);//遍历输出
    239                 stack.pop();
    240             }
    241             prev = curr;
    242         }
    243     }
    244     
    245     /**
    246      * 非递归后序遍历以x为根结点的二叉树
    247      * @author Alfred
    248      * @param x 根结点
    249      */
    250     public void postOrderTreeWalkNonrecursive2(TreeNode x){
    251         Stack<TreeNode> stack = new Stack<TreeNode>();
    252         Stack<TreeNode> output = new Stack<TreeNode>();
    253         TreeNode curr = null;
    254         if(x != null){
    255             stack.push(x);
    256         }
    257         while(!stack.empty()){
    258             curr = stack.pop();
    259             output.push(curr);//存放到输出地栈里面
    260             if(curr.getLeft() != null){
    261                 stack.push(curr.getLeft());//压左孩子
    262             }
    263             if(curr.getRight() != null){
    264                 stack.push(curr.getRight());//压右孩子
    265             }
    266         }
    267         while(!output.empty()){
    268             TreeNode tmpNode = output.pop();
    269             System.out.print(tmpNode);//打印输出
    270         }
    271     }
    272     
    273     public void postOrderTreeWalkNonrecursive(){
    274         System.out.println("方法1:");
    275         postOrderTreeWalkNonrecursive1(rootNode);
    276         System.out.println("\n方法2:");
    277         postOrderTreeWalkNonrecursive2(rootNode);
    278     }
    279     /**
    280      * 层序遍历二叉树
    281      * @author Alfred
    282      * @param x 根结点
    283      */
    284     public void levelOrderTreeWalk(TreeNode x){
    285         Queue<TreeNode> queue = new LinkedList<TreeNode>();
    286         TreeNode tmpNode = null;
    287         if(x != null){
    288             queue.offer(x);
    289         }
    290         while(!queue.isEmpty()){
    291             tmpNode = queue.poll();
    292             System.out.print(tmpNode);//打印输出
    293             if(tmpNode.getLeft() != null){
    294                 queue.offer(tmpNode.getLeft());//左孩子入队
    295             }
    296             if(tmpNode.getRight() != null){
    297                 queue.offer(tmpNode.getRight());//右孩子入队
    298             }
    299         }
    300     }
    301     public void levelOrderTreeWalk(){
    302         levelOrderTreeWalk(rootNode);
    303     }
    304     
    305     
    306     /**
    307      * 查找以x为根结点的树中key的值为k的结点,返回找到的结点或者null
    308      * @author Alfred
    309      * @param x 根结点
    310      * @param k 要查找的整数
    311      * @return 找到的结点或者null
    312      */
    313     private TreeNode treeSearch(TreeNode x, int k){
    314 //        System.out.println("treeSearch:"+x);
    315         if(x == null || k == x.getKey()){
    316             return x;
    317         }
    318         if(k < x.getKey()){
    319             return treeSearch(x.getLeft(), k);//查左子树
    320         }else{
    321             return treeSearch(x.getRight(), k);//查右子树
    322         }
    323     }
    324     /**
    325      * 非递归地查找以x为根结点的树中key的值为k的结点,返回找到的结点或者null
    326      * @author Alfred
    327      * @param x 根结点
    328      * @param k 要查找的整数
    329      * @return 找到的结点或者null
    330      */
    331     private TreeNode treeSearchNonrecursive(TreeNode x, int k){
    332         while(x != null && k != x.getKey()){
    333             if(k < x.getKey()){
    334                 x = x.getLeft();
    335             }else{
    336                 x = x.getRight();
    337             }
    338         }
    339         return x;
    340     }
    341     
    342     public TreeNode treeSearch(int k){
    343         return treeSearch(rootNode, k);
    344     }
    345     public TreeNode treeSearchNonrecursive(int k){
    346         return treeSearchNonrecursive(rootNode, k);
    347     }
    348     /**
    349      * 找以x为根结点的二叉查找树中的最小值
    350      * @author Alfred
    351      * @param x 根结点
    352      * @return 最小值结点或者null
    353      */
    354     public TreeNode treeMin(TreeNode x){
    355         while(x.getLeft() != null){
    356             x = x.getLeft();
    357         }
    358         return x;
    359     }
    360     
    361     public TreeNode treeMin(){
    362         return treeMin(rootNode);
    363     }
    364     /**
    365      * 找以x为根结点的二叉查找树中的最大值
    366      * @author Alfred
    367      * @param x 根结点
    368      * @return 最大值结点或者null
    369      */
    370     public TreeNode treeMax(TreeNode x){
    371         while(x.getRight() != null){
    372             x = x.getRight();
    373         }
    374         return x;
    375     }
    376     
    377     public TreeNode treeMax(){
    378         return treeMax(rootNode);
    379     }
    380     /**
    381      * 找结点x的后继结点
    382      * @author Alfred
    383      * @param x 结点
    384      * @return x的后继结点或者null
    385      */
    386     public TreeNode treeSuccessor(TreeNode x){
    387         //第一种情况
    388         if(x.getRight() != null){
    389             return treeMin(x.getRight());
    390         }
    391         //第二种情况
    392         TreeNode tmpNode = x.getParent();
    393         while(tmpNode != null && x == tmpNode.getRight()){
    394             x = tmpNode;
    395             tmpNode = tmpNode.getParent();
    396         }
    397         return tmpNode;
    398     }
    399     
    400     /**
    401      * 找结点x的前趋结点
    402      * @author Alfred
    403      * @param x 结点
    404      * @return x的前趋结点或者null
    405      */
    406     public TreeNode treePredecessor(TreeNode x){
    407         //第一种情况
    408         if(x.getLeft() != null){
    409             return treeMax(x.getLeft());
    410         }
    411         //第二种情况
    412         TreeNode tmpNode = x.getParent();
    413         while(tmpNode != null && x == tmpNode.getLeft()){
    414             x = tmpNode;
    415             tmpNode = tmpNode.getParent();
    416         }
    417         return tmpNode;
    418     }
    419     
    420     /**
    421      * 删除二叉查找树中的结点z
    422      * @author Alfred
    423      * @param z 要删除的结点
    424      * @return 删除或者替换的结点
    425      */
    426     public TreeNode treeDelete(TreeNode z){
    427         TreeNode x = null, y = null;
    428         if(z.getLeft() == null || z.getRight() == null){
    429             //对应第1和第2种情况
    430             y = z;
    431         }else{
    432             //对应第3种情况
    433             y = treeSuccessor(z);
    434         }
    435         //将x置为y的非null子女,或者当y无子女时置为null
    436         if(y.getLeft() != null){
    437             x = y.getLeft();
    438         }else{
    439             x = y.getRight();
    440         }
    441         //通过修改x和y的父结点的引用,将y删除
    442         if(x != null){
    443             x.setParent(y.getParent());
    444         }
    445         if(y.getParent() == null){
    446             //x成为树根
    447             rootNode = x;
    448         }else if(y == y.getParent().getLeft()){
    449             //y是其父结点的左孩子
    450             y.getParent().setLeft(x);
    451         }else{
    452             //y是其父结点的右孩子
    453             y.getParent().setRight(x);
    454         }
    455         //如果y和z不是同一个结点,说明是第3种情况
    456         if(y != z){
    457             //内容替换
    458             z.setKey(y.getKey());
    459             z.setDataNum(y.getDataNum());
    460         }
    461         return y;
    462     }
    463     
    464     /**
    465      * 求两个结点的最低公共父结点
    466      * @author Alfred
    467      * @param x 结点
    468      * @param y 结点
    469      * @return 最低公共父结点
    470      */
    471     public TreeNode lca(TreeNode x, TreeNode y){
    472         TreeNode tmpNode = rootNode;
    473         //获取两个key值
    474         int xKey = x.getKey();
    475         int yKey = y.getKey();
    476         //给两个元素按从小到大排下序,使得x<y
    477         if(xKey > yKey){
    478             int tmpKey = xKey;
    479             xKey = yKey;
    480             yKey = tmpKey;
    481         }
    482         while(true){
    483             if(tmpNode.getKey() < xKey){
    484                 //这种情况下,lca在其右子树上
    485                 tmpNode = tmpNode.getRight();
    486             }else if(tmpNode.getKey() > yKey){
    487                 //这种情况下,lca在其左子树上
    488                 tmpNode = tmpNode.getLeft();
    489             }else{
    490                 return tmpNode;
    491             }
    492         }
    493     }
    494 }
    TestMain.java
     1 package com.alfred.bstree;
     2 
     3 public class testMain {
     4 
     5     public static void main(String[] args) {
     6         int[] A = new int[]{15,6,18,3,7,17,20,2,4,13,9,3,18,8,8,8,8,8};
     7         BSTree bsTree = new BSTree(A);
     8         System.out.println("前序遍历递归方法:");
     9         bsTree.preOrderTreeWalk();
    10         System.out.println("\n前序遍历非递归方法:");
    11         bsTree.preOrderTreeWalkNonrecursive();
    12         System.out.println("\n中序遍历递归方法:");
    13         bsTree.inOrderTreeWalk();
    14         System.out.println("\n中序遍历非递归方法:");
    15         bsTree.inOrderTreeWalkNonrecursive();
    16         System.out.println("\n后序遍历递归方法:");
    17         bsTree.postOrderTreeWalk();
    18         System.out.println("\n后序遍历非递归方法:");
    19         bsTree.postOrderTreeWalkNonrecursive();
    20         System.out.println("\n层序遍历方法:");
    21         bsTree.levelOrderTreeWalk();
    22         
    23         System.out.println("\n递归查找:");
    24         System.out.println(bsTree.treeSearch(8));
    25         System.out.println("非递归查找:");
    26         System.out.println(bsTree.treeSearchNonrecursive(8));
    27         
    28         System.out.println("\n最大值:");
    29         System.out.println(bsTree.treeMax());
    30         System.out.println("最小值:");
    31         System.out.println(bsTree.treeMin());
    32         System.out.println("8的后继:");
    33         System.out.println(bsTree.treeSuccessor(bsTree.treeSearch(8)));
    34         System.out.println("8的前驱:");
    35         System.out.println(bsTree.treePredecessor(bsTree.treeSearch(8)));
    36         System.out.println("\n最大最小值的LCA:");
    37         System.out.println(bsTree.lca(bsTree.treeMin(), bsTree.treeMax()));
    38         
    39         System.out.println("删除8之后:");
    40         TreeNode eight = bsTree.treeSearch(8);
    41         bsTree.inOrderTreeWalk();
    42         System.out.println();
    43         bsTree.treeDelete(eight);
    44         bsTree.inOrderTreeWalk();
    45     }
    46 }


      ps:关于二叉查找树的一些操作先写到这里吧,有不对的地方,请广大博友指正啊。

      pss:画图好累啊。。转载请注明。。。

  • 相关阅读:
    数据链路层
    补码加减法
    matlab函数
    HDU2159_二维完全背包问题
    HDU2844买表——多重背包初探
    HDU1025贫富平衡
    最大m段子段和
    01背包浮点数情况
    第K大01背包
    HDU2955 01背包
  • 原文地址:https://www.cnblogs.com/unpolishedgem/p/2494770.html
Copyright © 2020-2023  润新知