红黑树代码实现

代码框架

import java.util.Comparator;

public class RBTree<E> extends BinarySearchTree<E>{
	private static final boolean RED = false;
	private static final boolean BLACK = true;
	
	public RBTree() {
		this(null);
	}
	public RBTree(Comparator<E> comparator) {
		super(comparator);
	}
	
	/**
	 * 红黑树的节点类
	 * 节点有颜色,RED 或者 BLACK
	 *默认新添加为红色
	 */
	private static class RBNode<E> extends Node<E> {
		boolean color = RED;
		public RBNode(E element, Node<E> parent) {
			super(element, parent);
		}
		
		@Override
		public String toString() {
			String str = "";
			if (color == RED) {
				str = "R_";
			}
			return str + element.toString();
		}
	}
	
	@Override
	protected void afterAdd(Node<E> node) {
		
	}
	
	@Override
	protected void afterRemove(Node<E> node) {
		
	}

}

添加(12种情况)

在这里插入图片描述
添加的所有情况

17左右,33左右,46左,50左右,72左右,76右,88左右,一共12种
在这里插入图片描述在黑节点后+节点,满足红黑树的性质;而在红色叶子节点后+节点,不满足红黑树性质
以下是修复的方法

修复性质4(添加在父节点为红色的情况)

LL(RR)两种

在祖父节点的右孩子的右边添加或在祖父节点的左孩子的左边添加。
若新添加的元素的叔父节点不是红色的情况
在这里插入图片描述

LR(RL)两种

在这里插入图片描述

上溢(四种)Uncle是红色

粉红色为新增加的节点
(LL)
在这里插入图片描述
(RR)
在这里插入图片描述
(LR)
在这里插入图片描述
(RL)
在这里插入图片描述

添加代码

@Override
protected void afterAdd(Node<E> node) {
	Node<E> parent = node.parent;
	
	// 添加的是根节点 或者 上溢到达了根节点
	if (parent == null) {
		black(node);//把根节点变黑
		return;
	}
	
	// 如果父节点是黑色,直接返回
	if (isBlack(parent)) return;
	
	// 叔父节点
	Node<E> uncle = parent.sibling();
	// 祖父节点
	Node<E> grand = red(parent.parent);
	
	if (isRed(uncle)) { // 叔父节点是红色【B树节点上溢】
		black(parent);
		black(uncle);
		// 把祖父节点当做是新添加的节点
		afterAdd(red(grand));
		return;
	}
	
	// 叔父节点不是红色
	if (parent.isLeftChild()) { // L
		if (node.isLeftChild()) { // LL
			black(parent);
			red(grand);
			rotateRight(grand);
		} else { // LR
			black(node);
			red(grand);
			rotateLeft(parent);
			rotateRight(grand);
		}
		rotateRight(grand);
	} else { // R
		if (node.isLeftChild()) { // RL
			black(node);
			red(grand);
			rotateRight(parent);
			rotateLeft(grand);
		} else { // RR
			black(parent);
			red(grand);
			rotateLeft(grand);
		}
	}
}

删除

在这里插入图片描述

删除——red节点

在这里插入图片描述

删除——black节点(3情况)

在这里插入图片描述

删除——拥有一个red节点的black节点

应该通过节点颜色判断,而不是用二叉搜索树里度为几的概念来判断
在这里插入图片描述
在这里插入图片描述

删除——black叶子节点,sibling为black(方法是借兄弟)

B树要求父节点的元素个数比它子节点的个数少1,如图,要删除88,就会出现下溢的情况
76是88的兄弟
在这里插入图片描述
第三个选择了LL,只旋转一次,如果LR的需要旋转两次
在这里插入图片描述

删除——black叶子节点,sibling为black(兄弟借不了,父节点下来合并)

如果删除节点的父节点为红,那么她边上定有合并的黑色节点,它下来合并,原来的节点就不会发生下溢。
如果删除节点的父节点为黑,下来的话上面就会发生下溢
不肯能存在父节点为黑,她边上定有合并的红色节点,因为条件就是被删除元素的兄弟节点为黑
在这里插入图片描述

删除——black叶子节点,sibling为red(借兄弟的孩子)

将兄弟孩子变成兄弟,这样就可以套用上面的方法(当兄弟是黑色节点时就借兄弟)
让80右旋转
在这里插入图片描述

删除代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值