import java.util.Random;

/**
* 二叉排序树(又称二叉查找树)
* (1)能够是一颗空树
* (2)若左子树不空,则左子树上全部的结点的值均小于她的根节点的值
* (3)若右子树不空,则右子树上全部的结点的值均大于她的根节点的值
* (4)左、右子树也分别为二叉排序树
*
*
* 性能分析:
* 查找性能:
* 含有n个结点的二叉排序树的平均查找长度和树的形态有关。
* (最坏情况)当先后插入的keyword有序时。构成的二叉排序树蜕变为单枝树。查找性能为O(n)
* (最好情况)二叉排序树的形态和折半查找的判定树同样,其平均查找长度和log2(n)成正比
*
*
* 插入、删除性能:
* 插入、删除操作间复杂度都O(log(n))级的。
* 即经过O(log(n))时间搜索到了需插入删除节点位置和删除节点的位置
* 经O(1)级的时间直接插入和删除
* 与顺序表相比。比序顺序表插入删除O(n)(查找时间O(log(n))移动节点时间O(n))要快
* 与无序顺序表插入时间O(1),删除时间O(n)相比,由于是有序的,所查找速度要快非常多
*
*
*
* 作者:小菜鸟
* 创建时间:2014-08-17
*
*/ public class BinarySortTree { private Node root = null; /**查找二叉排序树中是否有key值*/
public boolean searchBST(int key){
Node current = root;
while(current != null){
if(key == current.getValue())
return true;
else if(key < current.getValue())
current = current.getLeft();
else
current = current.getRight();
}
return false;
} /**向二叉排序树中插入结点*/
public void insertBST(int key){
Node p = root;
/**记录查找结点的前一个结点*/
Node prev = null;
/**一直查找下去,直到到达满足条件的结点位置*/
while(p != null){
prev = p;
if(key < p.getValue())
p = p.getLeft();
else if(key > p.getValue())
p = p.getRight();
else
return;
}
/**prve是要安放结点的父节点,依据结点值得大小,放在对应的位置*/
if(root == null)
root = new Node(key);
else if(key < prev.getValue())
prev.setLeft(new Node(key));
else prev.setRight(new Node(key));
} /**
* 删除二叉排序树中的结点
* 分为三种情况:(删除结点为*p 。其父结点为*f)
* (1)要删除的*p结点是叶子结点,仅仅须要改动它的双亲结点的指针为空
* (2)若*p仅仅有左子树或者仅仅有右子树,直接让左子树/右子树取代*p
* (3)若*p既有左子树,又有右子树
* 用p左子树中最大的那个值(即最右端S)取代P。删除s,重接其左子树
* */
public void deleteBST(int key){
deleteBST(root, key);
}
private boolean deleteBST(Node node, int key) {
if(node == null) return false;
else{
if(key == node.getValue()){
return delete(node);
}
else if(key < node.getValue()){
return deleteBST(node.getLeft(), key);
}
else{
return deleteBST(node.getRight(), key);
}
}
} private boolean delete(Node node) {
Node temp = null;
/**右子树空,仅仅须要重接它的左子树
* 假设是叶子结点,在这里也把叶子结点删除了
* */
if(node.getRight() == null){
temp = node;
node = node.getLeft();
}
/**左子树空, 重接它的右子树*/
else if(node.getLeft() == null){
temp = node;
node = node.getRight();
}
/**左右子树均不为空*/
else{
temp = node;
Node s = node;
/**转向左子树,然后向右走到“尽头”*/
s = s.getLeft();
while(s.getRight() != null){
temp = s;
s = s.getRight();
}
node.setValue(s.getValue());
if(temp != node){
temp.setRight(s.getLeft());
}
else{
temp.setLeft(s.getLeft());
}
}
return true;
} /**中序非递归遍历二叉树
* 获得有序序列
* */
public void nrInOrderTraverse(){
Stack<Node> stack = new Stack<Node>();
Node node = root;
while(node != null || !stack.isEmpty()){
while(node != null){
stack.push(node);
node = node.getLeft();
}
node = stack.pop();
System.out.println(node.getValue());
node = node.getRight();
}
} public static void main(String[] args){
BinarySortTree bst = new BinarySortTree();
/**构建的二叉树没有同样元素*/
int[] num = {4,7,2,1,10,6,9,3,8,11,2, 0, -2};
for(int i = 0; i < num.length; i++){
bst.insertBST(num[i]);
}
bst.nrInOrderTraverse();
System.out.println(bst.searchBST(10));
bst.deleteBST(2);
bst.nrInOrderTraverse();
} /**二叉树的结点定义*/
public class Node{
private int value;
private Node left;
private Node right; public Node(){
}
public Node(Node left, Node right, int value){
this.left = left;
this.right = right;
this.value = value;
}
public Node(int value){
this(null, null, value);
} public Node getLeft(){
return this.left;
}
public void setLeft(Node left){
this.left = left;
}
public Node getRight(){
return this.right;
}
public void setRight(Node right){
this.right = right;
}
public int getValue(){
return this.value;
}
public void setValue(int value){
this.value = value;
}
} }

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. CREATE FUNCTION - 定义一个新函数

    SYNOPSIS CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] ) RETURNS rettype { LANGUAGE lang ...

  2. MySQL 中去重 distinct 用法

    在使用MySQL时,有时需要查询出某个字段不重复的记录,这时可以使用mysql提供的distinct这个关键字来过滤重复的记录,但是实际中我们往往用distinct来返回不重复字段的条数(count( ...

  3. 获取minist数据并转换成lmdb

    caffe本身是没有数据集的,但在data目录下有获取数据的一些脚本.MNIST,一个经典的手写数字库,包含60000个训练样本和10000个测试样本,每个样本为28*28大小的黑白图片,手写数字为0 ...

  4. mac vim设置python语法高亮

    1 "显示行号  2 set nu  3   4 "设置缩进tabstop  5 set ts=4  6 set shiftwidth=4  7 set expandtab  8 ...

  5. Delphi最简化异步选择TCP服务器

    网上Delphi的Socket服务器优良代码,实在少见,索性写个简化的异步Socket服务器,虽然代码较少,但却该有的都有了,使用的是异步选择WSAAsyncSelect,减少了编写线程的繁琐.可能会 ...

  6. li标签和checkbox绑定

    参考原文:https://www.cnblogs.com/youxin/p/3885496.html 我们经常需要li或span包含一个checkbox,不管点击checkbox或li都会触发相应的事 ...

  7. ios中摄像头/相册获取图片压缩图片上传服务器方法总结

    本文章介绍了关于ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结,有需要了解的同学可以参考一下下.     这几天在搞iphone上面一个应用的开发,里面有需要摄像头/相册编程和图片上传的问 ...

  8. 如何在 CentOS 7 上生成 SSL 证书为 Nginx 加密

    本文首发:开发指南:如何在 CentOS 7 上安装 Nginx Let’s Encrypt 是由 Internet Security Research Group (ISRG) 开发的一个自由.自动 ...

  9. JS实现标签页切换效果

    本文实例为大家分享了JS标签页切换的具体代码,供大家参考,具体内容如下   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ...

  10. buf.fill()

    buf.fill(value[, offset[, end]][, encoding]) value {String} | {Buffer} | {Number} offset {Number} 默认 ...