二叉搜索树:一棵二叉搜索树是以一棵二叉树来组织的,这样一棵树可以使用链表的数据结构来表示(也可以采用数组来实现)。除了key和可能带有的其他数据外,每个节点还包含Left,Right,Parent,它们分别指节点的左孩子,右孩子,和父节点。

一个二叉搜索树总是满足 :node.left.key<node.key<=node.right.key。

以下是一个用java实现的二叉搜索树,包含了查找最大值,最小值,查找某一节点,插入和删除操作。

接下来通过代码来分析二叉搜索树中的思想:在代码实现二叉搜索树中,大量采用了递归的思想,同样可以采用循环去递归来实现。

插入:自根节点起递归调用“寻找合适位置方法”,使二叉搜索树始终满足条件  node.left.key<node.key<=node.right.key。

查询:自根节点起递归调用“查找孩子的方法”。查找孩子的方法采用的思想是,判断node.key==key 返回,node.key>key 递归查找左子树,node.key<=key 递归查             找右子树。

查询最小值:递归查找左孩子,直到最后一个左孩子。

查询最大值:递归查找右孩子,直到最后一个右孩子。

遍历:

前序遍历:根的关键字输出在左右子树的关键字之前。根 左 右。

中序遍历:根的关键字输出在左右子树的关键字之间。左 根 右。

后序遍历:根的关键字输出在左右子树的关键字之后。左 右 根。

删除:删除一棵搜索树是比较麻烦的。共有以下4种情况

1.删除节点没有孩子,直接断开连接即可

2.a图:删除节点没有左孩子,将右孩子移至删除节点处

3.b图:删除节点没有右孩子,将左孩子移至删除节点处

4.c图:有左右孩子,右孩子 没有 左孩子,将右孩子移动至删除节点处,将左孩子的父节点连接值右孩子。

5.d图:有左右孩子,且右孩子也有左右孩子,则查找右孩子的最小节点,将最小节点移至删除节点处。

public class SearchTree {
                     //树的根节点
      private Node Root = null;
                     //内部类,结点
      private class Node{

         Node parent;//父节点
         Node Left;//左孩子
         Node Right;//右孩子
         int keyValue;//关键字

         public Node(Node parent,
                Node Left,
                Node Right,
                int keyValue) {
          this.parent = parent;
          this.Left = Left;
          this.Right = Right;
          this.keyValue = keyValue;
         }
      }

      public void delete(int value) {
        Node deleteNode = this.search(value);//查找删除节点
        if(deleteNode.Left==null) {//没有左孩子
          transplant(deleteNode, deleteNode.Right);
        }else if(deleteNode.Right==null) {//没有右孩子
          transplant(deleteNode, deleteNode.Left);
        }else {//有左右孩子时
          Node min = this.min(deleteNode.Right);//查找右孩子的最小节点
          if(min.parent!=deleteNode) {
            transplant(min, min.Right);
            min.Right = deleteNode.Right;
            min.Right.parent = min;
          }
        transplant(deleteNode, min);
        min.Left = deleteNode.Left;
        min.Left.parent = min;
        }
      }

//交换子树,将node2 移动至node1的位置。
      private void transplant(Node node1,Node node2) {
        if(node1.parent==null) {
          this.Root = node2;
        }else if(node1==node1.parent.Left) {
          node1.parent.Left = node2;
        }else {
          node1.parent.Right= node2;
        }
        if(node2!=null) {
          node2.parent = node1.parent;
        }
      }

//查找方法
      public Node search(int value) {
        return searchNode(this.Root,value);
      }

      private Node searchNode(Node node,int key) {
        if(node==null || node.keyValue==key) {
          return node;
        }
        if(node.keyValue>key) {
          return this.searchNode(node.Left,key);
        }else {
          return this.searchNode(node.Right, key);
        }
      }

//插入方法
      public void insert(int value) {
        Node child = new Node(null, null, null, value);
        findRightPlace(this.Root,child);
      }

      private void findRightPlace(Node currentRoot,Node insertNode) {
        if(currentRoot!=null) {
            if(currentRoot.keyValue>insertNode.keyValue) {
              if(currentRoot.Left==null) {
                currentRoot.Left = insertNode;
                insertNode.parent = currentRoot;
              }else {
                findRightPlace(currentRoot.Left,insertNode);
                   }
            }else {
              if(currentRoot.Right==null) {
                currentRoot.Right = insertNode;
                insertNode.parent = currentRoot;
              }else {
                findRightPlace(currentRoot.Right,insertNode);
              }
            }
        }else {
            this.Root = insertNode;
        }
      }

//查找最大
      public int findMax() {
        return max(this.Root)==null?-1:max(this.Root).keyValue;
      }

      private Node max(Node node) {
        if(node!=null) {
          if(node.Right!=null) {
            return max(node.Right);
          }else {
            return node;
          }
        }else {
          return null;
        }
      }

//查找最小
      public int findMin() {
        return min(this.Root)==null?-1:min(this.Root).keyValue;
      }

      private Node min(Node node) {
        if(node!=null) {
          if(node.Left!=null) {
            return min(node.Left);
          }else {
            return node;
          }
        }else {
          return null;
        }
      }

//后序遍历
      public void after() {
        afterShow(this.Root);
      }

