用Java实现红黑树的完整代码

红黑树的四大性质:

1:红黑树节点的颜色非红即黑

2:红色节点的两个子节点必须是黑色

3:叶子都为黑色(这里的叶子节点是指NULL节点)

4:每个节点到叶子节点的所有路径包含的黑色节点个数要相同


插入时需要重新进行红黑树平衡的三种情况(其它比较简单的直接插入情况就不讲了,有不懂的直接@我),假设父节点是左孩子,叔父节点是右孩子,反之为对称情况好理解

1:父亲节点是红色,叔父节点也是红色

需要转化为:父节点涂黑,叔父节点也涂黑,祖父节点涂红,把祖父节点赋值为当前节点,然后变为下面2,3情况一种


2:当前节点为父节点的右孩子,叔父节点为黑色

需要转化为:把父节点左旋,当前节点赋值为父节点,父节点赋值为当前节点,此时变为第3种情况


3:当前节点是父节点的左孩子,叔父节点为黑色

需要转化为:父节点涂黑,祖父节点涂红并右旋,此时红黑树变为平衡状态


删除需要进行的四种情况(其它比较简单直接删除的情况就不讲了),有一点说明下,删除的节点可以由后继节点来填补,后继节点一般是大于被删除节点的最小节点,所以真正需要平衡转化的地方是后继节点那里

假设当前节点()是左孩子,兄弟节点是右孩子,反之为对称情况好理解

1:当前节点为黑色包含空的情况(大多数为空),兄弟节点为红色

需要转化为:兄弟涂黑,父亲涂红并左旋,如果变成2情况,则不会转化3,4情况,重新循环,如果变化为3情况,则会转化为第4种情况,如果变化为4情况,红黑树重新平衡并跳出循环


2:当前节点为黑色包含空的情况(大多数为空),兄弟节点为黑,并且兄弟节点的左孩子和右孩子都为黑

需要转化为:兄弟节点涂红,父节点赋值为当前节点,重新循环


3:当前节点为黑色包含空的情况(大多数为空),兄弟节点为黑,并且兄弟左孩子为红色,右孩子为黑色

需要转化为:兄弟节点涂红,左孩子涂黑,并把兄弟节点右旋  则转化为第4种情况


4:当前节点为黑色包含空的情况(大多数为空),兄弟节点为黑色,并且兄弟右孩子为红色,左孩子为任一颜色

需要转化为:兄弟节点涂成父节点的颜色,父节点涂黑,兄弟右孩子涂黑,并把父节点左旋,红黑树达到平衡状态


已下是完整源码:

import java.util.Scanner;

public class DRBTree<T extends Comparable<T>> {
 
 private RBNode<T> mroot;
 private static final boolean RED = false;
 private static final boolean BLACK = true;
 
 public class RBNode<T extends Comparable<T>>{
  
  private boolean color;
  private T key;
  private RBNode<T> parent;
  private RBNode leftChild;
  private RBNode rightChild;
  
  public RBNode(boolean col,T key,RBNode paret,RBNode leftChild,RBNode rightChild){
   this.color = col;
   this.key = key;
   this.parent = parent;
   this.leftChild = leftChild;
   this.rightChild = rightChild;
  }
  
  public T getKey() {
   return this.key;
  }
 }
 
 public RBNode<T> parentOf(RBNode<T> node){
  if(node!=null) {
   return node.parent;
  }
  
  return null;
 }
 
 public boolean colorOf(RBNode<T> node){
  if(node!=null) {
   return node.color;
  }
  return BLACK;
 }
 
 public void setParent(RBNode<T> node,RBNode<T> parent) {
  if(node!=null) {
   node.parent = parent;
  }
 }
 
 public void setColor(RBNode<T> node,boolean color) {
  if(node!=null) {
   node.color = color;
  }
 }
 
 public boolean isRed(RBNode<T> node) {
  return (node!=null&&node.color == RED)?true:false;
 }
 
 public boolean isBlack(RBNode<T> node) {
  return !isRed(node);
 }
 
