1. import java.util.Random;
  2.  
  3. /**
  4. * 二叉排序树(又称二叉查找树)
  5. * (1)能够是一颗空树
  6. * (2)若左子树不空,则左子树上全部的结点的值均小于她的根节点的值
  7. * (3)若右子树不空,则右子树上全部的结点的值均大于她的根节点的值
  8. * (4)左、右子树也分别为二叉排序树
  9. *
  10. *
  11. * 性能分析:
  12. * 查找性能:
  13. * 含有n个结点的二叉排序树的平均查找长度和树的形态有关。
  14. * (最坏情况)当先后插入的keyword有序时。构成的二叉排序树蜕变为单枝树。查找性能为O(n)
  15. * (最好情况)二叉排序树的形态和折半查找的判定树同样,其平均查找长度和log2(n)成正比
  16. *
  17. *
  18. * 插入、删除性能:
  19. * 插入、删除操作间复杂度都O(log(n))级的。
  20. * 即经过O(log(n))时间搜索到了需插入删除节点位置和删除节点的位置
  21. * 经O(1)级的时间直接插入和删除
  22. * 与顺序表相比。比序顺序表插入删除O(n)(查找时间O(log(n))移动节点时间O(n))要快
  23. * 与无序顺序表插入时间O(1),删除时间O(n)相比,由于是有序的,所查找速度要快非常多
  24. *
  25. *
  26. *
  27. * 作者:小菜鸟
  28. * 创建时间:2014-08-17
  29. *
  30. */
  31.  
  32. public class BinarySortTree {
  33.  
  34. private Node root = null;
  35.  
  36. /**查找二叉排序树中是否有key值*/
  37. public boolean searchBST(int key){
  38. Node current = root;
  39. while(current != null){
  40. if(key == current.getValue())
  41. return true;
  42. else if(key < current.getValue())
  43. current = current.getLeft();
  44. else
  45. current = current.getRight();
  46. }
  47. return false;
  48. }
  49.  
  50. /**向二叉排序树中插入结点*/
  51. public void insertBST(int key){
  52. Node p = root;
  53. /**记录查找结点的前一个结点*/
  54. Node prev = null;
  55. /**一直查找下去,直到到达满足条件的结点位置*/
  56. while(p != null){
  57. prev = p;
  58. if(key < p.getValue())
  59. p = p.getLeft();
  60. else if(key > p.getValue())
  61. p = p.getRight();
  62. else
  63. return;
  64. }
  65. /**prve是要安放结点的父节点,依据结点值得大小,放在对应的位置*/
  66. if(root == null)
  67. root = new Node(key);
  68. else if(key < prev.getValue())
  69. prev.setLeft(new Node(key));
  70. else prev.setRight(new Node(key));
  71. }
  72.  
  73. /**
  74. * 删除二叉排序树中的结点
  75. * 分为三种情况:(删除结点为*p 。其父结点为*f)
  76. * (1)要删除的*p结点是叶子结点,仅仅须要改动它的双亲结点的指针为空
  77. * (2)若*p仅仅有左子树或者仅仅有右子树,直接让左子树/右子树取代*p
  78. * (3)若*p既有左子树,又有右子树
  79. * 用p左子树中最大的那个值(即最右端S)取代P。删除s,重接其左子树
  80. * */
  81. public void deleteBST(int key){
  82. deleteBST(root, key);
  83. }
  84. private boolean deleteBST(Node node, int key) {
  85. if(node == null) return false;
  86. else{
  87. if(key == node.getValue()){
  88. return delete(node);
  89. }
  90. else if(key < node.getValue()){
  91. return deleteBST(node.getLeft(), key);
  92. }
  93. else{
  94. return deleteBST(node.getRight(), key);
  95. }
  96. }
  97. }
  98.  
  99. private boolean delete(Node node) {
  100. Node temp = null;
  101. /**右子树空,仅仅须要重接它的左子树
  102. * 假设是叶子结点,在这里也把叶子结点删除了
  103. * */
  104. if(node.getRight() == null){
  105. temp = node;
  106. node = node.getLeft();
  107. }
  108. /**左子树空, 重接它的右子树*/
  109. else if(node.getLeft() == null){
  110. temp = node;
  111. node = node.getRight();
  112. }
  113. /**左右子树均不为空*/
  114. else{
  115. temp = node;
  116. Node s = node;
  117. /**转向左子树,然后向右走到“尽头”*/
  118. s = s.getLeft();
  119. while(s.getRight() != null){
  120. temp = s;
  121. s = s.getRight();
  122. }
  123. node.setValue(s.getValue());
  124. if(temp != node){
  125. temp.setRight(s.getLeft());
  126. }
  127. else{
  128. temp.setLeft(s.getLeft());
  129. }
  130. }
  131. return true;
  132. }
  133.  
  134. /**中序非递归遍历二叉树
  135. * 获得有序序列
  136. * */
  137. public void nrInOrderTraverse(){
  138. Stack<Node> stack = new Stack<Node>();
  139. Node node = root;
  140. while(node != null || !stack.isEmpty()){
  141. while(node != null){
  142. stack.push(node);
  143. node = node.getLeft();
  144. }
  145. node = stack.pop();
  146. System.out.println(node.getValue());
  147. node = node.getRight();
  148. }
  149. }
  150.  
  151. public static void main(String[] args){
  152. BinarySortTree bst = new BinarySortTree();
  153. /**构建的二叉树没有同样元素*/
  154. int[] num = {4,7,2,1,10,6,9,3,8,11,2, 0, -2};
  155. for(int i = 0; i < num.length; i++){
  156. bst.insertBST(num[i]);
  157. }
  158. bst.nrInOrderTraverse();
  159. System.out.println(bst.searchBST(10));
  160. bst.deleteBST(2);
  161. bst.nrInOrderTraverse();
  162. }
  163.  
  164. /**二叉树的结点定义*/
  165. public class Node{
  166. private int value;
  167. private Node left;
  168. private Node right;
  169.  
  170. public Node(){
  171. }
  172. public Node(Node left, Node right, int value){
  173. this.left = left;
  174. this.right = right;
  175. this.value = value;
  176. }
  177. public Node(int value){
  178. this(null, null, value);
  179. }
  180.  
  181. public Node getLeft(){
  182. return this.left;
  183. }
  184. public void setLeft(Node left){
  185. this.left = left;
  186. }
  187. public Node getRight(){
  188. return this.right;
  189. }
  190. public void setRight(Node right){
  191. this.right = right;
  192. }
  193. public int getValue(){
  194. return this.value;
  195. }
  196. public void setValue(int value){
  197. this.value = value;
  198. }
  199. }
  200.  
  201. }

