AVL树----java

AVL树是高度平衡的二叉查找树

1.单旋转LL旋转

理解记忆:1.在不平衡的节点的左孩子的左孩子插入导致的不平衡,所以叫LL

private AVLTreeNode<T> leftLeftRotation(AVLTreeNode<T> k2) {AVLTreeNode<T> k1;k1 = k2.left;k2.left = k1.right;k1.right = k2;k2.height = max( height(k2.left), height(k2.right)) + 1;k1.height = max( height(k1.left), k2.height) + 1;return k1;
}

2.单旋转RR

理解记忆:1.不平衡节点的右孩子的有孩子插入导致的不平衡,所以叫RR

private AVLTreeNode<T> rightRightRotation(AVLTreeNode<T> k1) {AVLTreeNode<T> k2;k2 = k1.right;k1.right = k2.left;k2.left = k1;k1.height = max( height(k1.left), height(k1.right)) + 1;k2.height = max( height(k2.right), k1.height) + 1;return k2;
}

3.双旋转LR

理解记忆:1.不平衡节点的左孩子的有孩子导致的不平衡,所以叫LR

2.须要先对k1  RR,再对根K3  LL

private AVLTreeNode<T> leftRightRotation(AVLTreeNode<T> k3) {k3.left = rightRightRotation(k3.left);return leftLeftRotation(k3);
}

4.双旋转RL


理解记忆:1.不平衡节点的右孩子的左孩子导致的不平衡,所以叫RL

2.须要先对k3 LL,在对k1 RR

private AVLTreeNode<T> rightLeftRotation(AVLTreeNode<T> k1) {k1.right = leftLeftRotation(k1.right);return rightRightRotation(k1);
}

5.AVL的样例

遍历,查找等和二叉查找树一样就不在列出,主要是 插入 和  删除