 public void setRed(RBNode<T> node) {
   if(node!=null) { 
  node.color = RED;
   } 
 }
 
 public void setBlack(RBNode<T> node) {
  if(node!=null) {
   
   node.color = BLACK;
  }
 }
 
 //寻找为key值的节点
 public RBNode<T> search(T key,RBNode<T> node){
  
   if(node!=null) { 
  int com = key.compareTo(node.key);
  if(com<0) {
   return search(key,node.leftChild);
  }else if(com>0) {
   return search(key,node.rightChild);
  }else {
   return node;
  }
   }
   return null;
  
 }
 
 //寻找后继节点,即大于该节点的最小节点
 public RBNode<T> min(RBNode<T> node){
   if(node.leftChild == null) {
    return node;
   }
  
   while(node.leftChild!=null) {
    node = node.leftChild;
   }
  
   return node;
 }
 
 public RBNode successor(RBNode<T> node) {
  if(node.rightChild !=null) {
     return min(node.rightChild);
  }
  
  RBNode<T> y = node.parent;
  while((y!=null)&&(y.rightChild == node)) {
   node = y;
   y = y.parent;
  }
  return y;
 }

 //对某个节点进行左旋
 public void leftRonate(RBNode<T> x) {
  RBNode<T> y = x.rightChild;
  
  if(y.leftChild!=null) {
   y.leftChild.parent = x;
  }
  
  x.rightChild = y.leftChild;
     y.leftChild = x;
     y.parent = x.parent;
    
    
    
     if(x.parent!=null) {
      if(x.parent.leftChild == x) {
       x.parent.leftChild = y;
      }else {
       x.parent.rightChild = y;
      }
     }else {
      this.mroot = y;
     }
     x.parent = y;
    
 }
 
 //对某个节点进行右旋
 public void rightRonate(RBNode<T> x) {
  RBNode<T> y = x.leftChild;
  
  if(y.rightChild!=null) {
   y.rightChild.parent = x;
  }
  
  y.parent = x.parent;
  x.leftChild = y.rightChild;
  y.rightChild = x;
  
  if(x.parent!=null) {
   if(x.parent.leftChild == x) {
    x.parent.leftChild = y;
   }else {
    x.parent.rightChild = y;
   }
  }else {
   this.mroot = y;
  }
  x.parent = y;
 }
 
 
 
