package com.song.rbtree;
public class RBTree<K extends Comparable<K>,V> {
private static final boolean RED=true;
private static final boolean BLACK = false;
/**树根的引用*/
private RBNode root;
static class RBNode<K extends Comparable<K>,V>{
private RBNode parent;
private RBNode left;
private RBNode right;
private boolean color;
private K key;
private V value;
public RBNode(RBNode parent, RBNode left, RBNode right, boolean color, K key, V value) {
this.parent = parent;
this.left = left;
this.right = right;
this.color = color;
this.key = key;
this.value = value;
}
public RBNode() {
}
public RBNode getParent() {
return parent;
}
public void setParent(RBNode parent) {
this.parent = parent;
}
public RBNode getLeft() {
return left;
}
public void setLeft(RBNode left) {
this.left = left;
}
public RBNode getRight() {
return right;
}
public void setRight(RBNode right) {
this.right = right;
}
public boolean isColor() {
return color;
}
public void setColor(boolean color) {
this.color = color;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
/**
* 节点是否为红色
* @param node
*/
private boolean isRed(RBNode node){
if (node!=null){
return node.color==RED;
}
return false;
}
/**
*获取当前节点的父节点
* @param node
*/
private RBNode parentOf(RBNode node){
if(node!=null){
return node.parent;
}
return null;
}
/**
* 节点是否为黑色
* @param node
*/
private boolean isBlack(RBNode node){
if (node!=null){
return node.color==BLACK;
}
return false;
}
/**
* 设置节点颜色为红色
* @param node
*/
private void setRed(RBNode node){
if (node!=null){
node.color=RED;
}
}
/**
* 设置节点颜色为黑色
* @param node
*/
private void setBlack(RBNode node){
if (node!=null){
node.color=BLACK;
}
}
/**
* 中序打印红黑树
*/
public void inOrderPrint(){
inOrderPrint(this.root);
System.out.println();
}
private void inOrderPrint(RBNode node){
if (node!=null){
inOrderPrint(node.left);
System.out.print(" "+node.key);
inOrderPrint(node.right);
}
}
/**
* 左旋方法
* 1 将y的左节点的父节点变为x 并将x的右节点指向y的左子节点
* 2 将x的父节点(不为空) 更新为y的父节点 将 x的父节点的子树节点指定为y
* 3 将x的父节点更新为y y的左子节点指向x
*/
private void leftRotate(RBNode x){
RBNode y=x.right;
x.right=y.left;
if (y.left!=null){
y.left.parent=x;
}
if (x.parent!=null){
y.parent=x.parent;
if (x.parent.left==x){
x.parent.left=y;
}else {
x.parent.right=y;
}
}else {
this.root=y;
this.root.parent=null;
}
x.parent=y;
y.left=x;
}
/**
* 右旋方法
* 1 将x的右节点的父节点更新为y 将y的左节点指向x的右节点
* 2 将x父节点更新为y的父节点 更新y的父节点的 子树节点指向x
* 3 将y的父节点更新为x x的右节点指向y
*/
private void rightRotate(RBNode y){
RBNode x=y.left;
y.left=x.right;
if (x.right!=null){
x.right.parent=y;
}
if (y.parent!=null){
x.parent=y.parent;
if (y.parent.left==y){
y.parent.left=x;
}else {
y.parent.right=x;
}
}else {
this.root=x;
this.root.parent=null;
}
y.parent=x;
x.right=y;
}
/**
* 插入数据额
* @param key
* @param value
*/
public void insert(K key,V value){
RBNode<K, V> node = new RBNode<K, V>();
node.setKey(key);
node.setValue(value);
node.setColor(RED);
insert(node);
}
private void insert(RBNode node){
RBNode parent=null;
RBNode x=this.root;
while (x!=null){
parent=x;
int cmp = node.key.compareTo(x.key);
if (cmp>0){
x=x.right;
}else if (cmp==0){
x.setValue(node.getValue());
return;
}else {
x=x.left;
}
}
node.parent=parent;
if (parent!=null){
int cmp = node.key.compareTo(parent.key);
if (cmp>0){
parent.right=node;
}else {
parent.left=node;
}
}else {
this.root=node;
}
//修复红黑树平衡的方法
insertFixup(node);
}
/**
* 1 插入节点的父节点为黑色
* 2 插入加点key已存在
* 3 空树
* 以上三点不需要变化
* 插入节点的父节点为红色
* 叔叔节点为红色 父亲 叔叔节点变黑色 爷爷加点为红色 然后爷爷节点为当前节点
* 叔叔节点为黑色 或nil
* LL时 父节点变黑色 爷爷节点变红色 爷爷节点右旋
* LR时 父亲节点左旋 变为LL处理
* RR时 父亲节点变黑色 爷爷节点变红色 爷爷节点左旋
* RL时 父亲节点右旋 变为RR处理
*
*/
private void insertFixup(RBNode node) {
this.root.setColor(BLACK);
RBNode parent = parentOf(node);
RBNode gparent = parentOf(parent);
if (parent != null && isRed(parent)) {
//父节点为红色 一定存在爷爷节点
RBNode uncle = null;
if (parent == gparent.left) {
uncle = gparent.right;
if (uncle != null && isRed(uncle)) {
parent.setColor(BLACK);
uncle.setColor(BLACK);
gparent.setColor(RED);
insertFixup(gparent);
return;
}
//叔叔节点不存在或者为黑色
if (uncle == null || isBlack(uncle)) {
if (node == parent.left) {
parent.setColor(BLACK);
gparent.setColor(RED);
rightRotate(gparent);
return;
} else {
leftRotate(parent);
insertFixup(parent);
return;
}
}
} else {
uncle = gparent.left;
if (uncle != null && isRed(uncle)) {
parent.setColor(BLACK);
uncle.setColor(BLACK);
gparent.setColor(RED);
insertFixup(gparent);
return;
}
if (uncle == null || isBlack(uncle)) {
if (node == parent.right) {
parent.setColor(BLACK);
gparent.setColor(RED);
leftRotate(gparent);
return;
} else {
rightRotate(parent);
insertFixup(parent);
return;
}
}
}
}
}
}
每日学习:红黑树java实现
最新推荐文章于 2021-05-17 15:20:58 发布
本文介绍了一个红黑树的Java实现,包括插入操作及其平衡调整过程。通过左旋、右旋等方法确保树的性质得以维持。
1045

被折叠的 条评论
为什么被折叠?



