之前学习过红黑树,今天花时间写一下红黑树,突然发现发明红黑树的人简直就是天才!!!
红黑树作者----鲁道夫·贝尔
public class RB_tree {
//定义结点默认颜色是红色
static class TreeNode{
public TreeNode(int value,int index) {
this.index=index;
this.value=value;
}
int value = 0;
boolean RED = true;
TreeNode parent = null;
TreeNode left = null;
TreeNode right = null;
int index=0;
int count=0;
}
static TreeNode treeRoot = new TreeNode(-1, -1);
public static void main(String[] args) {
int[]nums = new int[]{1,1,2,3,5,8,7,9,11};
for(int i=0;i<nums.length;++i) {
TreeNode node = new TreeNode(nums[i],i);
insert(treeRoot.left, node);
}
delete(7);
System.out.println(query(7));
}
//加速搜索红黑树中大于某个值的元素,返回元素个数
public static int upper_sum(int value,TreeNode root) {
int sum=0;
if(root==null) return 0;
if(root.value<=value) {
sum=upper_sum(value, root.right);
}else {
sum+=upper_sum(value, root.left);
sum+=root.count;
sum+=upper_sum(value, root.left);
}
return sum;
}
public static int query(int target) {
TreeNode curr = treeRoot.left;
while(curr!=null) {
if(target>curr.value) {
curr=curr.right;
}else if(target<curr.value) {
curr=curr.left;
}else return curr.index;
}
return -1;
}
//插入方法
public static void insert(TreeNode root,TreeNode newNode) {
TreeNode curr = root;
if(root==null) {
newNode.RED=false;
treeRoot.left=newNode;
return;
}
while(curr!=null) {
if(newNode.value>curr.value) {
if(curr.right!=null) curr=curr.right;
else {
//先插入
curr.right=newNode;
newNode.parent=curr;
//调整红黑树,使其满足红黑树规则
fixup(newNode);
break;
}
}else if(newNode.value<curr.value) {
if(curr.left!=null) curr=curr.left;
else {
curr.left=newNode;
newNode.parent=curr;
fixup(newNode);
break;
}
}else return;
//元素已经存在,直接返回
}
}
//调整红黑树,使其满足要求
public static void fixup(TreeNode newNode) {
TreeNode parent = newNode.parent;
while(parent!=null&&parent.RED) {
//判断叔叔节点是其父节点的左子结点还是右子结点,为旋转做准备
boolean uncleInRight = parent.parent.right==parent;
TreeNode uncle = uncleInRight?parent.parent.right:parent.parent.left;
if(uncle.RED) /*叔叔节点是红结点*/{
parent.RED=false;
uncle.RED=false;
parent.parent.RED=true;
newNode=parent.parent;
}else/*叔叔节点是空节点*/{
//叔叔节点使其父节点的右子结点
if(uncleInRight) {
boolean currInLeft = newNode.parent.left==newNode;
if(currInLeft) {
//改变颜色
newNode.parent.RED=false;
newNode.parent.parent.RED=true;
//右旋
rightRotate(newNode.parent.parent);
break;
}else {
//左旋
leftRotate(newNode.parent);
newNode=newNode.left;
}
}
//叔叔节点是其父节点的左子结点
else {
boolean currInLeft = newNode.parent.left==newNode;
if(!currInLeft) {
//换颜色
newNode.parent.RED=false;
newNode.parent.parent.RED=true;
//左旋
leftRotate(newNode.parent.parent);
break;
}else {
//右旋
rightRotate(newNode.parent);
newNode=newNode.right;
}
}
}
parent=newNode.parent;
treeRoot.left.RED=false;
}
}
//删除结点
public static void delete(int target) {
TreeNode curr=treeRoot.left;
while(curr!=null) {
//如果目标元素值大于当前节点元素值,则当前节点设置成当前节点的右子结点
if(target>curr.value) {
curr=curr.right;
}
//如果目标元素值小于当前节点元素值,则当前节点设置成当前节点的左子结点
else if(target<curr.value) {
curr=curr.left;
}
//如果目标元素值等于当前节点元素值
else {
TreeNode successor = null;
//如果待删除结点是叶子结点
if(curr.right==null&&curr.left==null)
{
successor=curr;
//successor设置成当前节点,完成调整
}
//如果结点只有右子树
else if(curr.right!=null&&curr.left==null) {
//如果结点是根结点,那么直接把根结点设置成当前节点的右子结点
if(curr==treeRoot.left) {
curr.right.RED=curr.RED;
treeRoot.left=curr.right;
return;
}
if(curr.parent.left==curr) {
//如果当前节点不是根结点,并且当前节点是其父节点的左子结点
//把当前节点的颜色赋值给其右子结点,并把当前节点的右子结点赋值给其父节点的左子结点
curr.right.RED=curr.RED;
curr.parent.left=curr.right;
}else {
//如果当前节点不是根结点,并且当前节点是其父节点的右子结点
//把当前节点的颜色赋值给其右子结点,并把当前节点的右子结点赋值给其父节点的右子结点
curr.right.RED=curr.RED;
curr.parent.right=curr.right;
}
return;
}else if(curr.right==null&&curr.left!=null) {
if(curr==treeRoot.left) {
curr.left.RED=curr.RED;
treeRoot.left=curr.left;
return;
}
if(curr.parent.left==curr) {
curr.left.RED=curr.RED;
curr.parent.left=curr.left;
}else {
curr.left.RED=curr.RED;
curr.parent.right=curr.left;
}
return;
}else {
successor = nextTreeNode(curr);
int temp = curr.value;
curr.value=successor.value;
successor.value=temp;
curr=successor;
continue;
}
if(successor.RED) {
if(successor.parent.left==successor) {
successor.parent.left=null;
}else {
successor.parent.right=null;
}
return;
}else {
if(successor.parent.left==successor) {
if(successor.parent.right!=null) {
deFix_up(successor.parent.right);
}
successor.parent.left=null;
}else {
if(successor.parent.left!=null) {
deFix_up(successor.parent.left);
}
successor.parent.right=null;
}
return;
}
}
}
}
//找到待删除节点的后继结点/或者前驱结点,这里找到是后继结点
public static TreeNode nextTreeNode(TreeNode target) {
TreeNode curr = target.right;
if(curr==null) return null;
while(curr!=null) {
if(curr.left!=null) curr=curr.left;
else return curr;
}
return target.right;
}
//删除后调整
public static void deFix_up(TreeNode newNode) {
TreeNode curr=newNode;
while(curr!=treeRoot.left) {
TreeNode parent=curr.parent;
boolean inLeft = parent.left==curr;
//被删除结点的兄弟节点是黑色,父节点是红色
if(!curr.RED&&parent.RED) {
if(inLeft) {
curr.RED=true;
parent.RED=false;
break;
}else {
curr.RED=true;
parent.RED=false;
break;
}
}
//兄弟节点是红色,父节点是黑色
else if(curr.RED) {
parent.RED=true;
if(inLeft) {
curr.RED=false;
leftRotate(parent);
break;
}else {
curr.RED=false;
rightRotate(parent);
break;
}
}else if(inLeft&&curr.left.RED) {
curr.RED=parent.RED;
parent.RED=false;
curr.left.RED=false;
rightRotate(parent);
break;
}else if(!inLeft&&curr.right.RED){
curr.RED=parent.RED;
parent.RED=false;
curr.right.RED=false;
leftRotate(parent);
break;
}else if(inLeft&&curr.right.RED) {
curr.RED=true;
curr.right.RED=false;
leftRotate(curr);
curr=curr.parent;
}else if(!inLeft&&curr.left.RED) {
curr.RED=true;
curr.left.RED=false;
rightRotate(curr);
curr=curr.parent;
}else {
curr.RED=true;
curr=curr.parent;
}
}
}
//右旋
public static void rightRotate(TreeNode Node) {
TreeNode root=Node.parent;
boolean inRight = false;
TreeNode temp = Node.left;
Node.parent = temp;
Node.left=temp.right;
temp.right=Node;
if(root!=null) {
inRight = root.left==Node;
if(inRight) {
root.left=temp;
temp.parent=root;
}
else {
root.right=temp;
temp.parent=root;
}
}
}
//左旋
public static void leftRotate(TreeNode Node) {
TreeNode root=Node.parent;
boolean inRight = false;
TreeNode temp = Node.right;
Node.parent = temp;
Node.right=temp.left;
temp.left=Node;
if(root!=null) {
inRight = root.left==Node;
if(inRight) {
root.left=temp;
temp.parent=root;
}
else {
root.right=temp;
temp.parent=root;
}
}
}
}
红黑树插入与查找
最新推荐文章于 2024-11-26 17:29:16 发布