package com.lqz.tree;
/**
* 红黑树-Java实现
*/
public class RedBlackTree<Key extends Comparable<Key>, Value> {
//根节点
private Node root;
//记录树中元素的个数
private int N;
//红色链接
private static final boolean Red = true;
//黑色链接
private static final boolean Black = false;
//结点类
private class Node{
//存储键
public Key key;
//存储值
public Value value;
//记录左子节点
public Node left;
//记录右子节点
private Node right;
//由其父节点指向其键的颜色
public boolean color;
//构造方法
public Node(Key key, Value value, RedBlackTree<Key, Value>.Node left, RedBlackTree<Key, Value>.Node right,
boolean color) {
super();
this.key = key;
this.value = value;
this.left = left;
this.right = right;
this.color = color;
}
}
/**
* 获取树中元素的个数
* @return 树中元素的个数
*/
public int size() {
return N;
}
/**
* 判断当前的节点的父节点的指向是否为红色
*/
private boolean isRed(Node x) {
if(x==null) {
return false;
}
return x.color==Red;
}
/**
* 左旋
* @param x
* @return
*/
private Node rotateLeft(Node h) {
//获取h节点的右子节点为x节点
Node x = h.right;
//让x节点的左子节点作为h节点的右子节点
h.right = x.left;
//让h成为x节点的左子节点
x.left = h;
//让x节点的color属性等于h节点的color属性
x.color = h.color;
//让h节点的color属性变成红色
h.color = Red;
return x;
}
/**
* 右旋
* @param x
* @return
*/
private Node rotateRight(Node h) {
//获取h节点的左子节点为x节点
Node x = h.left;
//让x节点的右子节点作为h节点的左子节点
h.left = x.right;
//让h成为x节点的右子节点
x.right = h;
//让x节点的color属性等于h节点的color属性
x.color = h.color;
//让h节点的color属性变成红色
h.color = Red;
return x;
}
/**
* 颜色反转
* @param h
* @return
*/
private Node flipColor(Node h) {
//让当前节点变为红色
h.color = Red;
//让当前节点的左子节点和右子节点变为黑色
h.left.color = Black;
h.right.color = Red;
return null;
}
/**
* 在整个树上完成插入操作
* @param key
* @param value
*/
public void put(Key key,Value value) {
root = put(root, key, value);
//根节点的颜色总是黑色
root.color = Black;
//判断h是否为空,如果为空的话直接返回一个红色的节点
}
/**
* 在指定的节点上完成插入操作
* @param h
* @param key
* @param value
* @return
*/
public Node put(Node h,Key key,Value value) {
//判断插入的h节点是否为空,如果为空的话直接返回一个红色节点
if(h==null) {
N++;
return new Node(key, value, null, null, Red);
}
//如果不为空,比较h节点的键与key的大小
int cmp = key.compareTo(h.key);
if(cmp<0) {
//继续往左
h.left = put(h.left, key, value);
}else if(cmp>0) {
//继续往右
h.right = put(h.right, key, value);
}else {
//发生值得替换
h.value = value;
}
//进行左旋 当当前节点的的左子节点为黑色,右子节点为红色需要左旋
if(isRed(h.right)&&!isRed(h.left)) {
h = rotateLeft(h);
}
//进行右旋转 当h的左子节点为红色并且左子节点的左子节点为红色
if(isRed(h.left)&&isRed(h.left.left)) {
h = rotateRight(h);
}
//进行颜色反转 当h节点的左子节点和右子节点都为红色
if(isRed(h.left)&&isRed(h.right)) {
flipColor(h);
}
return h;
}
//根据key在树中找出对应的值
public Value get(Key key) {
return get(root, key);
}
public Value get(Node x,Key key) {
if(x==null) {
return null;
}
//比较x的键与key的大小
int cmp = key.compareTo(x.key);
if(cmp<0) {
return get(x.left, key);
}else if(cmp>0) {
return get(x.right, key);
}else {
return x.value;
}
}
}
红黑树代码-Java实现
最新推荐文章于 2023-03-16 14:43:03 发布