使用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=" ...
随机推荐
- 【做题笔记】P2251 质量检测
一看题就知道是线段树裸题了.可是,对于每个 \(i\) ,对应的 \(Q\) 序列的下标是多少呢?应该查询的区间又是什么呢? 找规律: \(i\ \ \ \ \ \ \ \ m\) \(1\ \Rig ...
- 阿里云云服务器ECS开发者工具包(SDK)
阿里云云服务器ECS开发者工具包(SDK) 前提条件 使用Alibaba Cloud SDK for Java,您需要一个阿里云账号和访问密钥(AccessKey). 请在阿里云控制台中的Access ...
- [C++_QT] 代码中不能有中文的解决方案 换行符问题
#开始 今天开始入坑QT了 似乎是个高大上的东西,师傅一直建议我学这个 (如果用C++做界面的话) 配置好环境之后写了代码运行没问题 但是添加了中文字符之后就 die 了,这个问题的话 LInux上的 ...
- 【C语言】创建一个函数,判断某一正整数是否为完数,并调用这个函数找出1000以内所有完数
什么是完数? 如果一个数等于它的因子之和,则称该数为“完数”(或“完全数”). 例如,6的因子为1.2.3,而 6=1+2+3,因此6是“完数”. 问题分析 根据完数的定义,解决本题的关键是计算出所 ...
- python正则表达式中括号的作用,形如 "(\w+)\s+\w+"
先看一个例子: import re string="abcdefg acbdgef abcdgfe cadbgfe" #带括号与不带括号的区别 regex=re.compile(& ...
- JS--easyui通用验证
// JavaScript Document $.extend($.fn.validatebox.defaults.rules, { Composite_validation: { validator ...
- 【快学Docker】快速创建容器,容器常用命令
前言 容器是Docker的三大核心概念之一.简单地说,容器是独立运行的一个或一组应用,以及它们的运行态环境.对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面 ...
- [LeetCode] 735. Asteroid Collision
行星碰撞. 题意是给一个数组 asteroids,表示在同一行的行星.对于数组中的每一个元素,其绝对值表示行星的大小,正负表示行星的移动方向(正表示向右移动,负表示向左移动).每一颗行星以相同的速度移 ...
- Django rest framework框架中有哪些组件
认证 权限(授权) 用户访问次数/频率限制 版本 解析器(parser) 序列化 分页 路由系统 视图 渲染器 认证 自定义认证的类 """ from rest_fram ...
- 关于浮动&关于BFC规范&whyoverflow清除浮动
https://www.cnblogs.com/smivico/p/7656270.html 浮动 https://www.jianshu.com/p/4b93eecb090e BFC https:/ ...