树——平衡二叉树插入和查找的JAVA实现(2):增加删除方法
- package com.tomsnail.data.tree;
- /**
- * AVL二叉平衡树
- * @author tomsnail
- * @date 2015年3月30日 下午4:35:50
- */
- public class AVLTree {
- /**
- * 根节点
- * @author tomsnail
- * @date 2015年3月30日 下午4:36:54
- */
- private AVLNode rootNode;
- private String bulidType = "";
- /**
- * 增加一个节点
- * @author tomsnail
- * @date 2015年3月30日 下午4:36:08
- */
- public void add(int value){
- AVLNode subNode = null;
- if(rootNode==null){
- subNode = new AVLNode(value);
- rootNode = subNode;
- }else{
- subNode = addNode(rootNode,value);
- }
- reBuild(subNode);
- }
- private AVLNode addNode(AVLNode node,int value){
- AVLNode subNode = null;
- if(node.getValue()>value){
- if(node.getLeftNode()==null){
- subNode = new AVLNode(value);
- node.setLeftNode(subNode);
- }else{
- subNode = addNode(node.getLeftNode(), value);
- }
- }
- if(node.getValue()<value){
- if(node.getRightNode()==null){
- subNode = new AVLNode(value);
- node.setRightNode(subNode);
- }else{
- subNode = addNode(node.getRightNode(),value);
- }
- }
- return subNode;
- }
- /**
- * 重平衡树
- * @author tomsnail
- * @date 2015年3月30日 下午5:42:00
- */
- private void reBuild(AVLNode node){
- if(node!=null){
- AVLNode tempRootNode = findTempRootNode(node);
- if(tempRootNode!=null){
- if(bulidType.equals("ll")){
- Lrotate(node,tempRootNode);
- }else if(bulidType.equals("rr")){
- Rrotate(node,tempRootNode);
- }else if(bulidType.equals("lr")){
- Rrotate(node,tempRootNode.getLeftNode());
- Lrotate(node,tempRootNode);
- }else if(bulidType.equals("rl")){
- Lrotate(node,tempRootNode.getRightNode());
- Rrotate(node,tempRootNode);
- }
- reBuild(tempRootNode);
- }
- }
- }
- /**
- * 右旋
- * @author tomsnail
- * @date 2015年3月30日 下午9:23:28
- */
- private void Rrotate(AVLNode node,AVLNode tempRootNode){
- AVLNode rotateNode = tempRootNode.getRightNode();//旋转节点
- AVLNode rootNode = tempRootNode.getRootNode();//主根节点
- String type = "";
- if(rootNode!=null){
- if(rootNode.getLeftNode()==tempRootNode){
- type="l";
- }else{
- type="r";
- }
- }
- AVLNode adjustNode = rotateNode.getLeftNode();//调整节点
- rotateNode.setLeftNode(tempRootNode);
- tempRootNode.setRightNode(null);
- if(adjustNode!=null){
- tempRootNode.setRightNode(adjustNode);
- }
- if(rootNode==null){
- rotateNode.setRootNode(null);
- this.rootNode = rotateNode;
- }
- if(type.equals("r")){
- rootNode.setRightNode(rotateNode);
- }else if(type.equals("l")){
- rootNode.setLeftNode(rotateNode);
- }
- }
- /**
- * 左旋
- * @author tomsnail
- * @date 2015年3月30日 下午9:23:28
- */
- private void Lrotate(AVLNode node,AVLNode tempRootNode){
- AVLNode rotateNode = tempRootNode.getLeftNode();//旋转节点
- AVLNode rootNode = tempRootNode.getRootNode();//主根节点
- String type = "";
- if(rootNode!=null){//子树类型
- if(rootNode.getLeftNode()==tempRootNode){
- type="l";
- }else{
- type="r";
- }
- }
- AVLNode adjustNode = rotateNode.getRightNode();//调整节点
- rotateNode.setRightNode(tempRootNode);
- tempRootNode.setLeftNode(null);
- if(adjustNode!=null){
- tempRootNode.setLeftNode(adjustNode);
- }
- if(rootNode==null){
- rotateNode.setRootNode(null);
- this.rootNode = rotateNode;
- }
- if(type.equals("r")){
- rootNode.setRightNode(rotateNode);
- }else if(type.equals("l")){
- rootNode.setLeftNode(rotateNode);
- }
- }
- /**
- * 查找最小不平衡的根节点
- * @author tomsnail
- * @date 2015年3月30日 下午5:40:55
- */
- private AVLNode findTempRootNode(AVLNode node){
- AVLNode noB = getNoBalance(node);
- if(noB==null){
- return null;
- }
- if(isTypeLL(noB)){
- bulidType = "ll";
- }else if(isTypeRR(noB)){
- bulidType = "rr";
- }else if(isTypeLR(noB)){
- bulidType = "lr";
- }else if(isTypeRL(noB)){
- bulidType = "rl";
- }
- return noB;
- }
- //左左类型
- private boolean isTypeLL(AVLNode noB){
- try {
- if(noB.getRightNode()==null&&noB.getLeftNode().getRightNode()==null&&!noB.getLeftNode().getLeftNode().hasSubNode()){
- return true;
- }
- if(noB.getRightNode()!=null&&noB.getLeftNode().getRightNode()!=null&&noB.getLeftNode().getLeftNode().hasSubNode()){
- return true;
- }
- } catch (Exception e) {
- }
- return false;
- }
- //右右类型
- private boolean isTypeRR(AVLNode noB){
- try {
- if(noB.getLeftNode()==null&&noB.getRightNode().getLeftNode()==null&&!noB.getRightNode().getRightNode().hasSubNode()){
- return true;
- }
- if(noB.getLeftNode()!=null&&noB.getRightNode().getLeftNode()!=null&&noB.getRightNode().getRightNode().hasSubNode()){
- return true;
- }
- } catch (Exception e) {
- }
- return false;
- }
- //左右类型
- private boolean isTypeLR(AVLNode noB){
- try {
- if(noB.getRightNode()==null&&noB.getLeftNode().getLeftNode()==null&&!noB.getLeftNode().getRightNode().hasSubNode()){
- return true;
- }
- if(noB.getRightNode()!=null&&noB.getLeftNode().getLeftNode()!=null&&noB.getLeftNode().getRightNode().hasSubNode()){
- return true;
- }
- } catch (Exception e) {
- }
- return false;
- }
- //右左类型
- private boolean isTypeRL(AVLNode noB){
- try {
- if(noB.getLeftNode()==null&&noB.getRightNode().getRightNode()==null&&!noB.getRightNode().getLeftNode().hasSubNode()){
- return true;
- }
- if(noB.getLeftNode()!=null&&noB.getRightNode().getRightNode()!=null&&noB.getRightNode().getLeftNode().hasSubNode()){
- return true;
- }
- } catch (Exception e) {
- }
- return false;
- }
- //获取不平衡的根节点
- private AVLNode getNoBalance(AVLNode node){
- if(node.getRootNode()==null){
- return null;
- }else{
- if(!isBalance(node.getRootNode())){
- return node.getRootNode();
- }else{
- return getNoBalance(node.getRootNode());
- }
- }
- }
- /**
- * 删除一个节点
- * @author tomsnail
- * @date 2015年3月30日 下午4:36:20
- */
- public void delete(int value){
- AVLNode wantDeleteNode = find(value);
- if(wantDeleteNode==null){
- return;
- }else{
- if(wantDeleteNode.getLeftNode()==null&&wantDeleteNode.getRightNode()==null){//删除节点没有左右子树
- AVLNode rootNode = wantDeleteNode.getRootNode();
- if(rootNode!=null){
- if(rootNode.getLeftNode()==wantDeleteNode){
- rootNode.setLeftNode(null);
- }else{
- rootNode.setRightNode(null);
- }
- reBuild(rootNode);
- }
- }else if(wantDeleteNode.getRightNode()==null){//删除节点只有左子树
- AVLNode rootNode = wantDeleteNode.getRootNode();
- if(rootNode!=null){
- if(rootNode.getLeftNode()==wantDeleteNode){
- rootNode.setLeftNode(wantDeleteNode.getLeftNode());
- }else{
- rootNode.setRightNode(wantDeleteNode.getLeftNode());
- }
- wantDeleteNode.setLeftNode(null);
- reBuild(rootNode);
- }
- }else if(wantDeleteNode.getLeftNode()==null){//删除节点只有右子树
- AVLNode rootNode = wantDeleteNode.getRootNode();
- if(rootNode!=null){
- if(rootNode.getRightNode()==wantDeleteNode){
- rootNode.setLeftNode(wantDeleteNode.getRightNode());
- }else{
- rootNode.setRightNode(wantDeleteNode.getRightNode());
- }
- wantDeleteNode.setRightNode(null);
- reBuild(rootNode);
- }
- }else {//删除节点有左右子树
- AVLNode maxNode = getLeftMaxValueNode(wantDeleteNode.getLeftNode());//找到节点左子树最大值的节点
- AVLNode rootMaxNode = maxNode.getRootNode();//获得该节点的父节点
- if(maxNode.getLeftNode()!=null){//如果最大值节点有左子树,则将最大值节点的父节点的右子树设为它
- rootMaxNode.setRightNode(maxNode.getLeftNode());
- maxNode.setLeftNode(null);
- }else{//否则置空
- rootMaxNode.setRightNode(null);
- }
- wantDeleteNode.setValue(maxNode.getValue());//把要删除节点的值用最大值节点的值替换
- maxNode=null;//引用置空
- reBuild(rootMaxNode);
- }
- }
- }
- //得到左子树最大值节点
- private AVLNode getLeftMaxValueNode(AVLNode node){
- if(node!=null&&node.getRightNode()!=null){
- return getLeftMaxValueNode(node.getRightNode());
- }else{
- return node;
- }
- }
- /**
- * 查找一个节点
- * @author tomsnail
- * @date 2015年3月30日 下午4:36:35
- */
- public AVLNode find(int value){
- return findWith2(rootNode,value);
- }
- private AVLNode findWith2(AVLNode node,int value){
- if(node==null){
- return null;
- }
- System.out.println(node.getValue());
- if(node.getValue()>value){
- return findWith2(node.getLeftNode(),value);
- }else if(node.getValue()<value){
- return findWith2(node.getRightNode(),value);
- }else{
- return node;
- }
- }
- /**
- * 中序遍历
- * @author tomsnail
- * @date 2015年3月31日 下午6:23:05
- */
- public void midScan(AVLNode node){
- if(node==null){
- return;
- }
- midScan(node.getLeftNode());
- System.out.println(node.getValue());
- midScan(node.getRightNode());
- }
- public AVLNode getRootNode() {
- return rootNode;
- }
- public static void main(String[] args) {
- int[] is = new int[]{10,11,23,3,5,44,32,4,6,18,19,7,8,70,50,60,40,55,65,53,80};//10,11,23,3,5,44,32,4,6,18,19,7,8,70,50,60,40,55,65,53,80
- AVLTree tree = new AVLTree();
- for(int i=0;i<is.length;i++){
- tree.add(is[i]);
- }
- System.out.println(tree.getRootNode().getValue());
- System.out.println("----------------------------");
- tree.midScan(tree.getRootNode());
- tree.delete(4);
- System.out.println(isBalance(tree.getRootNode()));
- System.out.println();
- //tree.find(40);
- }
- public static int depth(AVLNode node){
- if(node==null){
- return 0;
- }else{
- int ld = depth(node.getLeftNode());
- int rd = depth(node.getRightNode());
- return 1 + (ld >rd ? ld : rd);
- }
- }
- public static boolean isBalance(AVLNode node){
- if (node==null)
- return true;
- int dis = depth(node.getLeftNode()) - depth(node.getRightNode());
- if (dis>1 || dis<-1 )
- return false;
- else
- return isBalance(node.getLeftNode()) && isBalance(node.getRightNode());
- }
- }
- class AVLNode{
- private int value;
- private AVLNode leftNode;
- private AVLNode rightNode;
- private AVLNode rootNode;
- public int getValue() {
- return value;
- }
- public void setValue(int value) {
- this.value = value;
- }
- public AVLNode getLeftNode() {
- return leftNode;
- }
- public void setLeftNode(AVLNode leftNode) {
- this.leftNode = leftNode;
- if(leftNode!=null){
- leftNode.setRootNode(this);
- }
- }
- public AVLNode getRightNode() {
- return rightNode;
- }
- public void setRightNode(AVLNode rightNode) {
- this.rightNode = rightNode;
- if(rightNode!=null){
- rightNode.setRootNode(this);
- }
- }
- public AVLNode getRootNode() {
- return rootNode;
- }
- public void setRootNode(AVLNode rootNode) {
- this.rootNode = rootNode;
- }
- public boolean hasSubNode(){
- if(this.leftNode!=null||this.rightNode!=null){
- return true;
- }else{
- return false;
- }
- }
- public AVLNode(){
- }
- public AVLNode(int value){
- this.value = value;
- }
- }
树——平衡二叉树插入和查找的JAVA实现(2):增加删除方法的更多相关文章
- 树——平衡二叉树插入和查找的JAVA实现
package com.tomsnail.data.tree; /** * AVL二叉平衡树 * @author tomsnail * @date 2015年3月30日 下午4:35:50 */ pu ...
- 数据结构系列之2-3-4树的插入、查找、删除和遍历完整版源代码实现与分析(dart语言实现)
本文属于原创,转载请注明来源. 在上一篇博文中,详细介绍了2-3树的操作(具体地址:https://www.cnblogs.com/outerspace/p/10861488.html),那么对于更多 ...
- 数据结构系列之2-3树的插入、查找、删除和遍历完整版代码实现(dart语言实现)
弄懂了二叉树以后,再来看2-3树.网上.书上看了一堆文章和讲解,大部分是概念,很少有代码实现,尤其是删除操作的代码实现.当然,因为2-3树的特性,插入和删除都是比较复杂的,因此经过思考,独创了删除时分 ...
- DS-二叉排序树的插入、查找和删除
2019-12-02(菜鸡开始学习了...) Data Structure 之 二叉排序树 二叉排序树是给定一个节点后,接下来插入的数如果比它大就会放到它的右孩子那边,比它小就会放到它的左孩子那边. ...
- 萌新笔记——C++里创建 Trie字典树(中文词典)(二)(插入、查找、导入、导出)
萌新做词典第二篇,做得不好,还请指正,谢谢大佬! 做好了插入与遍历功能之后,我发现最基本的查找功能没有实现,同时还希望能够把内存的数据存入文件保存下来,并可以从文件中导入词典.此外,数据的路径是存在配 ...
- C++里创建 Trie字典树(中文词典)(二)(插入、查找、导入、导出)
萌新做词典第二篇,做得不好,还请指正,谢谢大佬! 做好了插入与遍历功能之后,我发现最基本的查找功能没有实现,同时还希望能够把内存的数据存入文件保存下来,并可以从文件中导入词典.此外,数据的路径是存在配 ...
- Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)
@Java300 学习总结 一.自定义节点 LinkList底层为双向链表.特点为查询效率低,但增删效率高,线程不安全. 链表数据储存在节点,且每个节点有指向上个和下个节点的指针. 创建ggLinke ...
- 树·AVL树/平衡二叉树
1.AVL树 带有平衡条件的二叉查找树,所以它必须满足条件: 1 是一棵二叉查找树 2 满足平衡条件 1.1 平衡条件: 1)严格的平衡条件:每个节点都必须有相同高度的左子树和右子树(过于严格而不被使 ...
- 【转】B树、B-树、B+树、B*树、红黑树、 二叉排序树、trie树Double Array 字典查找树简介
B 树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: ...
随机推荐
- hashCode与equals的作用与区别及应当注意的细节
最近去面试了几家公司,被问到hashCode的作用,虽然回答出来了,但是自己还是对hashCode和equals的作用一知半解的,所以决定把它们研究一下. 以前写程序一直没有注意hashCode的作用 ...
- Mac中遇到的Eclipse连接不上mySql的问题
1.首先我们在eclipse中连接数据库的过程中,遇到的问题就是如上图.开始百度Communications link failure 这几个关键字.得到的结果基本上就是基本配置参数wait_time ...
- Druid——阿里巴巴的开源项目(关于数据库连接、监控)
相关文章 0.Druid首页——jdbc连接池,监控组件 1.阿里巴巴的开源项目Druid(关于数据库连接) 2.ITeye谈Druid 3.DBCP(DataBase connection pool ...
- CentOS搭建git服务器实测
Git 可以使用四种主要的协议来传输数据:本地传输,SSH 协议,Git 协议和 HTTP 协议 1,安装: CentOS/Fedora: yum install git Ubuntu/Debian: ...
- linux查看磁盘挂载的三种方法
第一种方法:使用df命令,例如: orientalson:/home # df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda ...
- arcgis10.0 切片并发布服务及验证
1.切片参考网址:https://jingyan.baidu.com/article/fa4125accc6bef28ac7092d7.html 2.通过下面代码验证 参考网址https://www ...
- mfc 小程序---在系统菜单中添加菜单项
1建立一个对话框工程:在dlg类里定义一个菜单指针m_pMenu,在对话框OnInitDialog函数里添加代码: m_pMenu=GetSystemMenu(FALSE);//获取系统菜单的指针 m ...
- CGI模式下的bug
一般情况下$_SERVER['PHP_SELF'] 与 $_SERVER['SCRIPT_NAME'] 没有什么区别,但是如果PHP是以CGI模式运行的话两者就有差异 建议使用$_SERVER[' ...
- Mybatis中resultMap的基础配置
一.概述 resultMap 元素是 MyBatis 中最重要最强大的元素.它就是让你远离 90%的需要从结果集中取出数据的 JDBC 代码的那个东西,而且在一些情形下允许你做一些 JDBC 不支持的 ...
- Android笔记之Retrofit与RxJava的组合
依赖 implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:con ...