目前使用的是根据key的hashcode来进行排序,并且没有考虑hash碰撞的问题

 package com.zhou.tree;

 import java.util.Comparator;
import java.util.HashMap;
import java.util.Map; /**
* @Description:
* @author: zhoum
* @Date: 2019-05-16
* @Time: 9:44
*/
public class BinarySearchTree<K,V> { private Node root; private class Node{ private K key; private V value; private Node left,right,parent; public Node(K k,V v,Node parent) {
this.key = k;
this.value = v;
this.parent = parent;
}
} public BinarySearchTree() {} public void put(K k,V v){
if( k == null){ return; }
if(root == null){
root = new Node(k,v,null);
return;
}
insert(root,k,v); } private void insert(Node node,K k,V v){
if(k.hashCode() == node.key.hashCode() && k.equals(node.key)){
node.value = v;
}else if(k.hashCode() > node.key.hashCode()){
if(node.right == null){
Node n = new Node(k,v,node);
node.right = n;
}else {
insert(node.right,k,v);
}
}else {
if(node.left == null){
Node n = new Node(k,v,node);
node.left = n;
}else {
insert(node.left,k,v);
}
}
} public V get(K k){
if(root == null || k == null){
return null;
}
return get(root,k).value;
} private Node get(Node node,K k){
if(node == null){
return null;
}else if(node.key.hashCode() == k.hashCode() && node.key.equals(k)){
return node;
}else if(k.hashCode() > node.key.hashCode()){
if(node.right == null){
return null;
}
return get(node.right,k);
}else {
if(node.left == null){
return null;
}
return get(node.left,k);
} }
public boolean delete(K k){
Node node = get(root , k);
if(node == null){
return false;
}
//被删除节点右孩子为空
if(node.right == null){
//根节点
if(node.parent == null){
if(node.left == null){
root = null;
return true;
}
root = node.left;
root.parent = null;
return true;
}
if(node.parent.left != null && node.key.equals(node.parent.left.key)){
if(node.left == null){
node.parent.left = null;
}else {
node.parent.left = node.left;
node.left.parent = node.parent;
} }else if(node.parent.right != null && node.key.equals(node.parent.right.key)){
if(node.left == null){
node.parent.right = null;
}else {
node.parent.right = node.left;
node.left.parent = node.parent;
} }
return true; }
//被删除节点左孩子为空
if(node.left == null){
//如果为根节点
if(node.parent == null){
if(node.right == null){
root = null;
return true;
}
root = node.right;
root.parent = null;
return true;
}
if(node.parent.left.key.equals(node.key) ){
if(node.right == null){
node.parent.left = null;
}else {
node.parent.left = node.right;
node.right.parent = node.parent;
}
}else if(node.parent.right.key.equals(node.key)){
if(node.right == null){
node.parent.right = null;
}else {
node.parent.right = node.right;
node.right.parent = node.parent;
} }
return true;
} //被删除节点有两孩子
Node deleteNode = get(root , k);
Node minNode = get(root , getMin(deleteNode.right));
deleteNode.right.parent = deleteNode.left.parent = minNode;
if(deleteNode.parent == null){
if(minNode.key.equals(deleteNode.right.key)){
minNode.left = deleteNode.left;
root = minNode;
deleteNode.left.parent = minNode;
minNode.parent = null;
}else {
if(minNode.right != null){
minNode.right.parent = minNode.parent;
minNode.parent.left = minNode.right;
}
minNode.right = deleteNode.right;
minNode.left = deleteNode.left;
deleteNode.right.parent = deleteNode.left.parent = minNode;
minNode.parent = null;
root = minNode;
} }else {
if(minNode.key.equals(deleteNode.right.key)){
minNode.left = deleteNode.left;
minNode.parent = deleteNode.parent;
deleteNode.left.parent = minNode;
if(deleteNode.parent.right.key.equals(deleteNode.key)){
deleteNode.parent.right = minNode;
} else {
deleteNode.parent.left = minNode;
}
}else {
minNode.right.parent = minNode.parent;
minNode.parent.left = minNode.right;
minNode.left = deleteNode.left;
minNode.right = deleteNode.right;
deleteNode.left.parent = deleteNode.right.parent = minNode;
minNode.parent = deleteNode.parent;
if(deleteNode.parent.left.key.equals(deleteNode.key)){ deleteNode.parent.left = minNode;
}else {
deleteNode.parent.right = minNode;
}
}
}
return true;
} private K getMin(Node node){
if(node == null){
return null;
}
if(node.left == null){
return node.key;
}
return getMin(node.left);
} @Override
public String toString() {
Map<K,V> map = new HashMap<>();
setString(map,root);
return map.toString();
} private void setString(Map<K,V> map,Node node){
if(node != null){
map.put(node.key,node.value);
}
if(node.left != null){
setString(map,node.left);
}
if(node.right != null){
setString(map,node.right);
}
} }

