• 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
  • 相关阅读:
    怎么将一个类的成员函数作为指针传递给另一个类的成员函数 沉沉_
    C/C++中的头文件多文件组织 沉沉_
    函数的返回值返回变量和引用 沉沉_
    多操作赋的语义判断(如 int& *a和int* &a) 沉沉_
    ctags: 提示错误ctags: unrecognized option 'format=2' 沉沉_
    C++中关于流的概念 沉沉_
    Verilog 初学笔记顺序操作 和 并行操作的一点思考(参考黑金教程:Verilog HDL那些事 建模篇) 沉沉_
    void 指针 (转载) 沉沉_
    C语言的体系结构main函数存在的必然性(听杨力祥老师的课) 沉沉_
    转载:VC6.0中容易遇到的错误。http://hi.baidu.com/%C8%FD%C9%EE/blog/item/4a756ff2cb6bdb19b07ec5df.html 沉沉_
  • 原文地址:https://www.cnblogs.com/Laughing-Lz/p/5413913.html
Copyright © 2020-2023  润新知