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

/**
 * @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);
	}
}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
平衡二叉树(AVL树)是一种自平衡的二叉搜索树,它的左子树和右子树的高度差不超过1。在Java中,可以通过以下步骤实现平衡二叉树: 1. 定义节点类:首先定义一个节点类,包含节点值、左子节点和右子节点等属性。 ```java class Node { int value; Node left; Node right; public Node(int value) { this.value = value; this.left = null; this.right = null; } } ``` 2. 实现平衡二叉树类:创建一个平衡二叉树类,包含插入节点、删除节点、旋转操作等方法。 ```java class AVLTree { private Node root; // 插入节点 public void insert(int value) { root = insertNode(root, value); } private Node insertNode(Node root, int value) { if (root == null) { return new Node(value); } if (value < root.value) { root.left = insertNode(root.left, value); } else if (value > root.value) { root.right = insertNode(root.right, value); } else { // 如果存在相同值的节点,可以根据需求进行处理 return root; } // 更新节点的高度 root.height = 1 + Math.max(getHeight(root.left), getHeight(root.right)); // 平衡操作 int balance = getBalance(root); // 左左情况,进行右旋操作 if (balance > 1 && value < root.left.value) { return rightRotate(root); } // 右右情况,进行左旋操作 if (balance < -1 && value > root.right.value) { return leftRotate(root); } // 左右情况,先左旋再右旋 if (balance > 1 && value > root.left.value) { root.left = leftRotate(root.left); return rightRotate(root); } // 右左情况,先右旋再左旋 if (balance < -1 && value < root.right.value) { root.right = rightRotate(root.right); return leftRotate(root); } return root; } // 删除节点 public void delete(int value) { root = deleteNode(root, value); } private Node deleteNode(Node root, int value) { // 空树或未找到节点 if (root == null) { return root; } if (value < root.value) { root.left = deleteNode(root.left, value); } else if (value > root.value) { root.right = deleteNode(root.right, value); } else { // 找到要删除的节点 // 节点只有一个子节点或无子节点 if (root.left == null || root.right == null) { Node temp = null; if (temp == root.left) { temp = root.right; } else { temp = root.left; } // 无子节点的情况 if (temp == null) { temp = root; root = null; } else { // 一个子节点的情况 root = temp; } } else { // 节点有两个子节点,找到右子树中最小的节点 Node temp = minValueNode(root.right); // 将右子树中最小节点的值赋给要删除的节点 root.value = temp.value; // 删除右子树中最小的节点 root.right = deleteNode(root.right, temp.value); } } // 更新节点的高度 root.height = 1 + Math.max(getHeight(root.left), getHeight(root.right)); // 平衡操作 int balance = getBalance(root); // 左左情况,进行右旋操作 if (balance > 1 && getBalance(root.left) >= 0) { return rightRotate(root); } // 左右情况,先左旋再右旋 if (balance > 1 && getBalance(root.left) < 0) { root.left = leftRotate(root.left); return rightRotate(root); } // 右右情况,进行左旋操作 if (balance < -1 && getBalance(root.right) <= 0) { return leftRotate(root); } // 右左情况,先右旋再左旋 if (balance < -1 && getBalance(root.right) > 0) { root.right = rightRotate(root.right); return leftRotate(root); } return root; } // 获取节点的高度 private int getHeight(Node node) { if (node == null) { return 0; } return node.height; } // 获取节点的平衡因子 private int getBalance(Node node) { if (node == null) { return 0; } return getHeight(node.left) - getHeight(node.right); } // 右旋操作 private Node rightRotate(Node y) { Node x = y.left; Node T2 = x.right; x.right = y; y.left = T2; y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1; x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1; return x; } // 左旋操作 private Node leftRotate(Node x) { Node y = x.right; Node T2 = y.left; y.left = x; x.right = T2; x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1; y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1; return y; } // 获取最小值节点 private Node minValueNode(Node node) { Node current = node; while (current.left != null) { current = current.left; } return current; } } ``` 以上是一个简单的平衡二叉树Java实现,包括插入节点、删除节点、旋转操作等方法。你可以根据需要进行调整和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值