public class AVLTree<T extends Comparable<T>> {private AVLTreeNode<T> mRoot;    // 根结点// AVL树的节点(内部类)class AVLTreeNode<T extends Comparable<T>> {T key;                // keyword(键值)int height;         // 高度AVLTreeNode<T> left;    // 左孩子AVLTreeNode<T> right;    // 右孩子public AVLTreeNode(T key, AVLTreeNode<T> left, AVLTreeNode<T> right) {this.key = key;this.left = left;this.right = right;this.height = 0;}}// 构造函数public AVLTree() {mRoot = null;}/** 获取树的高度*/private int height(AVLTreeNode<T> tree) {if (tree != null)return tree.height;return 0;}public int height() {return height(mRoot);}/** 比較两个值的大小*/private int max(int a, int b) {return a>b ? a : b;}/** 前序遍历"AVL树"*/private void preOrder(AVLTreeNode<T> tree) {if(tree != null) {System.out.print(tree.key+" ");preOrder(tree.left);preOrder(tree.right);}}public void preOrder() {preOrder(mRoot);}/** 中序遍历"AVL树"*/private void inOrder(AVLTreeNode<T> tree) {if(tree != null){inOrder(tree.left);System.out.print(tree.key+" ");inOrder(tree.right);}}public void inOrder() {inOrder(mRoot);}/** 后序遍历"AVL树"*/private void postOrder(AVLTreeNode<T> tree) {if(tree != null) {postOrder(tree.left);postOrder(tree.right);System.out.print(tree.key+" ");}}public void postOrder() {postOrder(mRoot);}/** (递归实现)查找"AVL树x"中键值为key的节点*/private AVLTreeNode<T> search(AVLTreeNode<T> x, T key) {if (x==null)return x;int cmp = key.compareTo(x.key);if (cmp < 0)return search(x.left, key);else if (cmp > 0)return search(x.right, key);elsereturn x;}public AVLTreeNode<T> search(T key) {return search(mRoot, key);}/** (非递归实现)查找"AVL树x"中键值为key的节点*/private AVLTreeNode<T> iterativeSearch(AVLTreeNode<T> x, T key) {while (x!=null) {int cmp = key.compareTo(x.key);if (cmp < 0)x = x.left;else if (cmp > 0)x = x.right;elsereturn x;}return x;}public AVLTreeNode<T> iterativeSearch(T key) {return iterativeSearch(mRoot, key);}/* * 查找最小结点:返回tree为根结点的AVL树的最小结点。*/private AVLTreeNode<T> minimum(AVLTreeNode<T> tree) {if (tree == null)return null;while(tree.left != null)tree = tree.left;return tree;}public T minimum() {AVLTreeNode<T> p = minimum(mRoot);if (p != null)return p.key;return null;}/* * 查找最大结点:返回tree为根结点的AVL树的最大结点。*/private AVLTreeNode<T> maximum(AVLTreeNode<T> tree) {if (tree == null)return null;while(tree.right != null)tree = tree.right;return tree;}public T maximum() {AVLTreeNode<T> p = maximum(mRoot);if (p != null)return p.key;return null;}/** LL:左左相应的情况(左单旋转)。** 返回值:旋转后的根节点*/private AVLTreeNode<T> leftLeftRotation(AVLTreeNode<T> k2) {AVLTreeNode<T> k1;k1 = k2.left;k2.left = k1.right;k1.right = k2;k2.height = max( height(k2.left), height(k2.right)) + 1;k1.height = max( height(k1.left), k2.height) + 1;return k1;}/** RR:右右相应的情况(右单旋转)。** 返回值:旋转后的根节点*/private AVLTreeNode<T> rightRightRotation(AVLTreeNode<T> k1) {AVLTreeNode<T> k2;k2 = k1.right;k1.right = k2.left;k2.left = k1;k1.height = max( height(k1.left), height(k1.right)) + 1;k2.height = max( height(k2.right), k1.height) + 1;return k2;}/** LR:左右相应的情况(左双旋转)。** 返回值:旋转后的根节点*/private AVLTreeNode<T> leftRightRotation(AVLTreeNode<T> k3) {k3.left = rightRightRotation(k3.left);return leftLeftRotation(k3);}/** RL:右左相应的情况(右双旋转)。** 返回值:旋转后的根节点*/private AVLTreeNode<T> rightLeftRotation(AVLTreeNode<T> k1) {k1.right = leftLeftRotation(k1.right);return rightRightRotation(k1);}/* * 将结点插入到AVL树中,并返回根节点** 參数说明:*     tree AVL树的根结点*     key 插入的结点的键值* 返回值:*     根节点*/private AVLTreeNode<T> insert(AVLTreeNode<T> tree, T key) {if (tree == null) {// 新建节点tree = new AVLTreeNode<T>(key, null, null);if (tree==null) {System.out.println("ERROR: create avltree node failed!");return null;}} else {int cmp = key.compareTo(tree.key);if (cmp < 0) {    // 应该将key插入到"tree的左子树"的情况tree.left = insert(tree.left, key);// 插入节点后,若AVL树失去平衡,则进行相应的调节。if (height(tree.left) - height(tree.right) == 2) {if (key.compareTo(tree.left.key) < 0)tree = leftLeftRotation(tree);elsetree = leftRightRotation(tree);}} else if (cmp > 0) {    // 应该将key插入到"tree的右子树"的情况tree.right = insert(tree.right, key);// 插入节点后,若AVL树失去平衡,则进行相应的调节。if (height(tree.right) - height(tree.left) == 2) {if (key.compareTo(tree.right.key) > 0)tree = rightRightRotation(tree);elsetree = rightLeftRotation(tree);}} else {    // cmp==0System.out.println("加入�失败:不同意加入�同样的节点!");}}tree.height = max( height(tree.left), height(tree.right)) + 1;return tree;}public void insert(T key) {mRoot = insert(mRoot, key);}/* * 删除结点(z),返回根节点** 參数说明:*     tree AVL树的根结点*     z 待删除的结点* 返回值:*     根节点*/private AVLTreeNode<T> remove(AVLTreeNode<T> tree, AVLTreeNode<T> z) {// 根为空 或者 没有要删除的节点,直接返回null。if (tree==null || z==null)return null;int cmp = z.key.compareTo(tree.key);if (cmp < 0) {        // 待删除的节点在"tree的左子树"中tree.left = remove(tree.left, z);// 删除节点后,若AVL树失去平衡,则进行相应的调节。if (height(tree.right) - height(tree.left) == 2) {AVLTreeNode<T> r =  tree.right;if (height(r.left) > height(r.right))tree = rightLeftRotation(tree);elsetree = rightRightRotation(tree);}} else if (cmp > 0) {    // 待删除的节点在"tree的右子树"中tree.right = remove(tree.right, z);// 删除节点后,若AVL树失去平衡,则进行相应的调节。if (height(tree.left) - height(tree.right) == 2) {AVLTreeNode<T> l =  tree.left;if (height(l.right) > height(l.left))tree = leftRightRotation(tree);elsetree = leftLeftRotation(tree);}} else {    // tree是相应要删除的节点。// tree的左右孩子都非空if ((tree.left!=null) && (tree.right!=null)) {if (height(tree.left) > height(tree.right)) {// 假设tree的左子树比右子树高;// 则(01)找出tree的左子树中的最大节点//   (02)将该最大节点的值赋值给tree。//   (03)删除该最大节点。// 这相似于用"tree的左子树中最大节点"做"tree"的替身;// 採用这样的方式的优点是:删除"tree的左子树中最大节点"之后,AVL树仍然是平衡的。AVLTreeNode<T> max = maximum(tree.left);tree.key = max.key;tree.left = remove(tree.left, max);} else {// 假设tree的左子树不比右子树高(即它们相等,或右子树比左子树高1)// 则(01)找出tree的右子树中的最小节点//   (02)将该最小节点的值赋值给tree。//   (03)删除该最小节点。// 这相似于用"tree的右子树中最小节点"做"tree"的替身;// 採用这样的方式的优点是:删除"tree的右子树中最小节点"之后,AVL树仍然是平衡的。AVLTreeNode<T> min = maximum(tree.right);tree.key = min.key;tree.right = remove(tree.right, min);}} else {AVLTreeNode<T> tmp = tree;tree = (tree.left!=null) ? tree.left : tree.right;tmp = null;}}return tree;}public void remove(T key) {AVLTreeNode<T> z; if ((z = search(mRoot, key)) != null)mRoot = remove(mRoot, z);}/* * 销毁AVL树*/private void destroy(AVLTreeNode<T> tree) {if (tree==null)return ;if (tree.left != null)destroy(tree.left);if (tree.right != null)destroy(tree.right);tree = null;}public void destroy() {destroy(mRoot);}/** 打印"二叉查找树"** key        -- 节点的键值 * direction  --  0,表示该节点是根节点;*               -1,表示该节点是它的父结点的左孩子;*                1,表示该节点是它的父结点的右孩子。*/private void print(AVLTreeNode<T> tree, T key, int direction) {if(tree != null) {if(direction==0)    // tree是根节点System.out.printf("%2d is root\n", tree.key, key);else                // tree是分支节点System.out.printf("%2d is %2d's %6s child\n", tree.key, key, direction==1?"right" : "left");print(tree.left, tree.key, -1);print(tree.right,tree.key,  1);}}public void print() {if (mRoot != null)print(mRoot, mRoot.key, 0);}
}

