定义
- 是一个特殊的 二叉查找树
- 任何结点的两个子树的高度差小于等于1
- 前5个函数为后面的功能做铺垫,一般的树都有这些函数
1. 结点
public class Node{ int height; //树高 int value; //存值 Node left; Node right; public Node(int value, Node left, Node right) { this.value = value; this.left = left; this.right = right; this.height = 0; //默认树高为0 } }
2. 树高
//树高 public int height(){ return height(root); } private int height(Node node){ if(node != null){ return node.height; } return 0; //默认为0 }
3. 比大小
//比大小 private int max(int a,int b){ return a>b ? a : b; }
4. 找最值及其结点
//最值 public int min(){ Node node = minTree(root); if(node != null){ return node.value; } return 0; } //最值的结点 private Node minTree(Node node){ if(node == null) return null; while(node.left != null){ node = node.left; } return node; } public int max(){ Node node = maxTree(root); if(node != null){ return node.value; } return 0; } private Node maxTree(Node node){ if(node == null) return null; while(node.right != null){ node = node.right; } return node; }
5. 查找
public Node search(int value){ return search(root,value); } private Node search(Node node,int value){ if(node == null){ return node; } if(value < node.value){ return search(node.left,value); }else if(value > node.value){ return search(node.right,value); }else{ return node; } }
6. 旋转
为了实现任何结点的左右子树高度差小于等于1,就要用旋转
使树达到平衡,而旋转分为,左左旋转,右右旋转,左右旋转和右左旋转
- 左左旋转
private Node leftLeftRotation(Node node){ Node temp; temp = node.left; node.left = temp.right; temp.right = node; node.height = max( height(node.left), height(node.right)) + 1; temp.height = max( height(temp.right), node.height) + 1; return temp; }
- 右右旋转
public Node rightRightRotation(Node node){ Node temp; temp = node.right; node.right = temp.left; temp.left = node; node.height = max( height(node.left), height(node.right)) + 1; temp.height = max( height(temp.left), node.height) + 1; return temp; }
- 左右旋转
//左右旋转 private Node leftRightRotation(Node node){ node.left = rightRightRotation(node.left); return leftLeftRotation(node); }
- 右左旋转
//右左旋转 private Node rightLeftRotation(Node node){ node.right = leftLeftRotation(node.right); return rightRightRotation(node); }
7. 插入
//插入 public void add(int value){ root = add(root,value); } private Node add(Node node,int value){ if(node == null){ node = new Node(value,null,null); }else{ //左移 if(value < node.value){ node.left = add(node.left,value); //插入平衡调整 if((height(node.left) - height(node.right)) == 2){ if (value < node.left.value){ node = leftLeftRotation(node); }else{ node = leftRightRotation(node); } } //右移 }else if(value > node.value){ node.right = add(node.right,value); if ((height(node.right) - height(node.left)) == 2){ if(value > node.right.value){ node = rightRightRotation(node); }else{ node = rightLeftRotation(node); } } //相等 }else{ System.out.println("不能插入相同的值"); } } node.height = max(height(node.left),height(node.right)) + 1; return node; }
8. 删除
public void remove(int value){ Node node; Node tree = root; if( (node = search(root,value)) != null ){ root = remove(tree,node); } } private Node remove(Node tree, Node node){ if( tree == null || node == null){ return null; } //在左树 if(node.value < tree.value){ tree.left = remove(tree.left,node); //删除后不平衡 if(height(tree.right ) - height(tree.left) == 2){ Node temp = tree.right; if(height(temp.left) > height(temp.right)){ tree = rightLeftRotation(tree); }else{ tree = rightRightRotation(tree); } } }else if(node.value > tree.value){ tree.right = remove(tree, node); if(height(tree.left) - height(tree.right) == 2){ Node temp = tree.left; if(height(temp.right) > height(temp.left)){ tree = leftRightRotation(tree); }else{ tree = leftLeftRotation(tree); } } //是该结点了 }else{ if(tree.left != null && tree.right != null){ if(height(tree.left) > height(tree.right)){ Node max = maxTree(tree.left); tree.value = max.value; tree.left = remove(tree.left, max); }else{ Node min = minTree(tree.right); tree.value = min.value; tree.right = remove(tree.right, min); } }else{ Node temp = tree; tree = (tree.left != null) ? tree.left : tree.right; temp = null; } } return tree; }
9. 测试
public static void main(String[] args) { AVLTree tree = new AVLTree(); int[] arrs = {10,20,5,30,1,100,50}; for (int arr : arrs){ tree.add(arr); } tree.preOrder(); tree.add(1000); tree.remove(1); tree.preOrder(); }
20 10 30 分开上下输出----------------- 30 20 40
10. 整体代码
public class AVLTree { private Node root; public class Node{ int height; int value; Node left; Node right; public Node(int value, Node left, Node right) { this.value = value; this.left = left; this.right = right; this.height = 0; } } //树高 public int height(){ return height(root); } private int height(Node node){ if(node != null){ return node.height; } return 0; } //比大小 private int max(int a,int b){ return a>b ? a : b; } //左左旋转 private Node leftLeftRotation(Node node){ Node temp; temp = node.left; node.left = temp.right; temp.right = node; node.height = max( height(node.left), height(node.right)) + 1; temp.height = max( height(temp.right), node.height) + 1; return temp; } //右右旋转 public Node rightRightRotation(Node node){ Node temp; temp = node.right; node.right = temp.left; temp.left = node; node.height = max( height(node.left), height(node.right)) + 1; temp.height = max( height(temp.left), node.height) + 1; return temp; } //左右旋转 private Node leftRightRotation(Node node){ node.left = rightRightRotation(node.left); return leftLeftRotation(node); } //右左旋转 private Node rightLeftRotation(Node node){ node.right = leftLeftRotation(node.right); return rightRightRotation(node); } //插入 public void add(int value){ root = add(root,value); } private Node add(Node node,int value){ if(node == null){ node = new Node(value,null,null); }else{ //左移 if(value < node.value){ node.left = add(node.left,value); //插入平衡调整 if((height(node.left) - height(node.right)) == 2){ if (value < node.left.value){ node = leftLeftRotation(node); }else{ node = leftRightRotation(node); } } //右移 }else if(value > node.value){ node.right = add(node.right,value); if ((height(node.right) - height(node.left)) == 2){ if(value > node.right.value){ node = rightRightRotation(node); }else{ node = rightLeftRotation(node); } } //相等 }else{ System.out.println("不能插入相同的值"); } } node.height = max(height(node.left),height(node.right)) + 1; return node; } public void preOrder(){ preOrder(root); } public void preOrder(Node node){ if(node != null){ System.out.println(node.value); preOrder(node.left); preOrder(node.right); } } public Node search(int value){ return search(root,value); } private Node search(Node node,int value){ if(node == null){ return node; } if(value < node.value){ return search(node.left,value); }else if(value > node.value){ return search(node.right,value); }else{ return node; } } public void remove(int value){ Node node; Node tree = root; if( (node = search(root,value)) != null ){ root = remove(tree,node); } } private Node remove(Node tree, Node node){ if( tree == null || node == null){ return null; } //在左树 if(node.value < tree.value){ tree.left = remove(tree.left,node); //删除后不平衡 if(height(tree.right ) - height(tree.left) == 2){ Node temp = tree.right; if(height(temp.left) > height(temp.right)){ tree = rightLeftRotation(tree); }else{ tree = rightRightRotation(tree); } } }else if(node.value > tree.value){ tree.right = remove(tree, node); if(height(tree.left) - height(tree.right) == 2){ Node temp = tree.left; if(height(temp.right) > height(temp.left)){ tree = leftRightRotation(tree); }else{ tree = leftLeftRotation(tree); } } //是该结点了 }else{ if(tree.left != null && tree.right != null){ if(height(tree.left) > height(tree.right)){ Node max = maxTree(tree.left); tree.value = max.value; tree.left = remove(tree.left, max); }else{ Node min = minTree(tree.right); tree.value = min.value; tree.right = remove(tree.right, min); } }else{ Node temp = tree; tree = (tree.left != null) ? tree.left : tree.right; temp = null; } } return tree; } //最值 public int min(){ Node node = minTree(root); if(node != null){ return node.value; } return 0; } private Node minTree(Node node){ if(node == null) return null; while(node.left != null){ node = node.left; } return node; } public int max(){ Node node = maxTree(root); if(node != null){ return node.value; } return 0; } private Node maxTree(Node node){ if(node == null) return null; while(node.right != null){ node = node.right; } return node; } }
来源:https://www.cnblogs.com/Howlet/p/12215744.html