 //红黑树添加修复
 public void insertFixUp(RBNode<T> node) {
  RBNode<T> parent,gparent;
  while(((parent = parentOf(node))!=null)&&isRed(parent)) {
   gparent = parentOf(parent);
   if(gparent.leftChild == parent) {
    RBNode<T> uncle = gparent.rightChild;
    if(isRed(uncle)){
     setBlack(parent);
     setBlack(uncle);
     setRed(gparent);
     
     node = gparent;
     continue;
    }else {
     if(parent.rightChild == node) {
       leftRonate(parent);
       RBNode<T> temp = node;
       node = parent;
       parent = temp;
     }
     
     setBlack(parent);
     setRed(gparent);
     rightRonate(gparent);
     
    }
   }else {
    
    RBNode<T> uncle = gparent.leftChild;
    if(isRed(uncle)) {
     setBlack(parent);
     setBlack(uncle);
     setRed(gparent);
     
     node = gparent;
     continue;
    }else {
     if(parent.leftChild == node) {
      rightRonate(parent);
      RBNode<T> temp = node;
      node = parent;
      parent = temp;
     }
     setBlack(parent);
     setRed(gparent);
     leftRonate(gparent);
    }
   }
  }
  
  if(mroot == node) {
   setBlack(node);
  }
 }
 //红黑树删除修复
 public void deleteFixUp(RBNode<T> node,RBNode<T> parent) {
     
  RBNode<T> other;
  while(isBlack(node)&&node!=this.mroot) {
      
       if(parent.leftChild == node) {
        other = parent.rightChild;
        if(isRed(other)) {
         setRed(parent);
         setBlack(other);
         leftRonate(parent);
         continue;
        }else {
         if(isBlack(other.leftChild)&&isBlack(other.rightChild)) {
          setRed(other);
          node = parent;
          parent = parentOf(node);
         
        
         }else if(isRed(other.leftChild)&&isBlack(other.rightChild)) {
          setRed(other);
          setBlack(other.leftChild);
          rightRonate(other);
         }else if(isRed(other.rightChild)) {
          setColor(other,colorOf(parent));
          setBlack(parent);
          setBlack(other.rightChild);
          leftRonate(parent);
          break;
         }
        }
       }else {
        other = parent.leftChild;
        if(isRed(other)) {
         setBlack(other);
         setRed(parent);
         rightRonate(parent);
         continue;
        }else {
         if(isBlack(other.leftChild)&&isBlack(other.rightChild)) {
          setRed(other);
          node = parent;
          parent = parentOf(node);
         
        
         }else if(isRed(other.rightChild)&&isBlack(other.leftChild)) {
          setRed(parent);
          setBlack(other.rightChild);
          leftRonate(other);
         }else if(isRed(other.leftChild)) {
          setColor(other, colorOf(parent));
          setBlack(parent);
          setBlack(other.leftChild);
          rightRonate(parent);
          break;
         }
        }
        }
  }
  
  setBlack(node);
 
 }
 
 
 //红黑树添加操作
 public void insert(RBNode<T> node) {
 
      int com;
      RBNode<T> x = this.mroot;
      RBNode<T> y = null;
      while(x!=null) {
       y = x;
       com = node.key.compareTo(x.key);
      
       if(com<0) {
       x=x.leftChild;
       }else{
       x=x.rightChild;
       }
      
      }
     
      node.parent = y;
     
      if(y!=null) {
       com = node.key.compareTo(y.key);
       if(com<0) {
        y.leftChild = node;
       }else {
        y.rightChild = node;
       }
      }else {
       this.mroot = node;
      }
      setRed(node);
      insertFixUp(node);
 }
 
     public void insert(T key) {
  
  RBNode<T> node = new RBNode<T>(BLACK,key,null,null,null);
  
  if(node!=null) {
   insert(node);
  }
  }
 
 //红黑树删除操作
 public void delete(RBNode<T> node) {
  
  RBNode<T> child,parent,replace;
  boolean color = true;
  if(node.leftChild!=null&&node.rightChild!=null) {
   replace = successor(node);
   
   parent = parentOf(replace);
   child = replace.rightChild;
   color = colorOf(replace);
   
   if(node == parentOf(replace)) {
     parent = replace;
   }else {
    if(child!=null) {
       setParent(child,parentOf(replace));
    }
    replace.parent.leftChild = child;
    replace.rightChild = node.rightChild;
    setParent(node.rightChild,replace);
   }
   
   setParent(replace, parentOf(node));
   replace.leftChild = node.leftChild;
   setParent(node.leftChild,replace);
   setColor(replace,colorOf(node));
   
   if(parentOf(node)!=null) {
    if(node.parent.leftChild==node) {
     node.parent.leftChild = replace;
    }else {
     node.parent.rightChild = replace;
    }
   }else {
    this.mroot = replace;
   } 
   
   if(color==BLACK){
       deleteFixUp(child, parent);
   }
  }else {
  
   if(node.leftChild!=null) {
    replace = node.leftChild;
   }else {
    replace = node.rightChild;
   }
   
     parent = parentOf(node);
     
     if(parent!=null) {
      if(parent.leftChild==node) {
       parent.leftChild = replace;
      }else {
       parent.rightChild = replace;
      }
     }else {
      this.mroot = replace;
     }
     setParent(replace, parent);
   
      color = colorOf(node);
      child = replace;
   if(color==BLACK) {
    deleteFixUp(child, parent);
   }
  } 
    
 }
 
 public void delete(T key) {
  RBNode<T> node;
  if((node=search(key,this.mroot))!=null) {
   delete(node);
  }
 }
 
