AVL树
判断该二叉树是否是一棵二分搜索树,判断中序遍历是否有序
判断该二叉树是否是一棵二分搜索树,判断中序遍历是否有序
//判断该二叉树是否是一棵二分搜索树,判断中序遍历是否有序
public boolean isBST() {
ArrayList<K> keys=new ArrayList<>();
inOrder (root,keys);
for(int i=1;i<keys.size();i++)
if(keys.get(i-1).compareTo(keys.get(i))>0)
return false;
return true;
}
private void inOrder(Node node, ArrayList<K> keys) {
if(node==null)
return;
inOrder(node.left,keys);
keys.add(node.key);
inOrder(node.right,keys);
}
判断该二叉树是否是一颗平衡二叉树 (递归)
//判断该二叉树是否是一颗平衡二叉树 (递归)
public boolean isBalanced() {
return isBalanced(root);
}
//判断以Node为根的二叉树是否是一颗平衡二叉树,递归
private boolean isBalanced(Node node) {
if(node==null)
return true;
int balanceFactor=getBalanceFactor(node);
if(Math.abs(balanceFactor)>1)
return false;
return isBalanced(node.left) && isBalanced(node.right);
}
//获得节点node的高度
private int getHeight(Node node) {
if(node==null)
return 0;
return node.height;
}
//获得节点node的平衡因子
private int getBalanceFactor(Node node) {
if(node==null)
return 0;
return getHeight(node.left)-getHeight(node.left);
}
public class AVLTree<K extends Comparable<K>,V> {
private class Node{
public K key;
public V value;
public Node left,right;
public int height;
public Node(K key,V value){//构造函数
this.key=key;
this.value=value;
left=null;
right=null;
height=1; //默认1
}
}
private Node root;//根节点
private int size ;//二分搜素数存了多少个元素
public AVLTree() {
root =null;
size=0;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size==0;
}
//判断该二叉树是否是一棵二分搜索树,判断中序遍历是否有序
public boolean isBST() {
ArrayList<K> keys=new ArrayList<>();
inOrder (root,keys);
for(int i=1;i<keys.size();i++)
if(keys.get(i-1).compareTo(keys.get(i))>0)
return false;
return true;
}
private void inOrder(Node node, ArrayList<K> keys) {
if(node==null)
return;
inOrder(node.left,keys);
keys.add(node.key);
inOrder(node.right,keys);
}
//判断该二叉树是否是一颗平衡二叉树 (递归)
public boolean isBalanced() {
return isBalanced(root);
}
//判断以Node为根的二叉树是否是一颗平衡二叉树,递归
private boolean isBalanced(Node node) {
if(node==null)
return true;
int balanceFactor=getBalanceFactor(node);
if(Math.abs(balanceFactor)>1)
return false;
return isBalanced(node.left) && isBalanced(node.right);
}
//获得节点node的高度
private int getHeight(Node node) {
if(node==null)
return 0;
return node.height;
}
//获得节点node的平衡因子
private int getBalanceFactor(Node node) {
if(node==null)
return 0;
return getHeight(node.left)-getHeight(node.left);
}
//向以node为根的二分搜索树中插入元素e 递归
//返回插入新节点后二分搜索树的根
public void add(K key,V value) {
root=add(root,key,value);
}
private Node add(Node node ,K key,V value) {//返回Node类型的值
if(node==null) { //求解最基本问题
size++;
return new Node(key,value);
}
if(key.compareTo(node.key)<0)
node.left=add(node.left,key,value);//左节点为递归值
else if(key.compareTo(node.key)>0)
node.right=add(node.right,key,value);
//更新height
node.height=1+Math.max(getHeight(node.left),getHeight(node.right));
//计算平衡因子
int balanceFactor=getBalanceFactor(node);
if(Math.abs(balanceFactor)>1)
System.out.println("unbalanced");
return node; //返回根节点
}
AVL树 添加元素时 左平衡右平衡
什么时候维护平衡,加入节点后,沿着节点向上维护平衡性
右旋转
新子树x为根 满足平衡树也满足二分搜索树
LL 右旋转实现
private Node rightRotate(Node y) {
Node x = y.left;
Node T3=x.right;
// 向右旋转过程 (核心代码)
x.right=y;
y.left=T3;
//更新height
y.height=Math.max(getHeight(y.left), getHeight(y.right))+1;
x.height=Math.max(getHeight(x.left), getHeight(x.right))+1;
return x;
}
RR 左旋转![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/58fb11af07c371872eddf83be05315ca.png)
//左旋转
private Node leftRotate(Node y) {
Node x=y.right;
Node T2=x.left;
//向左旋转过程
x.left=y;
y.right=T2;
//更新height
y.height=Math.max(getHeight(y.left), getHeight(y.right))+1;
x.height=Math.max(getHeight(x.left), getHeight(x.right))+1;
return x;
}
然后将左右旋转维护平衡添加到添加元素操作中
public void add(K key,V value) {
root=add(root,key,value);
}
private Node add(Node node ,K key,V value) {//返回Node类型的值
if(node==null) { //求解最基本问题
size++;
return new Node(key,value);
}
if(key.compareTo(node.key)<0)
node.left=add(node.left,key,value);//左节点为递归值
else if(key.compareTo(node.key)>0)
node.right=add(node.right,key,value);
//更新height
node.height=1+Math.max(getHeight(node.left),getHeight(node.right));
//计算平衡因子
int balanceFactor=getBalanceFactor(node);
if(Math.abs(balanceFactor)>1)
System.out.println("unbalanced");
//维护平衡性
if(balanceFactor>1 && getBalanceFactor(node.left)>=0)
return rightRotate(node);//返回给调用的上一层
if(balanceFactor<-1 && getBalanceFactor(node.right)<=0)
return leftRotate(node);
return node; //返回根节点
}
LR RL 其他情况
插入的元素在不平衡节点的左侧的右侧
AVL树删除
//LR
if(balanceFactor>1 && getBalanceFactor(node.left)) {
node.left=leftRotate(node.left);
return rightRotate(node);
}
//RL
if(balanceFactor<-1 && getBalanceFactor(node.right)) {
node.left=rightRotate(node.left);
return leftRotate(node);
}
//删除以node为根的二分搜索树中值为e的节点,递归算法
//返回删除节点后新的二分搜索树的根
private Node remove(Node node, K key) {
if(node==null)
return null;
Node retNode;
if(key.compareTo(node.key)<0) {
node.left=remove(node.left,key);
retNode node;
}
else if(key.compareTo(node.key)>0) {
node.right=remove(node.right,key);
retNode node;
}
else { //e==node.e
//待删除节点左子树为空的情况
if(node.left==null) {
Node rightNode=node.right;
node.right=null;
size--;
retNode rightNode;
}
//待删除节点左子树为空的情况
else if(node.right==null) {
Node leftNode=node.left;
node.left=null;
size--;
retNode leftNode;
}
else {
//待删除节点左右子树均不为空的情况
//找到比这个待删除节点大的最小节点,即待删除节点右字数的的最小节点
//用这个节点顶替待删除节点位置
Node successor = minimum(node.right);
successor.right=remove(node.right,successor.key);//新的代替的节点右子树为删除最小值的树
successor.left =node.left;
node.left=node.right=null;
retNode= successor;
}
}
if(retNode==null)
return null;
//更新height
retNode.height=1+Math.max(getHeight(retNode.left),getHeight(retNode.right));
//计算平衡因子
int balanceFactor=getBalanceFactor(retNode);
//维护平衡性
//LL
if(balanceFactor>1 && getBalanceFactor(retNode.left)>=0)
return rightRotate(retNode);//返回给调用的上一层
//RR
if(balanceFactor<-1 && getBalanceFactor(retNode.right)<=0)
return leftRotate(retNode);
//LR
if(balanceFactor>1 && getBalanceFactor(retNode.left)) {
retNode.left=leftRotate(retNode.left);
return rightRotate(retNode);
}
//RL
if(balanceFactor<-1 && getBalanceFactor(retNode.right)) {
retNode.left=rightRotate(retNode.left);
return leftRotate(retNode);
}
return retNode;
}
基于AVL树的set
public class AVLSet<e extends Comparable<e>>implements Set<E> {
private AVLTree<E,Object> avl;
public AVLSet() {
avl=new AVLTree<>();
}
public int getSize() {
return avl.getSize();
}
public boolean isEmpty() {
return avl.isEmpty();
}
public void add(E e) {
avl.add(e,null);
}
public boolean contains(E e) {
return avl.contains(e);
}
public void remove(E e) {
avl.remove(e);
}
}
基于AVL树的map
public class AVLmap extends Comparable <K extends Comparable<k>,v>implements Map<K,V>{
private AVLTree<K,V> avl;
public AVLMap() {
avl=new AVLTree<>();
}
public int getSize() {
return avl.getSize();
}
public boolean isRmpty() {
return avl.isEmpty();
}
}