平衡二叉树的插入(java实现)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_37885641/article/details/83065619
/**
 * @author hgl
 * @data 2018年9月24日
 * @description 平衡二叉树的结点
 */
public class BSTNode {

	public int data;//数据
	public int bf;//结点的平衡因子
	
	public BSTNode lchild;//左孩子
	
	public BSTNode rchild;//右孩子
	
	public BSTNode parent;//父结点
}
public class Bcount {

	public int count;
}
/**
 * @author hgl
 * @data 2018年9月24日
 * @description 生成平衡二叉树
 */
public class Gtree {

	/*
	 * 左子树高
	 */
	public final static int LH = 1;
	
	/*
	 * 左右子树等高
	 */
	public final static int EH = 0;
	
	/*
	 * 右子树高
	 */
	public final static int RH = -1;

	
	/*
	 * 注意:p是二叉排序树上插入结点而失去平衡的最小子树根结点
	 */
	
	/**
	 * void
	 * @param p
	 * description:对以p为根的二叉排序树作右旋处理,处理之后,
	 * p为新的树根结点,即旋转处理之前的左子树的根结点
	 */
	public static BSTNode r_rotate(BSTNode p){
		BSTNode lc = p.lchild;
		BSTNode pt;
		if(p.parent!=null){
			pt = p.parent;
			pt.rchild = lc;
		}
		lc.parent = p.parent;
		p.lchild = lc.rchild;
		lc.rchild = p;
		p.parent = lc;
		p = lc;
		return p;
	}
	
	/**
	 * void
	 * @param p
	 * description:对以p为根的二叉排序树作左旋处理,处理之后,p
	 * 为新的树根结点,即旋转处理之前的右子树的根结点
	 */
	public static BSTNode l_rotate(BSTNode p){
		
		BSTNode rc = p.rchild;
		BSTNode pt = p.parent;
		rc.parent = p.parent;
		p.rchild = rc.lchild;
		rc.lchild = p;
		p.parent = rc;
		pt.lchild = rc;
		p = rc;
		return p;
	}
	
	/**
	 * void
	 * @param T
	 * @param e
	 * @param taller
	 * description:向二叉排序树中插入结点
	 * T是插入点的根结点
	 */
	@SuppressWarnings("all")
	public static int InsertAVL(BSTNode T,int e,Bcount taller){
		
		//taller 代表T长高与否
		if(T.data == 0){
			T.data = e;
			T.lchild = null;
			T.rchild = null;
			T.bf = EH;
			taller.count = 1;
		}else{
			if(e == T.data){
				taller.count = 0;
				return -1;
			}
			if(e > T.data){//如果待插入结点的值大于T结点的值
				BSTNode rc = null;
				if(T.rchild == null){
					rc = new BSTNode();
					T.rchild = rc;
					rc.parent = T;
				}else{
					rc = T.rchild;
				}
				if(InsertAVL(rc, e, taller) == -1){ //插入失败
					return -1;
				}
				if(taller.count == 1){ //已插入,且右子树增高
					switch(T.bf){
					//原本左子树比右子树高,现左/右子树等高
					case LH:
						T.bf = EH;
						taller.count = 0;
						break;
					//原本左右子树等高,现因右子树变高而使树增高
					case EH:
						T.bf = RH;
						taller.count = 1;
						break;
					case RH:
						RightBalance(T);
						taller.count = 0;
						break;
					}
				}
			}else{
				BSTNode lc = null;
				if(T.lchild == null){
					lc = new BSTNode();
					T.lchild = lc;
					lc.parent = T;
				}else{
					lc = T.lchild;
				}
				if(InsertAVL(lc, e, taller) == -1) return -1;
				if(taller.count == 1){
					switch(T.bf){
					//原本左子树比右子树高,需要作平衡处理
					case LH:
						LeftBalance(T);
						taller.count = 0;
						break;
						//原本左右子树等高,现因左子树变高而使树增高
					case EH:
						T.bf = LH;
						taller.count = 1;
						break;
						//原本右子树比左子树高,现左右子树等高
					case RH:
						T.bf = EH;
						taller.count = 0;
						break;
					}
				}
			}
		}
		return 0;
	}
	
	/**
	 * void
	 * @param T
	 */
	public static void LeftBalance(BSTNode T){
		BSTNode lc = T.lchild;//
	
		BSTNode rd = null;
		switch(lc.bf){ //检查T的左子树的平衡度,并做相应平衡处理
		case LH:  //新结点插入在T的左孩子的左子树上,要作单右旋处理
			T.bf = lc.bf = EH;
			T=r_rotate(T);
			break;
		case RH: //新结点插入在T的左孩子的右子树上,要作双旋处理
			rd = lc.rchild; //rd为T的左孩子的右子树的根
			switch(rd.bf){ //修改T及其左孩子的平衡因子
			case LH:
				T.bf = RH;
				lc.bf = EH;
				break;
			case EH:
				T.bf = lc.bf = EH;
				break;
			case RH:
				T.bf = EH;
				lc.bf = LH;
				break;
			}
			rd.bf = EH;
			l_rotate(T.lchild); //对T的左子树作左旋平衡处理
			r_rotate(T); //对T作右旋平衡处理
		}
	}
	
	
	/**
	 * void
	 * @param T
	 */
	public static void RightBalance(BSTNode T){
		BSTNode rc = T.rchild;
		BSTNode ld = null;
		switch(rc.bf){
		case RH:
			T.bf = rc.bf = EH;
			T = l_rotate(T);
			break;
		case LH:
			ld = rc.lchild;
			switch(ld.bf){
			case RH:
				T.bf = LH;
				rc.bf = EH;
				break;
			case LH:
				T.bf = EH;
				rc.bf = RH;
				break;
			case EH:
				T.bf = rc.bf = EH;
				break;
			}
			ld.bf = EH;
			r_rotate(T.rchild);
			l_rotate(T);
		}
	}
	
	/*
	 * 中序遍历
	 */
	public static void printTree(BSTNode T){
		if(T == null){
			return;
		}
		printTree(T.lchild);
		System.out.println(T.data);
		printTree(T.rchild);
	}
}
public class TestBBST {

	public static void main(String[] args) {
		int[] arr = {32,19,63,22,18,25,28};
		Bcount taller = new Bcount();
		BSTNode T = new BSTNode();
		for(int i = 0;i<arr.length;i++){
				Gtree.InsertAVL(T,arr[i],taller);
		}
		while(T.parent !=null){
			T = T.parent;
		}
		Gtree.printTree(T);
	}
}

测试没有问题,有兴趣的可以多多交流。

猜你喜欢

转载自blog.csdn.net/weixin_37885641/article/details/83065619