Java实现二叉排序树的插入、查找、删除的更多相关文章

  1. Java中数组的插入,删除,扩张

    Java中数组是不可变的,但是可以通过本地的arraycop来进行数组的插入,删除,扩张.实际上数组是没变的,只是把原来的数组拷贝到了另一个数组,看起来像是改变了. 语法: System.arrayc ...

  2. HDU 5687 字典树插入查找删除

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5687 2016百度之星资格赛C题,直接套用字典树,顺便巩固了一下自己对字典树的理解 #include< ...

  3. 二叉搜索树Java实现(查找、插入、删除、遍历)

    由于最近想要阅读下 JDK1.8 中 HashMap 的具体实现,但是由于 HashMap 的实现中用到了红黑树,所以我觉得有必要先复习下红黑树的相关知识,所以写下这篇随笔备忘,有不对的地方请指出- ...

  4. 算法与数据结构(十) 二叉排序树的查找、插入与删除(Swift版)

    在上一篇博客中,我们主要介绍了四种查找的方法,包括顺序查找.折半查找.插入查找以及Fibonacci查找.上面这几种查找方式都是基于线性表的查找方式,今天博客中我们来介绍一下基于二叉树结构的查找,也就 ...

  5. 二叉查找树的查找、插入和删除 - Java实现

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 作者: yangecnu(yangecnu's Blog on ...

  6. 【Java】 大话数据结构(11) 查找算法(2)(二叉排序树/二叉搜索树)

    本文根据<大话数据结构>一书,实现了Java版的二叉排序树/二叉搜索树. 二叉排序树介绍 在上篇博客中,顺序表的插入和删除效率还可以,但查找效率很低:而有序线性表中,可以使用折半.插值.斐 ...

  7. 数据结构Java实现03----单向链表的插入和删除

    文本主要内容: 链表结构 单链表代码实现 单链表的效率分析 一.链表结构: (物理存储结构上不连续,逻辑上连续:大小不固定)            概念: 链式存储结构是基于指针实现的.我们把一个数据 ...

  8. Java创建二叉搜索树,实现搜索,插入,删除操作

    Java实现的二叉搜索树,并实现对该树的搜索,插入,删除操作(合并删除,复制删除) 首先我们要有一个编码的思路,大致如下: 1.查找:根据二叉搜索树的数据特点,我们可以根据节点的值得比较来实现查找,查 ...

  9. 数据结构Java实现02----单向链表的插入和删除

    文本主要内容: 链表结构 单链表代码实现 单链表的效率分析 一.链表结构: (物理存储结构上不连续,逻辑上连续:大小不固定)            概念: 链式存储结构是基于指针实现的.我们把一个数据 ...

随机推荐

  1. shellinabox的安装使用

    一.简介 Shell In A Box(发音是shellinabox)是一款基于Web的终端模仿器,由Markus Gutschke开辟而成.它有内置的Web办事器,在指定的端口上作为一个基于Web的 ...

  2. CAD嵌套打印(网页版)

    当用户需要打印两个CAD控件的图纸时,可以采用嵌套打印实现.点击此处在线演示. 实现嵌套打印功能,首先将两个CAD控件放入网页中,js代码如下: <p align="center&qu ...

  3. Webstorm 的 Tab 键调整缩进值

    两步即可,注意版本

  4. PHP生成文档,并把数据加入文档的小案例

    PHP生成文档,可以利用file_put_contents($filename, $data),其中$filename表示文档名,$data表示需要放入的数据, 若存放的是数组,这还需要使用seria ...

  5. tinyxml

    在TinyXML中,根据XML的各种元素来定义了一些类:        TiXmlBase:整个TinyXML模型的基类.        TiXmlAttribute:对应于XML中的元素的属性.   ...

  6. 【转】vfork 和 fork的区别

    fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 1.  fork  ():子进程拷贝父进程的数据段,代码段     vfork ( ):子进程与父进程共享数据段 ...

  7. nginx配置location项的URL匹配规则

    Localtion URL的正则匹配规则 示例 location / { try_files $uri @apache; } #所有的路径都是/开头,表示匹配所有 location @apache { ...

  8. linux中的命令

    1,ln-链接 功能是为某一个文件在另外一个位置建立一个同步的链接,这个命令最常用的参数是-s,具体用法是: ln -s 源文件 目标文件  // -s 是 symbolic(符号,象征)的意思. l ...

  9. ALLEGRO中新画的热风焊盘不能找到的解决办法

    新画的热风焊盘(PCB Thermal Relif)改了路径,要想在Pad Designer中找到,方法是在allegro中Setup-User Preference Editor-Paths-Lib ...

  10. 缩小Oracle目录下UNDOTBS01.DBF文件的大小

    缩小Oracle目录下UNDOTBS01.DBF文件的大小 分类: Oracle 使用sys用户登录Oracle 方法一:重置表空间大小 执行ALTER DATABASE DATAFILE 'D:OR ...