博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
13、自平衡二叉查找树AVL
阅读量:6501 次
发布时间:2019-06-24

本文共 4915 字,大约阅读时间需要 16 分钟。

1 package ren.laughing.datastructure.baseImpl;  2   3 /**  4  * 自平衡二叉查找树AVL 继承二叉查找树  5  *   6  * @author Laughing_Lz  7  * @time 2016年4月20日  8  */  9 public class AVLTree extends BSTree { 10     /** 11      * 统一平衡方法 旋转操作 12      *  13      * @param z 14      *            z是失衡的结点 15      * @return 返回平衡后子树的根结点 16      */ 17     private BinTreeNode rotate(BinTreeNode z) { 18         BinTreeNode y = heightSubT(z);// 取y为z更高的孩子 19         BinTreeNode x = heightSubT(y);// 取x为y更高的孩子 20         boolean isLeft =z.isLChild();//标记z是否是左孩子 21         BinTreeNode p = z.getParent();//取z的父结点 22         BinTreeNode a,b,c; 23         BinTreeNode t0,t1,t2,t3; 24         //以下分四种情况重命名 25         if(y.isLChild()){
//1如果y是左孩子 26 c = z; 27 t3 = z.getRChild(); 28 if(x.isLChild()){
//1.1如果x是左孩子(左左失衡) 29 a = x; 30 b = y; 31 t0 = x.getLChild(); 32 t1 = x.getRChild(); 33 t2 = y.getRChild(); 34 }else{
//1.2如果x是右孩子(左右失衡) 35 b = x; 36 a = y; 37 t1 = x.getLChild(); 38 t2 = x.getRChild(); 39 t0 = y.getLChild(); 40 } 41 }else{
//2如果y是右孩子 42 a = z; 43 t0 = z.getLChild(); 44 if(x.isRChild()){
//2.1如果x是右孩子(右右失衡) 45 c = x; 46 b = y; 47 t2 = x.getLChild(); 48 t3 = x.getRChild(); 49 t1 = y.getLChild(); 50 }else{
//2.2如果x是左孩子(右左失衡) 51 b = x; 52 c = y; 53 t1 = x.getLChild(); 54 t2 =x.getRChild(); 55 t3 = y.getRChild(); 56 } 57 } 58 // x.server();//疑问,已经赋值给a b c 还有何用?★ 59 // y.server(); 60 // z.server(); 61 a.server();//断开与父结点的连接 62 b.server(); 63 c.server(); 64 if(t0 != null){ 65 t0.server(); 66 } 67 if(t1 != null){ 68 t1.server(); 69 } 70 if(t2 != null){ 71 t2.server(); 72 } 73 if(t3 != null){ 74 t3.server(); 75 } 76 b.setLChild(a);//重新设置左右孩子,平衡 77 b.setRChild(c); 78 a.setLChild(t0); 79 a.setRChild(t1); 80 c.setLChild(t2); 81 c.setRChild(t3); 82 if(isLeft){ 83 p.setLChild(b); 84 }else{ 85 p.setRChild(b); 86 } 87 return b;//返回平衡后子树的根 88 } 89 90 /** 91 * 获取结点v较高的子树 92 * 93 * @param v 94 * @return 95 */ 96 private BinTreeNode heightSubT(BinTreeNode v) { 97 if (v == null) { 98 return null; 99 }100 int lH = -1;// 若没有左子树,默认左子树高度为-1101 if (v.hasLChild()) {102 lH = v.getLChild().getHeight();103 }104 int rH = -1;// 若没有右子树,默认右子树高度为-1105 if (v.hasRChild()) {106 rH = v.getRChild().getHeight();107 }108 if (lH > rH) {109 return v.getLChild();110 } else if (lH < rH) {111 return v.getRChild();112 } else {
// 若两边子树等高113 if (v.isLChild()) {114 return v.getLChild();115 } else {116 return v.getRChild();117 }118 }119 }120 /**121 * 重写BSTree的insert方法122 * insert之后要重新平衡123 */124 @Override125 public void insert(Object obj) {126 super.insert(obj);127 root = reBalance(startBN);//重新平衡树128 }129 /**130 * 重新平衡AVL树131 * @param startBN132 * @return 返回平衡后的AVL树根结点133 */134 private BinTreeNode reBalance(BinTreeNode startBN) {135 if(startBN == null){136 return root;137 }138 BinTreeNode c = startBN;139 while(startBN != null){
//从startBN开始,向上逐一检查 z 的祖先★140 if(!isBalance(startBN)){
//若startBN失衡,则旋转使之重新平衡★141 startBN = rotate(startBN);142 }143 c = startBN;144 startBN = startBN.getParent();//继续检查其父亲145 }146 return c;147 }148 /**149 * 判断该结点是否平衡150 * @param startBN151 * @return152 */153 private boolean isBalance(BinTreeNode startBN) {154 if(startBN == null){155 return true;156 }157 int lH = startBN.hasLChild()?startBN.getLChild().getHeight():-1;158 int rH = startBN.hasRChild()?startBN.getRChild().getHeight():-1;159 return (Math.abs(lH-rH) <= 1);160 }161 /**162 * 重写BSTree的remove方法163 */164 @Override165 public Object remove(Object ele) {166 Object obj = super.remove(ele);167 root = reBalance(startBN);//重新平衡AVL树168 return obj;169 }170 }

 

转载于:https://www.cnblogs.com/Laughing-Lz/p/5413913.html

你可能感兴趣的文章
轻松记账工程冲刺第二阶段10
查看>>
分离导航模块
查看>>
Lighttpd1.4.20源代码分析 笔记 状态机之错误处理和连接关闭
查看>>
php代码中使用换行及(\n或\r\n和br)的应用
查看>>
高考估分查分选志愿一键搞定_支付宝又操办了件人生大事
查看>>
HTML中的form表单有一个关键属性 enctype
查看>>
LeetCode-135-Candy
查看>>
制作RPM包
查看>>
beego数据输出
查看>>
DecimalFormat
查看>>
如何在同一系统里同时启动多个Tomcat
查看>>
Unix / 类 Unix shell 中有哪些很酷很冷门很少用很有用的命令?(转)
查看>>
java显示本地磁盘所有盘符,显示桌面路径
查看>>
对Cost (%CPU) 粗略的理解
查看>>
java file 操作之创建、删除文件及文件夹
查看>>
SpringMVC学习二
查看>>
HDU Billboard
查看>>
解读源码中的问题
查看>>
7_2判断两个单链表是否相交,若相交,求出第一个交点
查看>>
linux的挂载命令
查看>>