数据结构---自平衡二叉树AVL

1.01 AVL树

名字缘由:G.M.Adelson-Velsky和E.M.Landis 。是一种最早的自平衡二分搜索树结构 。
AVL树既是平衡二叉树。AVL树的定义首先要求该树是二叉查找树(满足排序规则),并在此基础上增加了每个节点的平衡因子的定义,一个节点的平衡因子是该节点的左子树树高减去右子树树高的值。

在这里插入图片描述
在这里插入图片描述
平衡因子BF:该节点的左子树的深度减去它的右子树深度。(平衡二叉树上的所有节点的平衡因子可能是-1,0,1)

1.02 AVLTree代码实现

import java.util.ArrayList;

public class AVLTree<K extends Compareble<K>,V>implements Map<K,V>{
	private class Node{	//定义结点
		public K key;
		public V value;
		Node left,right;
		public int height;	//new 新增高度属性
		
		public Node(K key,V value){	//构造函数
			this.key=key;
			this.value=value;
			left=null;
			right=null;
			height=1; //new 结点默认高度为1
		}
		
		public String toString(){  //组成字符串
			return "("+key+","+value+")";
		}
	}

	private Node root;
	private int size;

	public AVLTree(){	//构造函数
		root=null;
		size=0;
	}
	
	public int getSize(){	//获取AVLTree的元素个数
		return size;
	}
    
    private boolean isEmpty(){
    	return size==0;
    }
    
    //new 获得结点node的高度
	private int getHeight(Node node){
		if(node==null){
			return 0;
		}
		return node.height;
	}

	//new 获得结点node的平衡因子
	private int getBalanceFactor(Node node){
		if(node==null){
			return 0;
		}
		return node.height;
	}

	//new 判断二叉树是否是一颗二叉搜索树(中序遍历)
	public boolean isBST(){
		ArrayList<K> keys=new ArrayList<K>();
		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;
	}

	//new 中序遍历
	private void inOrder(AVLTree<K,V>.Node node,ArrayList<K> keys){
		if(node==null){
			return;
		}
		inOrder(node.left,keys);
		keys.add(node.key);
		inOrder(node.right,keys);
	}

	//new 判断该二叉树是否是一颗平衡二叉树(平衡因子的绝对值<=1)
	public boolean isBalanced(){
	    return isBalanced(root);
	}
	//new 判断以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);
	}

	//new 右旋转操作
	private Node rightRotate(node y){
		Node x=y.next;
		Node T3=x.right;
		x.right=y;
		y.left=T3;
		//更新height结点值
		y.heigth=Math.max(getHeight(y.left),getHeight(y.right))+1;
		x.height=Math.max(getHeight(x.left),getHeight(x.right))+1;
		return x;
	}
	
	//new 左旋转操作
	private Node leftRotate(Node y){
		Node x=y.right;
		Node T3=x.left;
		x.left=y;
		y.right=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;
	}

	//增加元素
	public void add(K key,V value){
		root=add(root,key,value);
	}
	private Node add(Node node,K key,V value){
		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);
		}else{
			node.value=value;
		}
		//new 更新height
		node.height=1+Math.max(getHeight(node.left),getHeight(node.right));
		//new计算平衡因子
		int balanceFactor=getBalanceFactor(node);
		if(Math.abs(balanceFactor)>1){
			System.out.println("unbalanced:"+balanceFactor);
		}
		//new 平衡维护
		//new 1.左侧的左侧不平衡-》LL
		if(balanceFactor>1&&getBalanceFactor(node.left)>=0){
			return rightRotate(node);
		}
		//new 2.右侧的右侧不平衡-》RR
		if(balanceFactor<-1&&getBalanceFactor(node.right)<=0){
			return leftRotate(node);
		}
		//new 3.左侧的右侧不平衡-》LR
		if(balanceFactor>1&&getBalanceFactor(node.left)<0){
			node.left=leftRotate(node.left);
			return rightRotate(node);
		}
		//new 4.右侧的左侧不平衡-》RL
		if(balanceFactor<-1&&getBalanceFactor(node.right)>0){
			node.right=rightRotate(node.right);
			return leftRotate(node);
		}
		return node;
	}

	public V get(K key){ //根据键找值
		Node node=getNode(root,key);
		return node==null?null:node.value;
	}

	public void set(K key,V value){	//修改元素
		Node node=getNode(root,key);
		if(node==null){
			throw new IllegalArgumentException("doesn't exist!");
		}
		node.value=value;
	}

	public V remove(K key){	//删除元素
		Node node=getNode(root,key);
		if(node!=null){
			root=remove(root,key);
			return node.value;
		}
		return null;
	}
	private Node remove(Node node,K key){
		if(node==null){
			return null;
		}
		//只需要将删除结点后的新树的根进行自平衡即可
		//new 用retNode接收返回的结点
		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{
			if(node.left==null){
				Node rightNode=node.left;
				node.right=null;
				size--;
				retNode=rightNode;
			}else if(node.right==null){
				Node leftNode=node.left;
				node.left=null;
				size--;
				retNode=leftNode;
			}else{
				Node successor=minimun(node.right);
				//new注意Bug所在 removeMin没有自平衡手段
				//可以在removeMin中自平衡
				//或者在此调用remove即可,只不过要注意左为空,右为空,左右不为空三者是互斥逻辑
				//而且甚至会出现为空的情况 注意空指针异常
				successor.left=node.left;
				node.left=node.right=null;
				retNode=successor;
			}
		}
		//new避免空指针
		if(retNode==null){
			return null;
		}
		//new更新height
		retNode.height=1+Math.amx(getHeight(retNode.left),getHeight(retNode.right));
		//new计算平衡因子
		int balanceFactor=getBalanceFactor(node);
		if(Math.abs(balanceFactor)>1){
			System.out.println("unbalanced:"+balanceFactor);
		}
		//new 平衡维护
		//new 1.左侧的左侧不平衡-》LL
		if(balanceFactor>1&&getBalanceFactor(node.left)>=0){
			return rightRotate(node);
		}
		//new 2.右侧的右侧不平衡-》RR
		if(balanceFactor<-1&&getBalanceFactor(node.right)<=0){
			return leftRotate(node);
		}
		//new 3.左侧的右侧不平衡-》LR
		if(balanceFactor>1&&getBalanceFactor(node.left)<0){
			node.left=leftRotate(node.left);
			return rightRotate(node);
		}
		//new 4.右侧的左侧不平衡-》RL
		if(balanceFactor<-1&&getBalanceFactor(node.right)>0){
			node.right=rightRotate(node.right);
			return leftRotate(node);
		}
		return retNode;
	}

	private Node minimum(Node node){	//获取最小元素
		if(node.left==null){
			return node;
		}else{
			return minimum(node.left);
		}
	}

	public boolean contains(K key){	//是否包含
		returngetNode(root,key)!=null;
	}
	private Node getNode(Node node,K key){
		if(node==null){
			return null;
		}
		if(key.compareTo(node.key)==0){
			return node;
		}else if(key.compareTo(node.key)<0){
			return getNode(node.left,key);
		}else{
			return getNode(node.right,key);
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值