使用java实现二叉查找树的插入,修改和删除方法
目前使用的是根据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实现二叉查找树的插入,修改和删除方法的更多相关文章
- js/java 获取、添加、修改、删除cookie(最全)
一.cookie介绍 1.cookie的本来面目 HTTP协议本身是无状态的.什么是无状态呢,即服务器无法判断用户身份.Cookie实际上是一小段的文本信息(key-value格式).客户端向服务 ...
- Java知识积累3-XML的DOM解析修改和删除方法
import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder;import jav ...
- Java知识积累-XML的DOM解析修改和删除方法
import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder;import jav ...
- java操作xm——添加、修改、删除、遍历
package com.xml.zh; import javax.xml.parsers.*; import javax.xml.transform.Transformer; import javax ...
- Zookeeper通过java创建、查看、修改、删除znode
本章主要介绍zookeeper如何使用,其实通过zkCli.cmd我们是可以执行一些操作的:声明:参考及转自<http://www.blogjava.net/BucketLi/archive/2 ...
- Java如何连接SQLServer,并实现查询、修改、删除方法
场景:A:在UI自动化时,删除数据时候,在界面UI提示“该XX已被使用,无法删除”. 这时候我们有需要做数据初始化的操作,需要把历史数据做删除,来确脚本运行的重复执行,和稳定性质. B: 在做新增操作 ...
- Java 添加、读取、修改、删除Word文档属性
Word文档属性包括常规.摘要.统计.内容.自定义等,其中摘要包括标题.主题.作者.经理.单位.类别.关键词.备注等项目,通过设置这些摘要信息或自定义属性可方便对文档的管理.本文中将主要介绍对文档摘要 ...
- Easyui datagrid绑定数据,新增,修改,删除方法(一)
@{ ViewBag.Title = "UsersList"; } <script type="text/javascript"> $(functi ...
- 基于Easyui框架的datagrid绑定数据,新增,修改,删除方法(四)
@{ ViewBag.Title = "xxlist"; } <script type="text/javascript" language=" ...
随机推荐
- opencv:截取 ROI 区域
Rect roi; roi.x = 100; roi.y = 100; roi.width = 250; roi.height = 200; // 截取 ROI 区域 // 这种方式改变 sub,原图 ...
- 【代码学习】PYTHON装饰器
一.装饰器 对原代码不修改的基础上完善代码 写代码要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即: 封闭 ...
- [USACO12JAN]牛联盟Bovine Alliance
传送门:https://www.luogu.org/problemnew/show/P3043 其实这道题十分简单..看到大佬们在用tarjan缩点,并查集合并.... 蒟蒻渣渣禹都不会. 渣渣禹发现 ...
- Top 9 colleges in the world from 2010 to 2020, AI and interdisciplinary areas.
http://csrankings.org/
- Spring 事务管理的API
Spring事务管理有3个API,均为接口. (1)PlatformTransactionManager 平台事务管理器 常用的实现类: DataSourceTransactionManager ...
- maven工程引入外部jar包
pom.xml: <dependency> <groupId>new</groupId> <artifactId>new</artifactId& ...
- Cisco TrustSec(理解)
1.Cisco TrustSec的限制当指定了无效的设备ID时,受保护的访问凭据(Protected access credential,PAC)设置将失败并保持挂起状态. 即使在清除PAC并配置正确 ...
- 洛谷P1991 无线通讯网(最小生成树性质+连通块)
题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫星电话线路的哨所(两边都 ...
- Robot Framework 使用【2】-- MAC系统搭建Robot Framework
前言 上一篇中讲述了如何在windows环境下搭建Robot Framework,发完帖后有几位小伙伴就私下留言有没有MAC版本的搭建过程,由于笔者MAC上是安装了旧版本的,经过笔者本周零碎时间的尝试 ...
- __str__()方法和__repr__()方法
有时候我们想让屏幕打印的结果不是对象的内存地址,而是它的值或者其他可以自定义的东西,以便更直观地显示对象内容,可以通过在该对象的类中创建或修改__str__()或__repr__()方法来实现(显示对 ...