      private void afterShow(Node node) {
        if(node!=null) {
          afterShow(node.Left);
          afterShow(node.Right);
          System.out.println(node.keyValue);
        }
      }

//中序遍历
      public void mid() {
        midShow(this.Root);
      }

      private void midShow(Node node) {
        if(node!=null) {
          midShow(node.Left);
          System.out.println(node.keyValue);
          midShow(node.Right);
        }
      }

//前序遍历
      public void ahead() {
        aheadShow(this.Root);
      }

      private void aheadShow(Node node) {
        if(node!=null) {
          System.out.println(node.keyValue);
          aheadShow(node.Left);
          aheadShow(node.Right);
        }
}

参考资料 《算法导论》第三版

二叉搜索树 思想 JAVA实现的更多相关文章

  1. 【算法与数据结构】二叉搜索树的Java实现

    为了更加深入了解二叉搜索树,博主自己用Java写了个二叉搜索树,有兴趣的同学可以一起探讨探讨. 首先,二叉搜索树是啥?它有什么用呢? 二叉搜索树, 也称二叉排序树,它的每个节点的数据结构为1个父节点指 ...

  2. 96题--不同的二叉搜索树(java、中等难度)

    题目描述:给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例如下: 分析:本题可用动态规划的方法求解. 设 dp[n] 表示以 1 ... n 为节点组成的二叉搜索树的种类 ...

  3. 二叉搜索树及java实现

    二叉搜索树(Binary Search Tree) 二叉搜索树是二叉树的一种,是应用非常广泛的一种二叉树,英文简称为 BST 又被称为:二叉查找树.二叉排序树 任意一个节点的值都大于其左子树所有节 ...

  4. 二叉搜索树的java实现

    转载请注明出处 一.概念 二叉搜索树也成二叉排序树,它有这么一个特点,某个节点,若其有两个子节点,则一定满足,左子节点值一定小于该节点值,右子节点值一定大于该节点值,对于非基本类型的比较,可以实现Co ...

  5. hdu 3999 The order of a Tree (二叉搜索树)

    /****************************************************************** 题目: The order of a Tree(hdu 3999 ...

  6. 自己动手实现java数据结构(六)二叉搜索树

    1.二叉搜索树介绍 前面我们已经介绍过了向量和链表.有序向量可以以二分查找的方式高效的查找特定元素,而缺点是插入删除的效率较低(需要整体移动内部元素):链表的优点在于插入,删除元素时效率较高,但由于不 ...

  7. 【Java】 剑指offer(36) 二叉搜索树与双向链表

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不 ...

  8. Java实现二叉搜索树

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11406176.html 尝试一下用Java实现二叉搜索树/二叉查找树,记录自己的学习历程. 1 ...

  9. Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作

    什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T ...

随机推荐

  1. 二、SQL的生命周期

    MySQL的sql语句由客户端发出,经过连接和权限验证后,最终达到服务器端,由服务器分配thread线程处理,之后就是要介绍的具体服务器端的thread线程是怎么处理每条sql语句的.[ 了解thre ...

  2. Java中的并发工具类:CountDownLatch、CyclicBarrier和Semaphore

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 一. ...

  3. windows命令行下批量拷贝同一后缀的文件到另外一个目录

    一个目录下有很多文件夹,想拷贝每个文件夹下面的wmv文件到另外一个目录,如果鼠标打开一个文件,拷贝一个,再打开其他的,逐一操作,很麻烦的,百度了一下,xcopy命令就可以实现:例如将C盘x1目录下所有 ...

  4. Spring.net页面属性注入

    .条件spring.web程序集 1.1 system.web配置 <httpHandlers> <add verb="*" path="*.aspx& ...

  5. ajax 整个表单的提交

    重点:data: $("#form1").serialize() function setSaveNext() { setSaveData(); var cx = pageInde ...

  6. JVM致命错误日志(hs_err_pid.log)解读

    JVM致命错误日志(hs_err_pid.log)解读 摘自:https://blog.csdn.net/u013938484/article/details/51811400 2016年07月02日 ...

  7. [operator]ELK6 index pattern的问题

    完成了EL/FK的搭建之后,在kibana的主页只能看到默认的索引? 其实这个索引名字的设置是在logstash-smaple.conf(elk6.4)里的设置,比如我这样设置 input { bea ...

  8. centos7部署JavaWeb项目

    centos7部署JavaWeb项目共有三步 1.配置java环境 2.配置tomcat环境. 3.部署JavaWeb项目 一.配置java环境 1.1安装java 参考我的另一篇博文:https:/ ...

  9. (4)WePHP 模板引入CSS js

    模板有两个定义了两个常量 父类已经定义好了 //模板常量 $dirStr=dirname($_SERVER['SCRIPT_NAME']); $dirStr=$dirStr=='\\'?NULL:$d ...

  10. C/C++语言中的函数参数传参三种对比

    学了很长时间C/C++有时指针方面还是有点乱. 希望大神发现如果下面有不对的地方请指出.我发现之所以我乱就是因为中文表述不准确的问题,比如 ,地址值和地址 #include <iostream& ...