文章大量參考:http://www.cnblogs.com/skywang12345/p/3577479.html

AVL树----java相关推荐

  1. avl二叉树 java_平衡二叉树之AVL树(Adelson-Velsky and Landis Tree)简介及Java实现

    平衡二叉树之AVL树(Adelson-Velsky and Landis Tree)简介及Java实现 标签:#二叉树##数据结构##自平衡二叉树# 时间:2018/10/27 09:30:01 作者 ...

  2. AVL树(Java实现)

    文章目录 一.AVL树 二.代码实现(Java) 一.AVL树 二.代码实现(Java) import java.nio.BufferUnderflowException;/*** @author L ...

  3. AVL树-自平衡二叉查找树(Java实现)

    在计算机科学中,AVL树是最先发明的自平衡二叉查找树.AVL树得名于它的发明者 G.M. Adelson-Velsky 和 E.M. Landis,他们在 1962 年的论文 "An alg ...

  4. 数据结构 - 从二叉搜索树说到AVL树(一)之二叉搜索树的操作与详解(Java)

    二叉搜索树(Binary Search Tree),简称BST,顾名思义,一颗可以用于搜索的二叉树.BST在数据结构中占有很重要的地位,一些高级树结构都是其的变种,例如AVL树.红黑树等,因此理解BS ...

  5. 【数据结构与算法】AVL树的Java实现

    前情提要 之前只写了一些AVL树核心算法,这里给出一个AVL树的完整实现. AVL树是平衡查找二叉树,不仅能避免二叉搜索树出现斜树的状况,更是能保持比较标准的O(log2N),但AVL树可能需要很多次 ...

  6. 【数据结构与算法】AVL树核心算法的Java实现

    定义AVL树结点 public class AvlNode<T> {/*** 数据元素*/T element;/*** 结点高度*/int height;/*** 结点左儿子*/AvlNo ...

  7. java数据结构与算法之平衡二叉树(AVL树)的设计与实现中的事实代码

    普通二叉查找树的问题   在开篇,我们提到过,普通二叉树(二叉查找树)在操作的时间复杂度上不一定遵循O(㏒n),也有可能是O(n),这是为什么呢?在上一篇中,我们明明插入都按照一定规则比较的呀,其实那 ...

  8. 构造avl树_图解 AVL 自平衡二叉查找树及 java 实现

    思维导图 AVL树 AVL树是根据它的发明者G.M. Adelson-Velsky和E.M. Landis命名的. 它是最先发明的自平衡二叉查找树(Self-balancing binary sear ...

  9. Java数据结构——平衡二叉树(AVL树)

    AVL树的引入 搜索二叉树有着极高的搜索效率,但是搜索二叉树会出现以下极端情况: 这样的二叉树搜索效率甚至比链表还低.在搜索二叉树基础上出现的平衡二叉树(AVL树)就解决了这样的问题.当平衡二叉树(A ...

最新文章

  1. OpenCV代码提取:Windows上通过DShow获取Camera视频
  2. 关系数据库标准语言 SQL (ch.3)
  3. 在Sublime Text 3中配置编译和运行Java程序
  4. SpringMVC中利用HandlerExceptionResolver完成异常处理
  5. python好学嘛-Python好学吗?Python学习路线
  6. 【Go】从键盘输入字符串和数字
  7. Hello Mybatis 03 数据关联
  8. IP网络设计系列之-局域网设计
  9. php sql注入判断,php防止sql注入漏洞过滤函数的代码
  10. Windows Mobile开发应该选择哪种开发语言?
  11. 据说有人面试栽在了Thread类的stop()方法和interrupt()方法上
  12. python—004
  13. 【PHP】安装wampserver3.1.19后apache无法启动问题
  14. java内存分配分析/栈内存、堆内存
  15. windows通过javaw启动spring boot项目jar命令,查看进程命令,关闭进程命令
  16. php codesniffer 代码规范,如何用PHP_CodeSniffer检查代码规范
  17. 6章4节类的声明和对象与方法
  18. C语言期末考试知识点总结
  19. Mybatis与springboot项目启动时出现Field mapper in ‘xxx‘ required a bean of type ‘xxx‘ that could not be found
  20. xmind打不开java_xmind打开出错(JVM terminated. Exit code=-1) | 学步园

热门文章

  1. React Native - FlexBox弹性盒模型
  2. jstl 处理Date 时间
  3. Linux学习之01_基础命令介绍
  4. 敏捷需要重构吗?不需要吗?
  5. ssh无密码公钥登陆
  6. 彻底删除 XP 自带的 Windows Messenger方法
  7. asp登录页面跳转到注册页面_Java 添加页面跳转按钮到PDF文档
  8. RecycleView弹性滑动
  9. idea中开启Run Dashboard
  10. 两个矩阵相加 Exercise08_05