AVL树即是平衡二叉树,是一种特殊的二叉排序树。
它的左右子树都是平衡二叉树,并且左右子树的高度之差的绝对值不超过1。
平衡二叉树就是一棵二叉排序树,是二叉排序树的改进,提高了查找效率。
每插入一个新的结点,就需要检查新结点的插入是否使得原平衡二叉树失去平衡,如果失去平衡则需要进行平衡调整。
为了判断一棵二叉排序树是否是平衡二叉树,引进了平衡因子的概念。平衡因子是针对树中的结点来说的,一个结点的平衡因子为其左子树的高度减去右子树高度的差。
如果右边树的层数减左边层数大于1时。需要右旋转,反之需要左旋转
需要右旋转
第一步创建节点,分别提供get与Set方法,并重写ToString
public class TreeNode { private int val; private TreeNode left;//左 private TreeNode right;//右 TreeNode() {} TreeNode(int val) { this.val = val; }
第二步:需要考虑获取树左右的高度
//返回以TreeNode为根节点的数的高度, public int get(TreeNode TreeNode){ int l=0,r=0; if(TreeNode!=null&&TreeNode.getLeft()!=null){ l += get(TreeNode.getLeft()); } if(TreeNode!=null&&TreeNode.getRight()!=null){ r += get(TreeNode.getRight()); } return Math.max(l,r)+1; } 开始写左旋转
//左旋转 public TreeNode rotation(TreeNode node){ //先创建获取头节点 TreeNode one=new TreeNode(node.getVal()); //不能保证传入的二叉树是不是完全二叉树 if(node.getLeft()!=null){ //由于需要调整的是右边所以没有左子树什么事 one.setLeft(node.getLeft()); } //到这里就有两给独立的树了 node=node.getRight(); //如果新的树右边为null, if(node.getRight()==null){ // node.getLeft()比one大 node.setRight(node.getLeft()); node.setLeft(one); }else{ for(TreeNode f=node;f!=null;f=f.getLeft()){ if(f.getLeft()==null){ f.setLeft(one); break; } } } return node; }
右旋转同样的道理
//右旋转 public TreeNode RightRotation(TreeNode node){ TreeNode one=new TreeNode(node.getVal()); if(node.getRight()!=null){ one.setRight(node.getRight()); } node=node.getLeft(); for(TreeNode f=node;f!=null;f=f.getRight()){ if(f.getRight()==null){ f.setRight(one); break; } } return node; }
//组合方法 //不止能调整完全二叉树。任何二叉树都可以被调整为AVL树 public TreeNode AVL(TreeNode node){ int i =0, i1 =0; if(node.getLeft()!=null){ i = get(node.getLeft()); } if(node.getRight()!=null){ i1 = get(node.getRight()); } if(i>i1&&i-i1>1){ node = RightRotation(node); node =AVL(node); }else if(i<i1&&i1-1>1){ node = rotation(node); node =AVL(node); } return node ; }