BST 二叉搜索树 (binary Search Tree )[二]

1. BST非递归插入

  1. 首先通过不断比较,找到cur == null 情况下的cur的父节点(parent)
  2. 再经过和其父亲节点的data比较然后再将其插入到孩子域中
public void non_insert(T data) {
     if (this.root == null) {
         root = new BSTNode<>(data, null, null);    // #1 :当前root为null ,添加root节点
     }
     BSTNode<T> parent = null;
     BSTNode<T> cur = root;
     while (cur != null) {    // 主要目的为了找到父节点
         parent = cur;     // 每次向子节点遍历之前保存其父节点
         if (cur.getData().compareTo(data) > 0) {   //当前节点的值大于data,遍历其的左孩子
             cur = cur.getLeft();
         } else if (cur.getData().compareTo(data) < 0) { // 当前节点小于data ,遍历其的右孩子
             cur = cur.getRight();
         } else {
             return; // 相等情况直接返回
         }
     }

     if (parent.getData().compareTo(data) > 0) {
         parent.setLeft(new BSTNode<>(data, null, null));
     } else if (parent.getData().compareTo(data) < 0) {
         parent.setRight(new BSTNode<>(data, null, null));
     }

 }

2.BST递归插入

  public void insert(T data) {
     this.root = insert(this.root, data);
 }

 private BSTNode<T> insert(BSTNode<T> root, T data) {
     if (root == null) {   // 如果找到为null的叶子节点,则返回要插入的新节点
         return new BSTNode<>(data, null, null);    //
     }
     //根据data的大小一直往叶子节点查找
     if (root.getData().compareTo(data) < 0) {
         root.setRight(insert(root.getRight(), data));
     } else if (root.getData().compareTo(data) > 0) {
         root.setLeft(insert(root.getLeft(), data));
     }
     return root; // 给非叶子节点返回其原来的节点,不做改变
 }

3.BST 的非递归删除

blic void non_remove(T data) {
     if (root == null) {
         return;
     }
     BSTNode<T> parent = null;
     BSTNode<T> cur = root;
     while (cur != null) {
         if (cur.getData().compareTo(data) > 0) {
             parent = cur;
             cur = cur.getLeft();
         } else if (cur.getData().compareTo(data) < 0) {
             parent = cur;
             cur = cur.getRight();
         } else {
             break;
         }
     }


     //相等情况直接退出 ,再做处理
     // #1: BST中不存在值为data的节点
     if (cur == null) {
         return;
     }
     //#2: 处理有两个孩子待删除节点的情况
     if (cur.getLeft() != null && cur.getRight() != null) {
         BSTNode<T> old = cur; //保存要删除的节点
         parent = cur;
         cur = cur.getLeft();   // 此处是找到要删除节点的左节点

         while (cur.getRight() != null) { // 此处判断左节点是否含有右孩子
             parent = cur;
             cur = cur.getRight();
         }
         old.setData(cur.getData());  //直接覆盖即可 ,此时就转换为删除一个节点的情况
     }

     // #3: 处理只有一个孩子节点的情况
     BSTNode<T> child = cur.getLeft();   //获取到要删除节点的孩子节点
     if (child == null) {
         child = cur.getRight();
     }

     //真正的删除操作
     if (parent == null) {   //此时表示删除的是root节点,直接将root指向 child
         this.root = child;
     } else {

         if (cur == parent.getLeft()) {     // 找到cur是父节点的哪个孩子,直接替换就行   直接将整个节点的数据都覆盖了
             parent.setLeft(child);
         } else {
             parent.setRight(child);

         }
     }
 }

