java平衡二叉树AVL数
Posted lee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java平衡二叉树AVL数相关的知识,希望对你有一定的参考价值。
平衡二叉树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树
右旋:在插入二叉树的时候,根节点的右侧高度大于左侧高度,且绝对值超过了2,并且在root.左侧的值大于插入的值时发生右旋 。
左右旋:在插入二叉树的时候,根节点的右侧高度大于左侧高度,且绝对值超过了2,并且在root.左侧的值小于插入的值时发生,先对root的左子树发生左旋,再对root右旋。
左旋:在插入二叉树的时候,根节点的左侧高度大于右侧,绝对值超过2,且root右侧的值小于插入的值,这个时候发生左旋。
右左旋:在插入二叉树的时候,根节点的左侧高度大于右侧,绝对值超过2,且root右侧的值大于插入的值,这个时候发生右左旋。先对root的右子树发生右旋,再对root树发生左旋。
package com.lee.test; /** * 平衡二叉树 插入、删除、遍历 */ public class AVLTree { private class Node{ private Node left; private Node right; private int value; private int height = -1; private Node (int value){ this.value = value; } private Node(){ } } private Node head; //头 public AVLTree(){ } /** * 获取高度 * @param root * @return */ private int Height(Node root){ if (root == null){ return -1; }else { return root.height; } } /** * 右旋 * @return */ private Node rotateRight(Node root){ Node temp = root.left; root.left = temp.right; temp.right = root; root.height = Math.max(Height(root.left),Height(root.right)) +1; //高度设置为两者中最高的一个 temp.height = Math.max(Height(temp.left),Height(temp.right)) +1; //高度设置为两者中最高的一个 return temp; } /** * 左旋 * @return */ private Node rotateLeft(Node root){ Node temp = root.right; root.right = temp.left; temp.left = root; root.height = Math.max(Height(root.left),Height(root.right)) +1; //高度设置为两者中最高的一个 temp.height = Math.max(Height(temp.left),Height(temp.right)) +1; //高度设置为两者中最高的一个 return temp; } /** * 左右旋转 * @param node * @return */ private Node rotateLeftRight(Node node){ node.left = rotateLeft(node.left); return rotateRight(node); } /** * 右左旋转 * @param node * @return */ private Node rotateRightLeft(Node node){ node.right = rotateRight(node.right); return rotateLeft(node); } //插入 public Node insert(Node root ,int value){ if (root == null){ root = new Node(value); }else if(value <root.value){ //插入左边 root.left = insert(root.left,value); if (Height(root.left) - Height(root.right) == 2){ //需要左旋 if (value < root.left.value){ root = rotateRight(root); }else{ root = rotateLeftRight(root); } } }else{ root.right = insert(root.right,value); if (Height(root.right) - Height(root.left) ==2) //需要右旋 { if (value > root.right.value){ root = rotateLeft(root); }else { root = rotateRightLeft(root); } } } root.height = Math.max(Height(root.left),Height(root.right))+1; return root; } private Node deleteNode(Node root,int value) { if(root == null) return root;//根节点null 无操作 if(value < root.value) { root.left = deleteNode(root.left, value); //删除可能发生在左边,继续向下遍历左子树 }else if(value > root.value) { root.right = deleteNode(root.right, value); //删除可能发生在右边,继续向下遍历右子树 }else { //找到需要删除的节点 if(root.left!=null && root.right!=null) { //如果当前结点左右子树不为空,将问题转化为 删除一个子节点为空的节点 Node pre = root.right; while(pre.left != null) { pre = pre.left; } root.value = pre.value; root.right = deleteNode(root.right, pre.value); }else { //左右结点仅有一个或者都为空,删除该节点,如果有子节点 用子节点直接覆盖 root = (root.left != null) ? root.left : root.right; } } //删除完成,调整平衡性 if(root == null) return root; root.height = Math.max(Height(root.left), Height(root.right))+1; //失衡 if(Height(root.left)-Height(root.right)>=2) { //删除发生在右子树,模拟插入发生在左子树 if(Height(root.left.left) > Height(root.left.right)) { //插入发生在左子树,LL旋转 return rotateLeft(root); }else { //LR旋转 return rotateLeftRight(root); } }else if(Height(root.left)-Height(root.right)<=-2){ //删除发生在左子树,模拟插入发生在右子树 if(Height(root.right.left) > Height(root.right.right)) { //RL旋转 return rotateRight(root); }else { //RR旋转 return rotateRightLeft(root); } } //未失衡,不做操作 return root; } //遍历 private void print(Node node){ if (node == null){ return; } print(node.left); System.out.print(node.value+" "); print(node.right); // System.out.println(); } public void add(int value){ head = insert(head,value); } public void delete(int value){ head = deleteNode(head,value); } public void show(){ print(head); System.out.println(); } public static void main(String args[]){ AVLTree tree = new AVLTree(); tree.add(24); tree.add(20); tree.add(26); tree.add(18); tree.add(22); tree.add(23); tree.add(19); tree.add(21); tree.add(17); tree.add(10); tree.add(12); tree.add(14 ); tree.show(); tree.delete(22); tree.show(); } }
以上是关于java平衡二叉树AVL数的主要内容,如果未能解决你的问题,请参考以下文章