红黑树的实现

1.知识储备:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.API设计:
在这里插入图片描述
在这里插入图片描述

3.平衡化:
在这里插入图片描述
在这里插入图片描述
4.插入:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.颜色反转:
在这里插入图片描述
6.知识点:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
7.:代码实现:

package Tree;

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;
		//存储值
		private value value;
		//记录左节点
		public Node left;
		//记录右节点
		public Node right;
		//由父节点指向当前节点的链接颜色
		 public boolean color;   //true代表红色,false代表黑色
		 
		 public Node(key key,value value,Node left,Node right,boolean color) {
			// TODO Auto-generated constructor stub
			 this.key=key;
			 this.value=value;
			 this.left=left;
			 this.right=right;
			 this.color=color;
		}
	}
	public RedBlackTree() {
		// TODO Auto-generated constructor stub
		this.root=null;
		this.N=0;
	}
	
	//判断当前节点父指向链接是否为红色
	private boolean isRED(Node x){
		//安全性验证
		if(x==null){
			return false;
		}
		return x.color==RED;
	}
	
	//左旋调整
	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;
		//由于反转完成后之前的父节点最终会指向x节点,所以返回x节点
		return x;
	}
	
	//右旋调整
	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属性为RED
		h.color=RED;
		//由于反转完成后之前的父节点最终会指向x节点,所以返回x节点
		return x;
	}
	
	//颜色反转,相当于完成拆分4-节点
	private void flipColors(Node h){
		//使当前节点变为红色
		h.color=RED;
		//当前节点的左子节点和右子节点都变为黑色
		h.left.color=BLACK;
		h.right.color=BLACK;
	}
	
	//在整个树上完成插入操作
	public void put(key key,value value){
		root=put(root,key,value);
		//根节点的颜色总是黑色
		root.color=BLACK; 
	}
	
	//在指定树中完成插入操作,并返回添加元素后新的树
	
	
	
	private Node put(Node h,key key,value value){
		//判断h是否为空,如果为空则直接返回一个红色的节点就可以了
		if(h==null){
			//元素个数+1
			N++;
			return new Node(key,value,null,null,RED);
		}
		//比较h节点的键和key的大小
		int cmp=h.key.compareTo(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;
			
		}
		
		//进行左旋:当当前节点h的左子节点为黑色,右子节点为红色,需要左旋
		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;
	}
	
	
	
	/*private Node put(Node h,key key,value value){
		//判断h是否为空,如果为空则直接返回一个红色的节点就可以了
		if(h==null){
			//元素个数+1
			N++;
			return new Node(key,value,null,null,RED);
		}
		//比较h节点的键和key的大小
		int cmp=h.key.compareTo(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;
			
		}
		
		//进行左旋:当当前节点h的左子节点为黑色,右子节点为红色,需要左旋
		if(h.left.color==BLACK&&h.right.color==RED){
			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;
	}*/
	
	//根据key在树中查找对应值
	public value get(key key){
		return get(root,key);
	}
	
	//从指定树中找出key对应值
	private value get(Node h,key key){
		//安全性校验
		if(h==null){
			return null;
		}
		//比较h节点的键和key的大小
		int cmp=h.key.compareTo(key);
		if(cmp>0){
			return get(h.right,key);
		}else if(cmp<0){
			return get(h.left,key);
		}else{
			return h.value;
			
		}
	}
	
	//获取树中元素个数
	public int size(){
		return N;
	}
}

8.测试:

package Tree;

public class RedBlackTreeTest {
    public static void main(String[] args) {
		//创建红黑树
    	RedBlackTree<Integer,String> tree=new RedBlackTree<Integer, String>();
    	//插入
    	tree.put(4,"4");
    	tree.put(2,"2");
    	tree.put(6,"6");
    	tree.put(1,"1");
    	tree.put(5,"5");
    	tree.put(3,"3");
    	tree.put(7,"7");
    	//获取
    	for(int i=1;i<=7;i++){
    		String value=tree.get(i);
    		System.out.println(value);
    	}
    	
    	System.out.println(tree.size());
	}
}

9.测试结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值