4.BST的递归删除

   public void remove(T data) {
     this.root = remove(root, data);
 }

 private BSTNode<T> remove(BSTNode<T> root, T data) {
     if (root == null) {
         return null;
     }
     if (root.getData().compareTo(data) > 0) {                //和递归插入类似
         root.setLeft(remove(root.getLeft(), data));       // 此处是直接将节点覆盖
     } else if (root.getData().compareTo(data) < 0) {
         root.setRight(remove(root.getRight(), data));
     } else {

         // #1 : 待删除节点有两个孩子的情况
         if (root.getRight() != null && root.getLeft() != null) {
             BSTNode<T> pre = root.getLeft(); // 此处找到待删节点的左孩子
             while (pre.getRight() != null) {
                 pre = pre.getRight();
             }
             root.setData(pre.getData());  // 此处的删除操作还未完成,所以是值传递
             //继续向下递归删除

             root.setLeft(remove(root.getLeft(), data));   //此处继续向左递归删除是因为 ; 取的是要删除节点左孩子的后继结点
         } else {             // 此处应该是处理只有一个节点的情况,直接将叶子节点赋值给父节点
             if (root.getLeft() != null) {
                 return root.getLeft();
             } else if (root.getRight() != null) {
                 return root.getRight();
             } else {
                 return null;
             }
         }
     }
     return root;    //此处返回的是其遍历到非叶子节点的情况
 }

5.非递归查询操作

    public boolean non_quary(T data) {
     BSTNode<T> cur = root;
     while (cur != null) {
         if (cur.getData().compareTo(data) > 0) {
             cur = cur.getLeft();
         } else if (cur.getData().compareTo(data) < 0) {
             cur = cur.getRight();
         } else {
             return true;    // 相等情况返回true
         }
     }
     return false; // root = null 的情况和没找到的情况
 }

6.BST递归查询操作

    public boolean quary(T data) {

     return quary(root, data);
 }

 private boolean quary(BSTNode<T> root, T data) {
     if (root == null) {
         return false;
     }
     if (root.getData().compareTo(data) > 0) {
         return quary(root.getLeft(), data);   // 继续向下递归查找
     } else if (root.getData().compareTo(data) < 0) {
         return quary(root.getLeft(), data);
     } else {
         return true;
     }
 }

7.求BST树的镜像

  • (也就是遍历问题,将整棵树遍历一遍) 此处遍历只能是先序遍历 或者 后序遍历
  • 简单来说就是将左右子树交换
  • 此时中序遍历结果为递减的
public void mirror() {

     mirror(root);
 }

 private void mirror(BSTNode<T> root) {
     if (root == null) {
         return;
     }
     BSTNode<T> temp = root.getLeft();
     root.setLeft(root.getRight());
     root.setRight(temp);

     mirror(root.getLeft());
     mirror(root.getRight());
 }

8.将BST树中满足[begin,end]区间的数打印出来

 public void findAreaDatas(T begin, T end) {

     findAreaDatas(root, begin, end);
 }

 private void findAreaDatas(BSTNode<T> root, T begin, T end) {
     if (root == null) {
         return;
     }
     if (root.getData().compareTo(begin) > 0) { //当前节点的值大于begin时,在节点的左边进行寻找
         findAreaDatas(root.getLeft(), begin, end);
     }
     if (root.getData().compareTo(begin) >= 0 && root.getData().compareTo(end) <= 0) {
         System.out.print(root.getData() + " ");
     }
     if (root.getData().compareTo(end) < 0) {//当前节点的值小于end时,在当前节点的右边进行寻找
         findAreaDatas(root.getRight(), begin, end);
     }

 }

9.判断一个二叉树是否为BST树,是BST树返回true 不是返回false

 BSTNode<T> pre = null; // 保存遍历前一个节点的值

 public boolean isBSTree() {

     return isBSTree(this.root);
 }

 private boolean isBSTree(BSTNode<T> root) {
     if (root == null) {
         return true;
     }
     if (!isBSTree(root.getLeft())) {   // 判断左子树返回false的情况
         return false;
     }
     if (pre != null && root.getData().compareTo(pre.getData()) < 0) {
         return false;
     }
     return isBSTree(root.getLeft());
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值