失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 红黑树java源代码分析_JAVA 红黑树源码

红黑树java源代码分析_JAVA 红黑树源码

时间:2023-01-03 08:48:59

相关推荐

红黑树java源代码分析_JAVA 红黑树源码

class RBTree>{

private static final String RedColor = "red";

private static final String BlackColor = "black";

//定义一个根结点

RBNode root;

//定义结点数量

private int size = 0;

//返回总结点数量

public int getSize(){

return this.size;

}

//根据key查找对应的结点

public RBNode findData(int key){

RBNode p;

p = root;

while(p != null){

if (key > p.getKey()){

p = p.getRight();

}

else if (key < p.getKey()){

p = p.getLeft();

}

else{

return p;

}

}

return null;

}

//查询每个结点的颜色

public void findColor(RBNode node){

if (node != null) {

System.out.println("for test ==>> " + " key => " + node.getKey() + ", color => " + node.getColor() + ", data => " + node.getData() + ", left => " + node.getLeft() + ", right => " + node.getRight() + ", parent => " + node.getParent());

findColor(node.getLeft());

findColor(node.getRight());

}

}

//返回根结点

public RBNode findRoot(){

return root;

}

//查找后继结点

public RBNode findAfterNode(RBNode node){

if (node.getRight() != null) {

RBNode trbNode = node.getRight();

while (trbNode.getLeft() != null) {

trbNode = trbNode.getLeft();

}

return trbNode;

}

return null;

}

//查找前驱结点

public RBNode findBeforeNode(RBNode node){

if (node.getLeft() != null) {

RBNode trbNode = node.getLeft();

while (trbNode.getRight() != null) {

trbNode = trbNode.getRight();

}

return trbNode;

}

return null;

}

//插入数据

public T putData(int key, T data){

size ++;

RBNode node;

node = root;

//如果根结点为空,则直接新建一个结点为根结点

if (node == null){

node = new RBNode(key, data, BlackColor, null, null, null);

root = node;

return node.getData();

}

else{

RBNode p = node;

//查找插入新结点的位置

while(node != null) {

p = node;

if (key < node.getKey()) {

node = node.getLeft();

}

else if (key > node.getKey()){

node = node.getRight();

}

else{

//插入结点的key已存在,原有的红黑树已经是平衡的,则直接更新结点的data

node.setData(data);

return node.getData();

}

}

//插入新结点,新插入的结点为红色

RBNode e = new RBNode(key, data, RedColor, null, null, p);

if (key > p.getKey()){

p.setRight(e);

e.setParent(p);

}

else{

p.setLeft(e);

e.setParent(p);

}

if (p.getParent() == null){

//插入新结点时只有根结点

return e.getData();

}

else{

/**

* 插入新结点的父结点为黑结点,由于插入的结点是红色的;

* 当新插入结点的父结点为黑结点时,直接插入即可,并不会影响红黑树的平衡,无需做自平衡;

*/

if (e.getParent().getColor().equals(BlackColor)){

return e.getData();

}

/**

* 插入新结点的父结点为红结点,由于插入的结点也是红结点

* 如果插入的父结点为红结点,那么该父结点不可能为根结点,所以插入结点总是存在祖父结点

*/

else {

/**

* 插入的新结点的父结点为红结点

* 并且叔叔结点存在并且为红结点(叔叔结点是插入新结点的父结点的兄弟结点)

*/

//当前结点的祖父结点的父结点

RBNode ttPParent = null;

//当前结点的父结点的兄弟结点

RBNode tPBrother = null;

//当前结点

RBNode t = e;

//当前结点的父结点

RBNode tParent = t.getParent();

//当前结点的祖父结点

RBNode tPParent = t.getParent().getParent();

if (tPParent != root){

// 保存当前结点祖父结点的父结点

ttPParent = tPParent.getParent();

}

while (t != null) {

// 新增结点的父结点不为空

if (tParent != null){

//判断新增结点的父结点的颜色,若为黑色直接退出

if(tParent.getColor().equals(BlackColor)){

break;

}

if (tPParent != null) {

if (tPParent != root){

// 保存当前结点祖父结点的父结点

ttPParent = tPParent.getParent();

}

else{

ttPParent = null;

}

if (tParent == tPParent.getLeft()) {

//当前结点的父结点的兄弟结点

tPBrother = tPParent.getRight();

}

else if(tParent == tPParent.getRight()){

//当前结点的父结点的兄弟结点

tPBrother = tPParent.getLeft();

}

else{

tPBrother = null;

}

if (tPBrother != null) {

//若当前结点的父结点和父结点的兄弟结点都为红色,则替换颜色

if ((tParent.getColor().equals(RedColor)) && (tPBrother.getColor().equals(RedColor))) {

/**

* 将当前结点的父结点置为黑色;

* 将父结点的兄弟结点置为黑色;

* 将祖父结点置为红色

*/

tParent.setColor(BlackColor);

tPBrother.setColor(BlackColor);

tPParent.setColor(RedColor);

}

if ((tParent.getColor().equals(RedColor)) && (tPBrother.getColor().equals(BlackColor))) {

/**

* 若当前结点的父结点为红色,父结点的兄弟结点为黑色

* 则以当前结点的祖父结点为旋转点,旋转二叉树

*/

if (tParent == tPParent.getLeft()) {

LeftRotationBalance(t, tParent, tPParent, ttPParent);

break;

}

else {

RightRotationBalance(t, tParent, tPParent, ttPParent);

break;

}

}

}

else{

if (tParent.getColor().equals(RedColor)) {

/**

* 若当前结点的父结点为红色,父结点的兄弟结点为空

* 则以当前结点的祖父结点为旋转点,旋转二叉树

*/

if (tParent == tPParent.getLeft()) {

LeftRotationBalance(t, tParent, tPParent, ttPParent);

break;

}

else {

RightRotationBalance(t, tParent, tPParent, ttPParent);

break;

}

}

}

t = tPParent;

if (t.getParent() != null){

tParent = t.getParent()

if (t.getParent().getParent() != null){

tPParent = t.getParent().getParent();

}

else{

tPParent = null;

}

}

else{

tParent = null;

tPParent = null;

}

}

else{

t = tParent;

tParent = null;

tPParent = null;

ttPParent = null;

}

}

else{

//若 t 为根结点,将根结点颜色置为黑色

if (t == root) {

t.setColor(BlackColor);

}

break;

}

}

return e.getData();

}

}

}

}

//删除数据

public boolean delData(int key){

size --;

RBNode delNode = findData(key);

if (delNode != null){

int flag = 0; //后继结点

RBNode node = null;

RBNode replaceNode = null;

//删除结点为红色结点,则直接使用 前驱 或 后继 结点替换删除结点

replaceNode = findAfterNode(delNode);

//后继结点,若后继结点查询不到则查找前驱结点

if (replaceNode == null){

flag = 1; //前驱结点

replaceNode = findBeforeNode(delNode);

}

/**

* delNode 删除结点

* replaceNode 替换结点

* delBrother 替换结点的兄弟结点

* delParent 替换结点的父结点

* delPParent 替换结点的祖父结点

* delBrotherLeft 替换结点的兄弟结点的左子结点

* delBrotherRight 替换结点的兄弟结点的右子结点

*/

while (replaceNode != null){

node = null;

//后继结点,循环查找到整颗二叉树的最后后继结点

if(flag == 0){

if (replaceNode.getRight() != null) {

//查找替换结点的后继结点

node = findAfterNode(replaceNode.getRight());

if (node != null) {

delNode.setKey(replaceNode.getKey());

delNode.setData(replaceNode.getData());

delNode = replaceNode;

replaceNode = node;

continue;

}

else{

break;

}

}

else{

break;

}

}

//前驱结点,循环查找到整颗二叉树的最后前驱结点

if (flag == 1){

if (replaceNode.getLeft() != null) {

//查找替换结点的右子结点的 前驱 或 后继 结点

node = findBeforeNode(replaceNode.getLeft());

if (node != null) {

delNode.setKey(replaceNode.getKey());

delNode.setData(replaceNode.getData());

delNode = replaceNode;

replaceNode = node;

continue;

}

else{

break;

}

}

else{

break;

}

}

}

//前驱结点、后继结点都为空,则删除结点跟替换结点相同

if (replaceNode == null){

replaceNode = delNode;

}

else{

//将替换结点的数据赋给删除结点

delNode.setData(replaceNode.getData());

delNode.setKey(replaceNode.getKey());

}

/**

* 当替换结点的颜色为红色,则直接删除替换结点,不影响平衡

* 当替换结点的颜色为红色,替换结点肯定是叶子结点,根结点不可能为红色

* 也不存在红红结点、红黑结点

* 如果替换结点有两个子结点,那肯定不是最终的后继结点或前驱结点,代码走不到这里

* 此种情况下,直接删除替换结点就好,不影响平衡

*/

if (replaceNode.getColor().equals(BlackColor)){

if (replaceNode == replaceNode.getParent().getLeft()){

if (replaceNode.getRight() != null) {

/**

* 替换结点有右子结点时:

* 若替换结点为黑色,替换结点的右子结点不可能为黑色

* 直接将替换结点的右子结点设置为替换结点,将结点置黑,并将替换结点删除即可

*/

replaceNode.getRight().setColor(replaceNode.getColor());

replaceNode.getRight().setParent(replaceNode.getParent());

replaceNode.getParent().setLeft(replaceNode.getRight());

return true;

}

}

if (replaceNode == replaceNode.getParent().getRight()){

if (replaceNode.getLeft() != null){

/**

* 替换结点有右子结点时:

* 若替换结点为黑色,替换结点的右子结点不可能为黑色

* 直接将替换结点的右子结点设置为替换结点,将结点置黑,并将替换结点删除即可

*/

replaceNode.getLeft().setColor(replaceNode.getColor());

replaceNode.getLeft().setParent(replaceNode.getParent());

replaceNode.getParent().setRight(replaceNode.getLeft());

return true;

}

}

if (replaceNode == root){

root = null;

return true;

}

else {

//替换结点没有子结点,且为黑色

boolean rbNode = delBrotherBlack(replaceNode);

if (rbNode == true){

//删除后继结点

if (replaceNode == replaceNode.getParent().getLeft()){

replaceNode.getParent().setLeft(null);

}

if (replaceNode == replaceNode.getParent().getRight()){

replaceNode.getParent().setRight(null);

}

replaceNode.setLeft(null);

replaceNode.setRight(null);

replaceNode.setParent(null);

return true;

}

}

}

}

return false;

}

//替换结点是黑色时逻辑处理

public boolean delBrotherBlack(RBNode delNode){

/**

* 若替换结点的颜色为黑色,则分以下情况:

* 1:替换结点是其父结点的左子结点:

* 1.1:替换结点的兄弟结点是红结点;

* 1.2:替换结点的兄弟结点是黑结点;

* 1.2.1:替换结点的兄弟结点的右子结点是红结点,左子结点任意颜色;

* 1.2.2:替换结点的兄弟结点的右子结点是黑结点,左子结点是红结点;

* 1.2.3:父亲结点为红色,替换结点与兄弟结点都为黑色,兄弟结点的子结点都为黑结点;

* 1.2.4:父亲结点为黑色,替换结点与兄弟结点都为黑色,兄弟结点的子结点都为黑结点;

*====================================================================

* 2:替换结点时其父结点的右子结点;

* 2.1:替换结点的兄弟结点时红结点;

* 2.2:替换结点的兄弟结点时黑结点;

* 2.2.1:替换结点的兄弟结点的左子结点是红结点,右子结点任意颜色;

* 2.2.2:替换结点的兄弟结点的左子结点是黑结点,右子结点为红结点;

* 2.2.3:父亲结点为红色,替换结点与兄弟结点都为黑色,兄弟结点的子结点都为黑结点;

* 2.2.4:父亲结点为黑色,替换结点与兄弟结点都为黑色,兄弟结点的子结点都为黑结点;

*/

RBNode delBrotherLeft = null;

RBNode delBrotherRight = null;

RBNode delParent = null;

RBNode delBrother = null;

RBNode delPParent = null;

if (delNode.getParent() != null){

delParent = delNode.getParent();

if (delParent.getParent() != null){

delPParent = delParent.getParent();

}

}

//1. 替换结点是其父结点的左子结点

if (delNode == delParent.getLeft()) {

if (delParent.getRight() != null) {

delBrother = delParent.getRight(); //保存替换结点的兄弟结点

if (delBrother.getLeft() != null){

delBrotherLeft = delBrother.getLeft();

}

if (delBrother.getRight() != null){

delBrotherRight = delBrother.getRight();

}

}

// 1.1 替换结点的兄弟结点是红结点

if (delBrother.getColor().equals(RedColor)){

delBrother.setColor(BlackColor);

delParent.setColor(RedColor);

delLeftRotation(delNode, delParent, delBrother, delPParent);

boolean rbNode1 = delBrotherBlack(delNode);

if (rbNode1 == true){

return true;

}

}

// 1.2 替换结点的兄弟结点是黑结点

else{

//1.2.1:替换结点的兄弟结点的右子结点是红结点,左子结点任意颜色;

if (delBrotherRight.getColor().equals(RedColor)){

delBrother.setColor(delParent.getColor());

delParent.setColor(BlackColor);

delBrotherRight.setColor(BlackColor);

delLeftRotation(delNode, delParent, delBrother, delPParent);

return true;

}

//1.2.2:替换结点的兄弟结点的右子结点是黑结点,左子结点为红结点;

if (delBrotherRight.getColor().equals(BlackColor)){

if (delBrotherLeft.getColor().equals(RedColor)){

//先将兄弟结点的左子结点右旋

delBrotherLeft.setParent(delParent);

delParent.setRight(delBrotherLeft);

delBrother.setParent(delBrotherLeft);

delBrotherLeft.setRight(delBrother);

delBrother.setLeft(null);

//交换兄弟结点与兄弟左子结点的颜色

delBrother.setColor(RedColor);

delBrotherLeft.setColor(BlackColor);

boolean rbNode2 = delBrotherBlack(delNode);

if (rbNode2 == true){

return true;

}

}

}

//1.2.3:父亲结点为红色,替换结点与兄弟结点都为黑色,兄弟结点的子结点都为黑结点;

if (delParent.getColor().equals(RedColor)) {

if ((delBrotherLeft.getColor().equals(BlackColor)) && (delBrotherRight.getColor().equals(BlackColor))) {

delParent.setColor(BlackColor);

delBrother.setColor(RedColor);

return true;

}

}

//1.2.4:父亲结点为黑色,替换结点与兄弟结点都为黑色,兄弟结点的子结点都为黑结点;

if (delParent.getColor().equals(BlackColor)){

if ((delBrotherLeft.getColor().equals(BlackColor)) && (delBrotherRight.getColor().equals(BlackColor))) {

delBrother.setColor(RedColor);

delNode = delParent;

if (delNode == null){

return false;

}

boolean rbNode3 = delBrotherBlack(delNode);

if (rbNode3 == true){

return true;

}

}

}

}

}

//替换结点是其父结点的右子结点

else{

if (delParent.getLeft() != null) {

delBrother = delParent.getLeft(); //保存替换结点的兄弟结点

if (delBrother.getLeft() != null) {

delBrotherLeft = delBrother.getLeft();

}

if (delBrother.getRight() != null) {

delBrotherRight = delBrother.getRight();

}

}

// 2.1 替换结点的兄弟结点是红结点

if (delBrother.getColor().equals(RedColor)){

delBrother.setColor(BlackColor);

delParent.setColor(RedColor);

delRightRotation(delNode, delParent, delBrother, delPParent);

boolean rbNode1 = delBrotherBlack(delNode);

if (rbNode1 == true){

return true;

}

}

// 2.2 替换结点的兄弟结点是黑结点

else{

//2.2.1:替换结点的兄弟结点的左子结点是红结点,右子结点任意颜色;

if (delBrotherLeft.getColor().equals(RedColor)){

delBrother.setColor(delParent.getColor());

delParent.setColor(BlackColor);

delBrotherLeft.setColor(BlackColor);

delRightRotation(delNode, delParent, delBrother, delPParent);

return true;

}

//2.2.2:替换结点的兄弟结点的左子结点是黑结点,右子结点为红结点;

if (delBrotherLeft.getColor().equals(BlackColor)){

if (delBrotherRight.getColor().equals(RedColor)){

//先将兄弟结点的右子结点左旋

delBrotherRight.setParent(delParent);

delParent.setLeft(delBrotherRight);

delBrother.setParent(delBrotherRight);

delBrotherRight.setLeft(delBrother);

delBrother.setRight(null);

//交换兄弟结点与兄弟左子结点的颜色

delBrother.setColor(RedColor);

delBrotherRight.setColor(BlackColor);

boolean rbNode2 = delBrotherBlack(delNode);

if (rbNode2 == true){

return true;

}

}

}

//2.2.3:父亲结点为红色,替换结点与兄弟结点都为黑色,兄弟结点的子结点都为黑结点;

if (delParent.getColor().equals(RedColor)) {

if ((delBrotherRight.getColor().equals(BlackColor)) && (delBrotherLeft.getColor().equals(BlackColor))) {

delParent.setColor(BlackColor);

delBrother.setColor(RedColor);

return true;

}

}

//1.2.4:父亲结点为黑色,替换结点与兄弟结点都为黑色,兄弟结点的子结点都为黑结点;

if (delParent.getColor().equals(BlackColor)){

if ((delBrotherLeft.getColor().equals(BlackColor)) && (delBrotherRight.getColor().equals(BlackColor))) {

delBrother.setColor(RedColor);

delNode = delParent;

if (delNode == null){

return false;

}

boolean rbNode3 = delBrotherBlack(delNode);

if (rbNode3 == true){

return true;

}

}

}

}

}

return false;

}

//删除结点左旋

public void delLeftRotation(RBNode delNode, RBNode delParent, RBNode delBrother, RBNode delPParent){

if (delBrother.getLeft() != null){

delBrother.getLeft().setParent(delParent);

delParent.setRight(delBrother.getLeft());

}

else{

delParent.setRight(null);

}

delParent.setParent(delBrother);

delPParent.setRight(delBrother);

delBrother.setParent(delPParent);

delBrother.setLeft(delParent);

}

//删除结点右旋

public void delRightRotation(RBNode delNode, RBNode delParent, RBNode delBrother, RBNode delPParent){

if (delBrother.getRight() != null){

delBrother.getRight().setParent(delParent);

delParent.setLeft(delBrother.getRight());

}

else{

delParent.setLeft(null);

}

delParent.setParent(delBrother);

delPParent.setLeft(delBrother);

delBrother.setParent(delPParent);

delBrother.setRight(delParent);

}

//插入结点右旋

public void LeftRotationBalance(RBNode t, RBNode tParent, RBNode tPParent, RBNode ttPParent){

//若新增结点为父结点的右子结点时

if (t == tParent.getRight()){

//先将新增结点的父结点左旋

if (t.getLeft() != null){

t.setParent(tParent);

tParent.setRight(t.getLeft());

}

else{

tParent.setRight(null);

}

t.setParent(tPParent);

tPParent.setLeft(t);

tParent.setParent(t);

tParent.setRight(null);

t.setLeft(tParent);

tParent = t;

}

//将新增结点的父结点的颜色置为黑色

if (tParent.getColor().equals(RedColor)){

tParent.setColor(BlackColor);

}

//将新增结点的祖父结点颜色置为红色

if (tPParent.getColor().equals(BlackColor)){

tPParent.setColor(RedColor);

}

//以新增结点的父结点为旋转点,右旋结点

if (tParent.getRight() != null){

tParent.getRight().setParent(tPParent);

tPParent.setLeft(tParent.getRight());

}

else{

tPParent.setLeft(null);

}

tParent.setRight(tPParent);

tPParent.setParent(tParent);

tParent.setParent(ttPParent);

if (tPParent == root){

root = tParent;

}

else{

if (tPParent == ttPParent.getLeft()){

ttPParent.setLeft(tParent);

}

if (tPParent == ttPParent.getRight()){

ttPParent.setRight(tParent);

}

}

}

//插入结点左旋

public void RightRotationBalance(RBNode t, RBNode tParent, RBNode tPParent, RBNode ttPParent){

if (t == tParent.getLeft()){

//先将新增结点的父结点右旋

if (t.getRight() != null){

t.getRight().setParent(tParent);

tParent.setLeft(t.getRight());

}

else{

tParent.setLeft(null);

}

t.setParent(tPParent);

tPParent.setRight(t);

t.setRight(tParent);

tParent.setParent(t);

tParent.setLeft(null);

tParent = t;

}

//将新增结点的父结点的颜色置为黑色

if (tParent.getColor().equals(RedColor)){

tParent.setColor(BlackColor);

}

//将新增结点的祖父结点的颜色置为红色

if (tPParent.getColor().equals(BlackColor)){

tPParent.setColor(RedColor);

}

//以新增结点的父结点为旋转点,左旋结点

if (tParent.getLeft() != null){

tParent.getLeft().setParent(tPParent);

tPParent.setRight(tParent.getLeft());

}

else{

tPParent.setRight(null);

}

tParent.setLeft(tPParent);

tPParent.setParent(tParent);

tParent.setParent(ttPParent);

if (tPParent == root){

root = tParent;

}

else{

if (tPParent == ttPParent.getLeft()){

ttPParent.setLeft(tParent);

}

if (tPParent == ttPParent.getRight()){

ttPParent.setRight(tParent);

}

}

}

}

//定义一个红黑树结点

class RBNode>{

//结点key

private int key;

//结点数据

private T data;

//结点颜色

private String color;

//结点左指针

private RBNode left;

//结点右指针

private RBNode right;

//结点父结点

private RBNode parent;

public RBNode(int key, T data, String color, RBNode left, RBNode right, RBNode parent){

this.key = key;

this.data = data;

this.color = color;

this.left = left;

this.right = right;

this.parent = parent;

}

public T getData(){

return this.data;

}

public int getKey(){

return this.key;

}

public String getColor(){

return this.color;

}

public RBNode getLeft(){

return this.left;

}

public RBNode getRight(){

return this.right;

}

public RBNode getParent(){

return this.parent;

}

public void setData(T data){

this.data = data;

}

public void setLeft(RBNode left){

this.left = left;

}

public void setRight(RBNode right){

this.right = right;

}

public void setParent(RBNode parent){

this.parent = parent;

}

public void setColor(String color){

this.color = color;

}

public void setKey(int key){

this.key = key;

}

}

如果觉得《红黑树java源代码分析_JAVA 红黑树源码》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。