红黑树插入与查找

之前学习过红黑树,今天花时间写一下红黑树,突然发现发明红黑树的人简直就是天才!!!
红黑树作者----鲁道夫·贝尔
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;
		}
	}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值