`

教你透彻了解红黑树

 
阅读更多

 

 

二叉搜索树实现:

import java.util.Objects;

public class SimpleBinarySearchTree {
	
	private BSTreeNode root;
	
	public SimpleBinarySearchTree()
	{
		this.root = null;
	}

	public BSTreeNode getRoot() {
		return root;
	}

	public void insert(SimpleBinarySearchTree T, BSTreeNode x)
	{
		
	}
	
	public void leftRotate(SimpleBinarySearchTree T, BSTreeNode x)
	{
		// set y
		BSTreeNode y = x.right;
		// Turn y's left subtree into x's right subtree
		x.right = y.left;
		y.left.parent = x;
		// Link x's parent to y
		y.parent = x.parent;
		if (x.parent == null)
		{
			root = y;
		}
		else if (x == x.parent.left)
		{
			x.parent.left = y;
		}
		else
		{
			x.parent.right = y;
		}
		// Put x on y's left
		y.left = x;
		x.parent = y;
	}

	static final class BSTreeNode
	{
		private BSTreeNode left;
		private BSTreeNode right;
		private BSTreeNode parent;
		private int value;
		
		public BSTreeNode(BSTreeNode left, BSTreeNode right, BSTreeNode parent, int value)
		{
			this.left = left;
			this.right = right;
			this.parent = parent;
			this.value = value;
		}

		public int getValue() {
			return value;
		}

		public void setValue(int value) {
			this.value = value;
		}
		
		@Override
		public int hashCode()
		{
			return Objects.hashCode(value);
		}
		
		@Override
		public boolean equals(Object o)
		{
			if (o == this)
			{
				return true;
			}
			
			if (o == null)
			{
				return false;
			}
			if (!(o instanceof BSTreeNode))
			{
				return false;
			}
			
			return ((BSTreeNode)o).value == value;
		}
	}
	
	public static void main(String[] args) {
		SimpleBinarySearchTree bsTree = new SimpleBinarySearchTree();
	}
}

 

 红黑树实现:

package com.linus.test;

import java.util.Objects;
import java.util.Random;

public class SimpleRedBlackTree {

	/* ------------------------------------------------------------ */
	// Tree bins

	/**
	 * Entry for Tree bins. Extends LinkedHashMap.Entry (which in turn extends
	 * Node) so can be used as extension of either regular or linked node.
	 */
	static final class SimpleRBTreeNode {
		int value;
		SimpleRBTreeNode parent; // red-black tree links
		SimpleRBTreeNode left;
		SimpleRBTreeNode right;
		boolean red;

		public SimpleRBTreeNode(SimpleRBTreeNode left, SimpleRBTreeNode right,
				SimpleRBTreeNode parent, int value) {
			this.value = value;
			this.left = left;
			this.right = right;
			this.parent = parent;
		}

		public SimpleRBTreeNode(int value) {
			this(null, null, null, value);
		}

		public final int getValue() {
			return value;
		}

		public final String toString() {
			return "value = " + value;
		}

		public final int hashCode() {
			return Objects.hashCode(value);
		}

		public final int setValue(int newValue) {
			int oldValue = value;
			value = newValue;
			return oldValue;
		}

		public final boolean equals(Object o) {
			if (o == this)
				return true;
			if (o instanceof SimpleRBTreeNode) {
				SimpleRBTreeNode e = (SimpleRBTreeNode) o;
				if (value == e.getValue())
					return true;
			}
			return false;
		}

		/**
		 * Returns root of tree containing this node.
		 */
		final SimpleRBTreeNode root() {
			for (SimpleRBTreeNode r = this, p;;) {
				if ((p = r.parent) == null)
					return r;
				r = p;
			}
		}

		public void clear() {
			SimpleRBTreeNode root = this;
			SimpleRBTreeNode left = root.left;
			SimpleRBTreeNode right = root.right;
			if (null != left) {
				left.clear();
			}
			if (null != right) {
				right.clear();
			}
			root.left = null;
			root.right = null;
			root.parent = null;
		}

		/**
		 * Finds the node starting at root p with the given value.
		 */
		final SimpleRBTreeNode find(int value) {
			SimpleRBTreeNode p = this;
			SimpleRBTreeNode pl = p.left, pr = p.right;
			if (p.value == value) {
				return p;
			} else if ((p.value > value) && (null != pl)) {
				return pl.find(value);
			} else if (null != pr) {
				return pr.find(value);
			} else {
				return null;
			}
		}

		/**
		 * Calls find for root node.
		 */
		final SimpleRBTreeNode getTreeNode(int value) {
			return ((parent != null) ? root() : this).find(value);
		}

		/* ------------------------------------------------------------ */
		// Red-black tree methods, all adapted from CLR

		static SimpleRBTreeNode rotateLeft(SimpleRBTreeNode root,
				SimpleRBTreeNode p) {
			SimpleRBTreeNode r, pp, rl;
			if (p != null && (r = p.right) != null) {
				if ((rl = p.right = r.left) != null)
					rl.parent = p;
				if ((pp = r.parent = p.parent) == null)
					(root = r).red = false;
				else if (pp.left == p)
					pp.left = r;
				else
					pp.right = r;
				r.left = p;
				p.parent = r;
			}
			return root;
		}

		static SimpleRBTreeNode rotateRight(SimpleRBTreeNode root,
				SimpleRBTreeNode p) {
			SimpleRBTreeNode l, pp, lr;
			if (p != null && (l = p.left) != null) {
				if ((lr = p.left = l.right) != null)
					lr.parent = p;
				if ((pp = l.parent = p.parent) == null)
					(root = l).red = false;
				else if (pp.right == p)
					pp.right = l;
				else
					pp.left = l;
				l.right = p;
				p.parent = l;
			}
			return root;
		}

		static SimpleRBTreeNode balanceInsertion(SimpleRBTreeNode root,
				SimpleRBTreeNode x) {
			x.red = true;
			for (SimpleRBTreeNode xp, xpp, xppl, xppr;;) {
				if ((xp = x.parent) == null) {
					x.red = false;
					return x;
				} else if (!xp.red || (xpp = xp.parent) == null)
					return root;
				if (xp == (xppl = xpp.left)) {
					if ((xppr = xpp.right) != null && xppr.red) {
						xppr.red = false;
						xp.red = false;
						xpp.red = true;
						x = xpp;
					} else {
						if (x == xp.right) {
							root = rotateLeft(root, x = xp);
							xpp = (xp = x.parent) == null ? null : xp.parent;
						}
						if (xp != null) {
							xp.red = false;
							if (xpp != null) {
								xpp.red = true;
								root = rotateRight(root, xpp);
							}
						}
					}
				} else {
					if (xppl != null && xppl.red) {
						xppl.red = false;
						xp.red = false;
						xpp.red = true;
						x = xpp;
					} else {
						if (x == xp.left) {
							root = rotateRight(root, x = xp);
							xpp = (xp = x.parent) == null ? null : xp.parent;
						}
						if (xp != null) {
							xp.red = false;
							if (xpp != null) {
								xpp.red = true;
								root = rotateLeft(root, xpp);
							}
						}
					}
				}
			}
		}

		static SimpleRBTreeNode balanceDeletion(SimpleRBTreeNode root,
				SimpleRBTreeNode x) {
			for (SimpleRBTreeNode xp, xpl, xpr;;) {
				if (x == null || x == root)
					return root;
				else if ((xp = x.parent) == null) {
					x.red = false;
					return x;
				} else if (x.red) {
					x.red = false;
					return root;
				} else if ((xpl = xp.left) == x) {
					if ((xpr = xp.right) != null && xpr.red) {
						xpr.red = false;
						xp.red = true;
						root = rotateLeft(root, xp);
						xpr = (xp = x.parent) == null ? null : xp.right;
					}
					if (xpr == null)
						x = xp;
					else {
						SimpleRBTreeNode sl = xpr.left, sr = xpr.right;
						if ((sr == null || !sr.red) && (sl == null || !sl.red)) {
							xpr.red = true;
							x = xp;
						} else {
							if (sr == null || !sr.red) {
								if (sl != null)
									sl.red = false;
								xpr.red = true;
								root = rotateRight(root, xpr);
								xpr = (xp = x.parent) == null ? null : xp.right;
							}
							if (xpr != null) {
								xpr.red = (xp == null) ? false : xp.red;
								if ((sr = xpr.right) != null)
									sr.red = false;
							}
							if (xp != null) {
								xp.red = false;
								root = rotateLeft(root, xp);
							}
							x = root;
						}
					}
				} else { // symmetric
					if (xpl != null && xpl.red) {
						xpl.red = false;
						xp.red = true;
						root = rotateRight(root, xp);
						xpl = (xp = x.parent) == null ? null : xp.left;
					}
					if (xpl == null)
						x = xp;
					else {
						SimpleRBTreeNode sl = xpl.left, sr = xpl.right;
						if ((sl == null || !sl.red) && (sr == null || !sr.red)) {
							xpl.red = true;
							x = xp;
						} else {
							if (sl == null || !sl.red) {
								if (sr != null)
									sr.red = false;
								xpl.red = true;
								root = rotateLeft(root, xpl);
								xpl = (xp = x.parent) == null ? null : xp.left;
							}
							if (xpl != null) {
								xpl.red = (xp == null) ? false : xp.red;
								if ((sl = xpl.left) != null)
									sl.red = false;
							}
							if (xp != null) {
								xp.red = false;
								root = rotateRight(root, xp);
							}
							x = root;
						}
					}
				}
			}
		}

		/**
		 * Recursive invariant check
		 */
		static boolean checkInvariants(SimpleRBTreeNode t) {
			SimpleRBTreeNode tp = t.parent, tl = t.left, tr = t.right;
			if (tp != null && t != tp.left && t != tp.right)
				return false;
			if (t.red && tl != null && tl.red && tr != null && tr.red)
				return false;
			if (tl != null && !checkInvariants(tl))
				return false;
			if (tr != null && !checkInvariants(tr))
				return false;
			return true;
		}
	}

	private SimpleRBTreeNode root;

	public void insert(int value) {
		SimpleRBTreeNode y = null;
		SimpleRBTreeNode parent = this.getRoot();

		while (parent != null) {
			y = parent;
			if (value < parent.getValue()) {
				parent = parent.left;
			} else if (value > parent.getValue()) {
				parent = parent.right;
			} else {
				System.out.println("Duplicate value: " + value);
				return;
			}
		}

		SimpleRBTreeNode node = new SimpleRBTreeNode(null, null, null, value);
		node.parent = y;
		if (y == null) {
			// Tree T is empty
			this.setRoot(node);
		} else if (node.getValue() < y.getValue()) {
			y.left = node;
		} else {
			y.right = node;
		}
		node.left = null;
		node.right = null;
		node.red = true;
		SimpleRBTreeNode.balanceInsertion(getRoot(), node);
	}

	public SimpleRBTreeNode delete(int value) {
		return SimpleRBTreeNode.balanceDeletion(root, new SimpleRBTreeNode(
				value));
	}

	public SimpleRBTreeNode getRoot() {
		return root;
	}

	public void setRoot(SimpleRBTreeNode root) {
		this.root = root;
	}

	public static void printTreeValue(SimpleRBTreeNode root) {
		if (null != root.left) {
			printTreeValue(root.left);
		}
		System.out.println("Value = " + root.value);
		if (null != root.right) {
			printTreeValue(root.right);
		}
	}

	public static void main(String[] args) {
		System.out.println("Test case 1");
		SimpleRedBlackTree tree = new SimpleRedBlackTree();
		Random rand = new Random(System.currentTimeMillis());
		int value;
		for (int i = 0; i < 5; i++) {
			value = rand.nextInt(100);
			System.out.println("Insert value: " + value);
			tree.insert(value);
		}
		SimpleRedBlackTree.printTreeValue(tree.getRoot());
		tree.getRoot().clear();

		System.out.println("Test case 2");
		SimpleRedBlackTree.printTreeValue(tree.getRoot());
		for (int i = 0; i < 5; i++) {
			tree.insert(i);
		}
		SimpleRedBlackTree.printTreeValue(tree.getRoot());
	}
}

 

 

网站地址:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/03.01.md

分享到:
评论

相关推荐

    杨过-教你透彻了解红黑树1

    参考算法导论 第12章 二叉查找树 第12.4节)。但二叉树若退化成了一棵具有n个结点的线性链后,则此些操作最坏情况运行时间为O(n)。后面我们会看到一种基于二

    红黑树的c实现源码与教程

    教你透彻了解红黑树: http://blog.csdn.net/v_JULY_v/archive/2010/12/29/6105630.aspx 红黑树算法的层层剖析与逐步实现 http://blog.csdn.net/v_JULY_v/archive/2010/12/31/6109153.aspx Ok,君自看。 ----------...

    十三个常用算法

    五(续)、教你透彻了解红黑树 六、教你从头到尾彻底理解KMP 算法 七、遗传算法 透析GA 本质 八、再谈启发式搜索算法 九、图像特征提取与匹配之SIFT 算法 九(续)、sift 算法的编译与实现 九(再续)、教你一步一步...

    十五个经典算法研究与总结、目录+索引(定稿版)

    五、教你透彻了解红黑树 (红黑数系列六篇文章之其中两篇) 五(续)、红黑树算法的实现与剖析 六、教你初步了解KMP算法、updated (KMP算法系列三篇文章) 六(续)、从KMP算法一步一步谈到BM算法 六(三续)、KMP...

    红黑树讲解ppt

    专业的红黑树讲解,透彻而细腻,学习红黑树的必备利器

    Struts1 程实例教

    Struts1 程实例教 透彻分析了Struts1的原理 外加实例配带 经典之作适合入门者和想详细了解Struts1的人 Struts1 程实例教 透彻分析了Struts1的原理 外加实例配带 经典之作适合入门者和想详细了解Struts1的人Struts1 ...

    透透彻彻了解服务器技术

    介绍服务器的技术例如磁盘阵列,集群技术,高端服务器技术,等常见集群技术 的一些技术介绍,让我们透彻透彻的了解服务器技术!

    一个把struts解释很透彻的教程

    一个把struts解释很透彻的教程

    电容去耦透彻讲解

    电容去耦透彻讲解

    jsp分页教程(资料)—透彻分析

    多种用列,多种方式,有浅到深的讲述了JSP分页技术

    三极管工作原理精辟透彻分析

    三极管工作原理分析,精辟、透彻,看后你就懂 随着科学技的发展,电子技术的应用几乎渗透到了人们生产生活的方方面面。晶体三极管作为电子技术中一个最为基本的常用器件,其原理对于学习电子技术的人自然应该是一个...

    8张图带你透彻了解三极管开关功能

    晶体管(三极管)的功能之一就是作为开关,利用其截止特性,实现开关功能。 但是很多人并不能很好的理解三极管的开关功能,下面以 8 个实例图片,生动的阐述三极管作为开关的功能。 低边开关 高边开关 基极电阻...

    primetime透彻解读作品

    primetime透彻解读作品primetime透彻解读作品primetime透彻解读作品

    最透彻明了的了解webservice 车票管理系统

    我最近遇到的问题,vs2008写出来的程序是3.5版本的vs2005是2.0的 现在大部分主机都支持2.0,如果你用2008的话,挂上去,配置文件会报错,这时你就要高转低了,把windouws里的3.5程序集删除了,然后把配置文件里的也...

    C语言教程\如何透彻理解C语言中指针的概念

    这一片文章很好的讲解的怎么去理解C语言的指针运用,对于C语言学习者,有很高的价值

    CAN控制器的波特率问题(透彻).doc

    知道怎么计算CAN控制器的波特率吗?这是一篇讲的很透彻的文章

    透彻解析眼图测量技术

    1.眼图的概念与作用2.眼图基本原理—如何生成眼图—眼图相关参数3.眼图测量步骤详解4.力科示波器在眼图测量方面的特点

    ERP的核心理念(精髓、透彻)

    ERP的核心理念(精髓、透彻)!仅供参考!希望对大家有所帮助!

    透彻分析FAT文件系统

    透彻分析FAT文件系统,有助于了解嵌入式文件系统的实现

Global site tag (gtag.js) - Google Analytics