java实现二叉平衡树

  1. 二叉平衡树定义
    二叉树中所有子树的左右子树的高度差不超过1

  2. 树的高度
    从所有叶节点开始数高度到根节点,其中的最大值即为树的高度

  3. 非平衡二叉树转成平衡二叉树(思路)

  1. 找出所有不平衡的子树,将不平衡子树的根节点记录下来.
  2. 调节位于最下方的子树,使之平衡
  3. 重复1,2步,直到这棵树平衡
    每次调整只调整节点数最少的子树,节点少的子树大部分情况都为4中的基本情况
  1. 二叉树的调节(旋转)
    不平衡的情况(符合二叉树的规则大的节点在右边,小的在左)
    图一
    java实现二叉平衡树_第1张图片
    图二
    java实现二叉平衡树_第2张图片

图一中
1,2两种情况,分别以中间的节点为旋转中心顺时针(1),逆时针(2)将根节点旋转到中间节点的下方.(两种情况对应)
3,4两种情况,将最下方的节点作为根节点,分别将根节点,中间节点作为最下方节点的左右子节点.(两种情况对应)
处理图:(四种情况中列出两种,其余两种对应)
java实现二叉平衡树_第3张图片

图二中
1(ll),2(rr)两种情况,分别以根节点的左子节点(1),右子节点(2)为旋转中心,将跟节点选装至他子节点的下方,子节点的右(左)子节点,称为根节点的左(右)子节点.(两种情况对应)

3(lr),4(rl)两种情况,以最下方的叶子节点的父节点为旋转中心,将跟节点的左(右)子节点旋转至其父节点的下方,这样3,4两种情况就转化成了1,2两种情况,再用处理1,2两种情况的方法处理.(两种情况对应)
处理图:(四种情况中列出两种,其余两种对应)java实现二叉平衡树_第4张图片

其余情况:最小的不平衡子树的高度超过4
java实现二叉平衡树_第5张图片

只需将根节点旋转至节点少的这一侧即可

  1. 算法设计及实现

了解了大致情况,要转换成二叉树,节点的变换,
(1)左右节点变化(是否从有到无或者从无到有),过程中很可能忘记setRight(null)操作,这样这棵树就完全乱了.我的User类中在设置左右节点时,就将左右节点的父节点设置成当前节点

public void setLeft(User faust) {
		
		this.left = faust;
		if(faust != null)
			faust.head = this;
		
	}

	public void setRight(User pippin) {
		
		this.right = pippin;
		if(pippin != null)
			pippin.head = this;
	}

(2)根节点是否改变,根节点没有父节点要setHead(null); root = user;这两步操作

计算树的高度

public int getDepth(User treeRoot){
		
		if(treeRoot == null)
			return 0;
		
		return Math.max(getDepth(treeRoot.getLeft()), getDepth(treeRoot.getRight()))+1;
		
	}

判断是否为平衡二叉树

ArrayList avlUsers = new ArrayList();
int l;//每次记录的是最后一次判断的子树的根
public boolean isAvl(User treeRoot){
		if(treeRoot == null)
			return true;
		if(Math.abs(getDepth(treeRoot.getLeft())-getDepth(treeRoot.getRight()))>1){
			avlUsers.add(treeRoot);//记录不平衡子树的根节点
			if(getDepth(treeRoot.getLeft())>getDepth(treeRoot.getRight()))
				l = 1;//左边子树高导致的不平衡
			else {
				l = 0;//右边子高导致的不平衡
			}
			return false;
		}
		else 
			return isAvl(treeRoot.getLeft())&&isAvl(treeRoot.getRight());//左右子树都平衡,这棵树才平衡
	}

调节算法

public void toAVL(User user){
		
		User insertUser = user.getHead();
		User insertUserHead = insertUser.getHead();
		
		
		if(insertUserHead.getRight() == null || insertUserHead.getLeft()==null){//单转
			treeRoate(user, insertUser, insertUserHead);
			
		}else {
			User p = insertUserHead.getHead();
			int g = getDepth(avlUsers.get(avlUsers.size()-1));
			if (g<5) {
				if(insertUserHead == p.getLeft() && insertUser == insertUserHead.getRight()){//图二中的3,lr
					
					//先单转
					treeRoate(user, insertUser, insertUserHead);
					
					treeRoateLL(p.getLeft().getLeft(), p.getLeft());
				}
				
				else if(insertUserHead == p.getRight() && insertUser == insertUserHead.getLeft()){//图二中的4,rl
					//先单转
					treeRoate(user, insertUser, insertUserHead);
					
					treeRoateLL(p.getRight().getRight(), p.getRight());
				}
			}else//图二中的1,2情况,其余情况
				treeRoateLL(insertUser, insertUserHead);
		}
	}

