2-3查找树和红黑二叉查找树

2-3查找树
定义:一颗2-3查找树或一颗空树,或由一下节点组成:

  1. 2-结点,含有一个键(及其对应的值)和两个链接,左链接指向的2-3树中的键都小于该结点,右链接指向的2-3树中的键都大于该结点
  2. 3-结点,含有两个键(及其对应的值)和三条链接,左链接指向的2-3树中的键都小于该结点,中链接指向的2-3树中的键都位于该结点的两个键之间,右链接指向2-3树中的键都大于该结点

红黑二叉查找树
定义:我们将树中的链接分为两种类型:
红链接将两个2-结点连接起来,构成一个3-结点
黑链接则是2-3树中的普通链接。

2-3查找树和红黑二叉查找树的关系
是一一对应的关系:
如果我们将红黑二叉树中的红链接所连接的两个结点合并,那么我们就会得到一颗2-3树。
相反,我们将一个2-3树中的3-结点画作由红色链接相连的两个2-结点,那么会得到一颗红黑树

用java表示红黑二叉查找树中的一个结点

	private class Node{
		Key key;
		Value value;
		Node left, right;
		int N;
		boolean color;
		
		Node(Key key, Value value, int N, boolean color){
			this.key = key;
			this.value = value;
			this.color = color;
		}
	}

在插入一个新的键时,我们主要通过旋转的操作帮助我们保证红黑树与2-3树之间的对应关系,以及保持平衡

		private static final boolean RED = true;
		private static final boolean BLACK = false;
		//结点的计数器
		private int size(Node x) {
			if(x == null) {
				return 0;
			}else {
				return x.N;
			}
		}
		//左旋转一个h结点的右链接
		Node rotateLeft(Node h) {
			Node x = h.left;
			h.right = x.left;
			x.color = h.color;
			h.color = RED;
			x.N = h.N;
			h.N = 1 + size(h.left) + size(h.right);
			return x;
		}
		//右旋转h的左链接
		Node rotateRight(Node h) {
			Node x = h.left;
			h.left = x.right;
			x.right = h;
			x.color = RED;
			x.N = h.N;
			h.N = 1 + size(h.left) + size(h.right);
			return x;
		}

红黑树的插入操作:

		//分解结点时转换链接颜色
		void flipColors(Node h) {
			h.color = RED;
			h.left.color = BLACK;
			h.right.color = BLACK;
		}
		//结点的计数器
		private int size(Node x) {
			if(x == null) {
				return 0;
			}else {
				return x.N;
			}
		}
		//插入操作:
		private Node put(Node h, Key key, Value val) {
			if(h == null) {
				return new Node(key, val, 1, RED);
			}
			int cmp = key.compareTo(h.key);
			if(cmp < 0) {
				h.left = put(h.left,key,val);
			}else if(cmp > 0){
				h.right = put(h.right, key, val);
			}else {
				h.value = val;
			}
			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);
			}
			h.N = size(h.left) + size(h.right) + 1;
			return h;
		}
		private Node root;
		public void put(Key key, Value val) {
			root = put(root, key, val);
			root.color = BLACK;
		}

本文参考自《算法(第四版)》韦恩著
github链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值