`

教你透彻了解红黑树

 
阅读更多

 

 

二叉搜索树实现:

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

    红黑树的插入操作类似于二叉查找树,但插入后需要根据红黑树的性质进行调整,可能涉及旋转和重新着色。首先,我们按照二叉查找树的方式找到插入位置,然后插入新节点并检查是否违反红黑树的性质。如果违反,通过旋转...

    红黑树的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...

    红黑树原理详解

    红黑树(Red-Black Tree)是一种自...红黑树的概念深入且复杂,理解并实现它需要对二叉树、排序和颜色属性有透彻的理解。在学习过程中,可以通过分析和模拟插入、删除操作来加深理解,并通过实际编程练习来巩固知识。

    十三个经典算法研究与总结、目录+索引

    #### 五(续):教你透彻了解红黑树 本篇通过更加深入的方式讲解红黑树的工作机制,包括插入和删除操作的处理方式,以及如何维护树的平衡特性。通过具体的例子和代码实现,帮助读者真正理解红黑树的核心思想。 ####...

    Struts1 程实例教

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

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

    "jsp分页教程(资料)—透彻分析"这个主题深入讲解了如何在JSP项目中实现高效且灵活的分页功能。下面我们将详细探讨JSP分页的相关知识点。 1. **基本概念**:分页是将大量数据分为多个部分,每次只加载一部分到页面上...

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

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

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

    通过这个透彻的Struts教程,开发者不仅可以理解Struts的基本工作流程,还能学习到如何有效地利用其特性来提高开发效率和应用质量。无论是初学者还是有经验的开发者,都能从中受益匪浅,提升自己的Java Web开发技能。

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

    《三极管工作原理精辟透彻分析》 在当今科技日新月异的时代,电子技术已经渗透到我们日常生活的各个角落,而晶体三极管作为电子技术的基础元件,其工作原理的理解对于学习电子技术至关重要。本文将深入剖析三极管的...

    透彻解析眼图测量技术

    ### 透彻解析眼图测量技术 #### 一、眼图的概念与作用 眼图是一种图形化的表示方式,用于评估高速数字通信系统中信号的质量。它由示波器通过重复采集信号并将其叠加显示而成,形成类似眼睛的图形。眼图能够直观地...

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

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

    电容去耦透彻讲解

    ### 电容去耦透彻讲解 #### 一、电容去耦原理概述 电容去耦技术在电子电路设计中扮演着至关重要的角色,它主要用于解决电源噪声问题,提高瞬态电流响应速度,并降低电源分配系统的阻抗。在电路板上,尤其是在负载...

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

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

    廖雪峰大神python教程1-3及新版全套PDF

    教程以中文呈现,语言简洁明了,讲解透彻,使得学习过程更为轻松。 在Python基础部分,教程会介绍Python的安装、语法特性,如变量、数据类型(包括整型、浮点型、字符串、布尔型等)、流程控制(条件语句、循环语句...

    钯金深度透彻分析.docx

    钯金深度透彻分析

Global site tag (gtag.js) - Google Analytics