图一中情况处理

public void treeRoate(User user,User insertUser,User insertUserHead){
		if(user==insertUser.getRight()&&insertUser == insertUserHead.getRight()){//rr
			
			if(insertUserHead == root){
				insertUser.setHead(null);
				root = insertUser;
				insertUser.setLeft(insertUserHead);
				insertUserHead.setRight(null);
			}else {
				User p = insertUserHead.getHead();
				if(p.getLeft() == insertUserHead)
					p.setLeft(insertUser);
				else
					p.setRight(insertUser);
				insertUser.setLeft(insertUserHead);
				insertUserHead.setRight(null);
			}
		}
		else if(user==insertUser.getLeft()&&insertUser == insertUserHead.getLeft()){//ll
			if(insertUserHead == root){
				insertUser.setHead(null);
				root = insertUser;
				insertUser.setRight(insertUserHead);
				insertUserHead.setLeft(null);
			}else {
				User p = insertUserHead.getHead();
				if(p.getLeft() == insertUserHead)
					p.setLeft(insertUser);
				else
					p.setRight(insertUser);
				insertUser.setRight(insertUserHead);
				insertUserHead.setLeft(null);
			}
		}
		else if(user==insertUser.getLeft()&&insertUser == insertUserHead.getRight()){//lr
			if(insertUserHead == root){
				user.setRight(insertUserHead);
				user.setLeft(insertUser);
				user.setHead(null);
				insertUserHead.setLeft(null);
				insertUser.setRight(null);
				root = user;
			}else {
				User p = insertUserHead.getHead();
				if(p.getLeft() == insertUserHead)
					p.setLeft(user);
				else
					p.setRight(user);
				
				user.setRight(insertUserHead);
				user.setLeft(insertUser);
				insertUserHead.setLeft(null);
				insertUser.setRight(null);
				
			}
		}
		else if(user==insertUser.getRight()&&insertUser == insertUserHead.getLeft()){//rl
			if(insertUserHead == root){
				user.setLeft(insertUserHead);
				user.setRight(insertUser);
				user.setHead(null);
				insertUserHead.setRight(null);
				insertUser.setLeft(null);
				root = user;
			}else {
				User p = insertUserHead.getHead();
				if(p.getLeft() == insertUserHead)
					p.setLeft(user);
				else
					p.setRight(user);
				
				user.setLeft(insertUserHead);
				user.setRight(insertUser);
				insertUserHead.setRight(null);
				insertUser.setLeft(null);
				
			}
		}
	}

其余情况和图二中的1,2情况处理

	public void treeRoateLL(User insertUser,User insertUserHead){
		
		User p = avlUsers.get(avlUsers.size()-1);
		User util;
		
		if(l == 0){//rr
			insertUserHead = p.getRight();
			//insertUser = insertUserHead.getRight();
			
			util = insertUserHead.getLeft();
			if(p == root){
				root = insertUserHead;
				insertUserHead.setLeft(p);
				insertUserHead.setHead(null);
				
				p.setRight(util);
			}else {
				
				User pHead = p.getHead();
				
				insertUserHead.setLeft(p);
				p.setRight(util);
				
				if(pHead.getLeft() == insertUserHead)
					pHead.setLeft(insertUserHead);
				else
					pHead.setRight(insertUserHead);
			}
		}
		else {//ll
			insertUserHead = p.getLeft();
			//insertUser = insertUserHead.getLeft();
			
			util = insertUserHead.getRight();
			if(p == root){
				root = insertUserHead;
				insertUserHead.setRight(p);
				insertUserHead.setHead(null);
				
				p.setLeft(util);
			}else {
				
				User pHead = p.getHead();
				
				insertUserHead.setRight(p);
				p.setLeft(util);
				
				if(pHead.getLeft() == insertUserHead)
					pHead.setLeft(insertUserHead);
				else
					pHead.setRight(insertUserHead);
			}
		}
		
	}

总函数

public boolean addAVL(User friend) throws IllegalArgumentException {
		
		if(friend == null){
			throw new IllegalArgumentException();
		}
		
		else {
			this.beFriend(friend);
			
			//清空list结合
			avlUsers.clear();
			
			/*if(isAvl(root) == false)
				toAVL(friend);*/
			User p = root;
			
			//用while循环遍历,将树中所有不平衡子树的根节点存在list集合中
			while(isAvl(p) == false){
				isAvl(p);
				if(l==1)
					p = avlUsers.get(avlUsers.size()-1).getLeft();
				else {
					p = avlUsers.get(avlUsers.size()-1).getRight();
				}
			}
			//如果list集合中有元素,说明树不平衡
			if(avlUsers.size()>0)
				toAVL(friend);
			return true;
		}
		
		return false;
	}

你可能感兴趣的:(java学习)