 //前序遍历
 public void preOrder(RBNode<T> node) {
   if(node!=null) {  
  System.out.print(node.key+" ");
  preOrder(node.leftChild);
  preOrder(node.rightChild);
   } 
 }
 
 public void preOrder() {
  preOrder(this.mroot);
 }
 
 //中序遍历
 public void inOrder(RBNode<T> node) {
  if(node!=null) {
   inOrder(node.leftChild);
   System.out.print(node.key+" ");
   inOrder(node.rightChild);
  }
 }
 public void inOrder() {
  inOrder(this.mroot);
 }
 
 //后序遍历
 public void postOrder(RBNode<T> node) {
  if(node!=null) {
   postOrder(node.leftChild);
   postOrder(node.rightChild);
   System.out.print(node.key+" ");
  }
 }
 
 public void postOrder() {
  postOrder(this.mroot);
 }
 
 //打印红黑树
 public void print(RBNode<T> node,int direction) {
   if(node!=null) { 
  if(direction == 0) {
   System.out.printf("%2d(%s) is root\n",node.key,node.color==false?"R":"B");
  }else {
   System.out.printf("%2d(%s) is %s child 父节点  %2d\n",node.key,node.color==false?"R":"B",direction==-1?"left":"right",node.parent.key);
  }
  print(node.leftChild,-1);
  print(node.rightChild,1);
   } 
 }
 
 public void print() {
  print(this.mroot,0);
 }
 public static void main(String[] args) {
  
  DRBTree<Integer> tree = new DRBTree<Integer>();
  
  int[] a = {10,20,30,40,50,60,70,80,90};
  
  //红黑树添加测试
  for(int i=0;i<a.length;i++) {
   tree.insert(a[i]);
  }
  
  System.out.print("前序遍历: ");
  tree.preOrder();
  
  System.out.print("\n中序遍历: ");
  tree.inOrder();
  
  System.out.print("\n后序遍历: ");
  tree.postOrder();
  
  System.out.println();
  tree.print();
  
  System.out.print("\n输入要删除的节点:");
  Scanner scan = new Scanner(System.in);
  
  int key = scan.nextInt();
  
  //红黑树删除测试
  tree.delete(key);
  
  System.out.println();
  tree.print();
 }
}


  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
红黑树是一种自平衡二叉查找树。它的插入和删除操作都可能导致树的不平衡,需要进行旋转和重新着色操作来维护树的平衡。 下面是一个 Java 程序,它实现红黑树的插入和删除操作: ```java public class RedBlackTree<T extends Comparable<T>> { private static final boolean RED = true; private static final boolean BLACK = false; private Node<T> root; private class Node<T extends Comparable<T>> { T key; Node<T> left, right; boolean color; Node(T key, boolean color) { this.key = key; this.color = color; } } private boolean isRed(Node<T> x) { if (x == null) return false; return x.color == RED; } private Node<T> rotateLeft(Node<T> h) { Node<T> x = h.right; h.right = x.left; x.left = h; x.color = h.color; h.color = RED; return x; } private Node<T> rotateRight(Node<T> h) { Node<T> x = h.left; h.left = x.right; x.right = h; x.color = h.color; h.color = RED; return x; } private void flipColors(Node<T> h) { h.color = !h.color; h.left.color = !h.left.color; h.right.color = !h.right.color; } public void insert(T key) { root = insert(root, key); root.color = BLACK; } private Node<T> insert(Node<T> h, T key) { if (h == null) return new Node<>(key, RED); int cmp = key.compareTo(h.key); if (cmp < 0) h.left = insert(h.left, key); else if (cmp > 0) h.right = insert(h.right, key); else h.key = key; if (isRed(h.right) && !isRed(h.left)) h = rotateLeft(h); if (isRed(h.left) && isRed(h.left.left)) h = rotateRight(h); if (isRed(h.left) && isRed(h.right)) flipColors(h); return h; } public void delete

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值