13、自平衡二叉查找树AVL
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;// 若没有左子树,默认左子树高度为-1 101 if (v.hasLChild()) { 102 lH = v.getLChild().getHeight(); 103 } 104 int rH = -1;// 若没有右子树,默认右子树高度为-1 105 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 @Override 125 public void insert(Object obj) { 126 super.insert(obj); 127 root = reBalance(startBN);//重新平衡树 128 } 129 /** 130 * 重新平衡AVL树 131 * @param startBN 132 * @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 startBN 151 * @return 152 */ 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 @Override 165 public Object remove(Object ele) { 166 Object obj = super.remove(ele); 167 root = reBalance(startBN);//重新平衡AVL树 168 return obj; 169 } 170 }
—————————————————————————————————————行走在人猿的并行线——Laughing_Lz