测试方法

 public class Test {

     public static void main(String[] args) {

         BinarySearchTree<String,String> b  = new BinarySearchTree<>();
b.put("aaa","123");
b.put("abc","85");
b.put("trf","69");
b.put("u","48");
b.put("jf","1");
b.put("dg","36");
b.put("aaa","999");
System.out.println(b.delete("aaa")); System.out.println(b); }
}

在执行delete前  数据的模型为

删除 aaa后

使用java实现二叉查找树的插入,修改和删除方法的更多相关文章

  1. js/java 获取、添加、修改、删除cookie(最全)

      一.cookie介绍 1.cookie的本来面目 HTTP协议本身是无状态的.什么是无状态呢,即服务器无法判断用户身份.Cookie实际上是一小段的文本信息(key-value格式).客户端向服务 ...

  2. Java知识积累3-XML的DOM解析修改和删除方法

    import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder;import jav ...

  3. Java知识积累-XML的DOM解析修改和删除方法

    import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder;import jav ...

  4. java操作xm——添加、修改、删除、遍历

    package com.xml.zh; import javax.xml.parsers.*; import javax.xml.transform.Transformer; import javax ...

  5. Zookeeper通过java创建、查看、修改、删除znode

    本章主要介绍zookeeper如何使用,其实通过zkCli.cmd我们是可以执行一些操作的:声明:参考及转自<http://www.blogjava.net/BucketLi/archive/2 ...

  6. Java如何连接SQLServer,并实现查询、修改、删除方法

    场景:A:在UI自动化时,删除数据时候,在界面UI提示“该XX已被使用,无法删除”. 这时候我们有需要做数据初始化的操作,需要把历史数据做删除,来确脚本运行的重复执行,和稳定性质. B: 在做新增操作 ...

  7. Java 添加、读取、修改、删除Word文档属性

    Word文档属性包括常规.摘要.统计.内容.自定义等,其中摘要包括标题.主题.作者.经理.单位.类别.关键词.备注等项目,通过设置这些摘要信息或自定义属性可方便对文档的管理.本文中将主要介绍对文档摘要 ...

  8. Easyui datagrid绑定数据,新增,修改,删除方法(一)

    @{ ViewBag.Title = "UsersList"; } <script type="text/javascript"> $(functi ...

  9. 基于Easyui框架的datagrid绑定数据,新增,修改,删除方法(四)

    @{ ViewBag.Title = "xxlist"; } <script type="text/javascript" language=" ...

随机推荐

  1. STA之OCV

    Timing sign-off Corner = library PVT +RC Corner + OCV 针对每个工艺结点,foundry都会给出一张类似的timing sign-off表格,定义了 ...

  2. 隐藏pyqt中调用matplotlib图片中的工具栏

    方法: # pyqtgraph使用matplotlib import pyqtgraph.widgets.MatplotlibWidget as mw a_plt = mw.MatplotlibWid ...

  3. 使用Spring框架整合Java Mail

    我的博客名为黑客之谜,今天演示的案例中会出现我的邮箱,还不赶紧收藏!我现在是小白,但是随着时间的流逝,我会逐渐向大神走进,所以,喜欢我的,或者喜欢大神的,点一波关注吧!顺便说一下,双十二快到了,有什么 ...

  4. 「JSOI2015」串分割

    「JSOI2015」串分割 传送门 首先我们会有一个贪心的想法:分得越均匀越好,因为长的绝对比短的大. 那么对于最均匀的情况,也就是 \(k | n\) 的情况,我们肯定是通过枚举第一次分割的位置,然 ...

  5. 「JSOI2015」圈地

    「JSOI2015」圈地 传送门 显然是最小割. 首先对于所有房子,权值 \(> 0\) 的连边 \(s \to i\) ,权值 \(< 0\) 的连边 \(i \to t\) ,然后对于 ...

  6. Redis安装及局域网访问配置CentOS

    1.安装gcc,用来编译reids 通过命令 sudo yum install gcc 2.安装redis $ wget http://download.redis.io/releases/redis ...

  7. jmeter的使用---压力测试

    jmeter用于压力测试 首先我们要区别压力和攻击,当设立了不适当的线程数量和准备时长,就容易造成攻击. 线程数:虚拟用户数.一个虚拟用户占用一个进程或线程.设置多少虚拟用户数在这里也就是设置多少个线 ...

  8. 创建Maven project 提示pom.xml 首行错误

    背景 使用eclipse创建Maven SpringBoot 2.2.0 项目时报错,更换springboot 版本也不行,排除框架依赖原因.然后别人的eclipse创建的同样2.2.2 maven项 ...

  9. opencv python:图像二值化

    import cv2 as cv import numpy as np import matplotlib.pyplot as plt # 二值图像就是将灰度图转化成黑白图,没有灰,在一个值之前为黑, ...

  10. Go标准库之Log

      文章引用自 Go语言标准库log介绍 无论是软件开发的调试阶段还是软件上线之后的运行阶段,日志一直都是非常重要的一个环节,我们也应该养成在程序中记录日志的好习惯. log Go语言内置的log包实 ...