红黑树描述

<pre name="code" class="java">/*
 * 红黑树
 */
public class RedBlackTree {
	public static final RbTreeNode NIL = new RbTreeNode(RbColor.BLACK);
	private RbTreeNode root = null;
	public static void main(String[] args) {
		RedBlackTree rbt = new RedBlackTree();
		//测试插入 page 179  红黑树不唯一
		rbt.insertRbTreeNode(new RbTreeNode(11,RbColor.BLACK));
		rbt.insertRbTreeNode(new RbTreeNode(2,RbColor.RED));
		rbt.insertRbTreeNode(new RbTreeNode(1,RbColor.BLACK));
		rbt.insertRbTreeNode(new RbTreeNode(7,RbColor.BLACK));
		rbt.insertRbTreeNode(new RbTreeNode(5,RbColor.RED));
		rbt.insertRbTreeNode(new RbTreeNode(8,RbColor.RED));
		rbt.insertRbTreeNode(new RbTreeNode(14,RbColor.BLACK));
		rbt.insertRbTreeNode(new RbTreeNode(15,RbColor.RED));
		rbt.printTree();
		rbt.deleteRbTreeNode(rbt.searchRbTreeNode(rbt.root, 7));
		rbt.printTree();
		System.out.println(rbt.searchMaximum(rbt.root).key);
	}

	public RedBlackTree() {
		this.root = NIL;
	}
	//中序遍历二叉树
	private void traverseTree(RbTreeNode x) {
		if(x != NIL) {
			traverseTree(x.left);
			System.out.print(x.key + " " + x.color + " ");
			traverseTree(x.right);
		}
	}
	private void printTree() {
		System.out.println("root:"+root.key+" "+root.color);
		traverseTree(root);
		System.out.println();
	}

	//查找某一子节点
	private RbTreeNode searchRbTreeNode(RbTreeNode x,int key) {
		while(x != NIL && key != x.key) {
			if(key < x.key) {
				x = x.left;
			} else {
				x = x.right;
			}
		}
		return x;
	}

	//插入某一子节点
	private void insertRbTreeNode(RbTreeNode z) {
		RbTreeNode y = NIL;
		RbTreeNode x = root;
		while(x != NIL) {
			y = x;
			if(z.key < x.key) {
				x = x.left;
			} else {
				x = x.right;
			}
		}
		z.parent = y;
		if(y == NIL) {
			root = z;
		} else if(z.key < y.key) {
			y.left = z;
		} else {
			y.right = z;
		}
		z.left = NIL;
		z.right = NIL;
		z.color = RbColor.RED;
		rbInsertFixUp(z);									//插入修正
	}

	//插入修正
	private void rbInsertFixUp(RbTreeNode z) {
		RbTreeNode y = null;
		while(z.parent.color == RbColor.RED) {				//当z的父节点是黑色时,不需要矫正
			if(z.parent == z.parent.parent.left) {			//左分支情况
				y = z.parent.parent.right;		//根据叔节点分情况
				if(y.color == RbColor.RED) {
					z.parent.color = RbColor.BLACK;
					y.color = RbColor.BLACK;
					z.parent.parent.color = RbColor.RED;
					z = z.parent.parent;
				} else {
					if(z == z.parent.right) {
						z = z.parent;
						leftRotate(z);
					}
					z.parent.color = RbColor.BLACK;
					z.parent.parent.color = RbColor.RED;
					rightRotate(z.parent.parent);
				}
			} else {
				y = z.parent.parent.left;		//根据叔节点分情况
				if(y.color == RbColor.RED) {
					z.parent.color = RbColor.BLACK;
					y.color = RbColor.BLACK;
					z.parent.parent.color = RbColor.RED;
					z = z.parent.parent;
				} else {
					if(z == z.parent.left) {
						z = z.parent;
						rightRotate(z);
					}
					z.parent.color = RbColor.BLACK;
					z.parent.parent.color = RbColor.RED;
					leftRotate(z.parent.parent);
				}
			}
		}
		root.color = RbColor.BLACK;
	}

	//删除某一子节点
	private void deleteRbTreeNode(RbTreeNode z) {
		RbTreeNode y = z;
		RbTreeNode x = NIL;
		RbColor yOriginalColor = y.color;
		if(z.left == NIL) {
			x = z.right;
			rbTransplant(z,z.right);
		} else if(z.right == NIL) {
			x = z.left;
			rbTransplant(z,z.left);
		} else {
			y = searchMinimum(z.right);
			yOriginalColor = y.color;
			x = y.right;
			if(y.parent == z) {
				x.parent = y;
			} else {
				rbTransplant(y,y.right);
				y.right = z.right;
				z.right.parent = y;
			}
			rbTransplant(z,y);
			y.left = z.left;
			z.left.parent = y;
			y.color = z.color;
		}
		if(yOriginalColor == RbColor.BLACK) {
			rbDeleteFixUp(x);
		}
	}

	private void rbDeleteFixUp(RbTreeNode x) {
		//x总是指向一个具有双重黑色的非根节点
		RbTreeNode w = NIL;
		while(x != root && x.color == RbColor.BLACK) {
			if(x == x.parent.left) {
				w = x.parent.right;		//w指向兄节点
				if(w.color == RbColor.RED) {
					w.color = RbColor.BLACK;				//case 1
					x.parent.color = RbColor.RED;			//case 1
					leftRotate(x.parent);					//case 1
					w = x.parent.right;						//case 1
				}
				if(w.left.color == RbColor.BLACK
					&& w.right.color == RbColor.BLACK) {
					w.color = RbColor.BLACK;				//case 2
					x = x.parent;							//case 2
				}
				else {
					if(w.right.color == RbColor.BLACK) {
						w.left.color = RbColor.BLACK;		//case 3
						w.color = RbColor.RED;				//case 3
						rightRotate(w);						//case 3
						w = x.parent.right;					//case 3
					}
					w.color = x.parent.color;				//case 4
					x.parent.color = RbColor.BLACK;			//case 4
					w.right.color = RbColor.BLACK;			//case 4
					leftRotate(x.parent);					//case 4
					x = root;								//case 4
				}
			} else {
				w = x.parent.left;		//w指向兄节点
				if(w.color == RbColor.RED) {
					w.color = RbColor.BLACK;				//case 1
					x.parent.color = RbColor.RED;			//case 1
					rightRotate(x.parent);					//case 1
					w = x.parent.left;						//case 1
				}
				if(w.right.color == RbColor.BLACK
					&& w.left.color == RbColor.BLACK) {
					w.color = RbColor.BLACK;				//case 2
					x = x.parent;							//case 2
				}
				else {
					if(w.left.color == RbColor.BLACK) {
						w.right.color = RbColor.BLACK;		//case 3
						w.color = RbColor.RED;				//case 3
						leftRotate(w);						//case 3
						w = x.parent.left;					//case 3
					}
					w.color = x.parent.color;
					x.parent.color = RbColor.BLACK;
					w.left.color = RbColor.BLACK;
					rightRotate(x.parent);
					x = root;
				}
			}
		}

	}

	private void rbTransplant(RbTreeNode u,RbTreeNode v) {
		if(u.parent == NIL) {
			root = v;
		} else if(u == u.parent.left) {
			u.parent.left = v;
		}  else {
			u.parent.right = v;
		}
		v.parent = u.parent;
	}

	//获取最小键值节点
	private RbTreeNode searchMinimum(RbTreeNode x) {
		while(x.left != NIL) {
			x = x.left;
		}
		return x;
	}

	//获取最大键值节点
	private RbTreeNode searchMaximum(RbTreeNode x) {
		while(x.right != NIL) {
			x = x.right;
		}
		return x;
	}

	//左旋
	private void leftRotate(RbTreeNode x) {
		RbTreeNode y = x.right;
		x.right = y.left;
		if(x.right != NIL) {
			y.left.parent = x;
		}
		y.parent = x.parent;
		if(x.parent == NIL) {			//如果是根节点
			root = y;
		} else if(x == x.parent.left) {
			x.parent.left = y;
		} else {
			x.parent.right = y;
		}
		y.left = x;
		x.parent = y;
	}

	//右旋
	private void rightRotate(RbTreeNode y) {
		RbTreeNode x = y.left;
		y.left = x.right;
		if(x.right != NIL) {
			x.right.parent = y;
		}
		x.parent = y.parent;
		if(y.parent == NIL) {
			root = x;
		} else if(y == y.parent.left) {
			y.parent.left = x;
		} else {
			y.parent.right = x;
		}
		x.right = y;
		y.parent = x;
	}

	//红黑树节点类
	private static class RbTreeNode {
		RbTreeNode left = null;
		RbTreeNode right = null;
		RbTreeNode parent = null;
		RbColor color = RbColor.RED;
		int key = 0;

		public RbTreeNode(int key,RbColor color) {
			this.key = key;
			this.color = color;
		}
		public RbTreeNode(RbColor color) {
			this.color = color;
		}
	}

	private enum RbColor {
		RED,BLACK
	}
}

时间: 2024-10-13 02:55:44

红黑树描述的相关文章

二叉树学习四:红黑树(参考维基百科)

1.红黑树描述:它或是一颗空树,或是具有下面属性的二叉搜索树: 1)节点非红即黑: 2)根节点是黑色: 3)所有NULL结点称为叶子节点,且认为颜色为黑 : 4)所有红节点的子节点都为黑色: 5)从任一节点到其叶子节点的所有路径上都包含相同数目的黑节点. 插入和删除操作时间可以保持为 O(log n) 次,图1(本文图来自维基百科)是一个具体的红黑树: 图1:红黑树 2.红黑树插入:假设插入节点为红,根据邻近结点的颜色进行具体调整: 1)为空树,直接插入,把颜色变换为黑: 2)插入结点的父结点为

红黑树&mdash;&mdash;算法导论(15)

1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极端情况是树变成了1条链)时,这些集合操作并不比在链表上执行的快.     于是我们需要构建出一种"平衡"的二叉搜索树.     红黑树(red-black tree)正是其中的一种.它可以保证在最坏的情况下,基本集合操作的时间复杂度是O(lgn). (2) 性质     与普通二叉搜索树不

B-树、B+树、红黑树

B-树 B-tree树即B树,B即Balanced,平衡的意思,B-树又称为多路平衡查找树.因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tree译作B-树,其实,这是个非常不好的直译,很容易让人产生误解.如人们可能会以为B-树是一种树,而B树又是另一种树.而事实上是,B-tree就是指的B树. 一.定义 B-树是一种多路搜索树(并不一定是二叉的) 1970年,R.Bayer和E.mccreight提出了一种适用于外查找的树,它是一种平衡的多叉树,称为B树(或B-树.B_树). 一棵

【算法导论】学习笔记——第13章 红黑树

红黑树(red-black tree)是许多平衡搜索树中的一种,因此基本操作(查询.删除.搜索)等在最坏情况下的时间复杂度均为O(lgn).13. 1 红黑树的性质红黑树时一棵二叉搜索树,并且在每个结点上增加了一个属性表示颜色:红色或黑色.通过对任何一条从根到叶子的简单路径上各个结点的颜色进行约束,红黑树确保没有一条路径会比其它路径长出2倍.因而是近似于平衡的.一棵红黑树是满足下面红黑性质的二叉搜索树:1. 每个结点是红色或黑色:2. 根结点是黑色的:3. 每个叶结点(NIL)是黑色的:4. 如

红黑树(一)之 原理和算法详细介绍---转帖

目录1 红黑树的介绍2 红黑树的应用3 红黑树的时间复杂度和相关证明4 红黑树的基本操作(一) 左旋和右旋5 红黑树的基本操作(二) 添加6 红黑树的基本操作(三) 删除 作者:Sky Wang    于 2013-08-08 概述:R-B Tree,又称为"红黑树".本文参考了<算法导论>中红黑树相关知识,加之自己的理解,然后以图文的形式对红黑树进行说明.本文的主要内容包括:红黑树的特性,红黑树的时间复杂度和它的证明,红黑树的左旋.右旋.插入.删除等操作. 请尊重版权,转

算法---红黑树实现介绍(一)

一.概述 红黑树是一种经典的存储结构,就其本身来说是一个二叉查找树,只是在这个基础上,树的节点增加了一个属性用于表示颜色(红或黑).通过限制从根节点到叶子的各个路径的节点着色的限制,来保证不会有哪个路径会比其它的路径长度超过2倍,从而红黑树是接近平衡的. 一直以来没有把红黑树完全理解,总觉得太难,望而生畏,最近下决心要弄清楚,也是花了很长时间,不过总算是明白了.记录下来以便更好的理解. 二.红黑树的特点 作为红黑树,需要有这5个限制,如下: 1)树中的每个节点,要么是红色,要么是黑色 2)树的根

红黑树(一)之原理和算法的详细分析【转】

本文转载自:http://www.cnblogs.com/skywang12345/p/3245399.html R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树.红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black). 红黑树的特性:(1)每个节点或者是黑色,或者是红色.(2)根节点是黑色.(3)每个叶子节点(NIL)是黑色. [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!](4)如果

树:BST、AVL、红黑树、B树、B+树

我们这个专题介绍的动态查找树主要有: 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree).这四种树都具备下面几个优势: (1) 都是动态结构.在删除,插入操作的时候,都不需要彻底重建原始的索引树.最多就是执行一定量的旋转,变色操作来有限的改变树的形态.而这些操作所付出的代价都远远小于重建一棵树.这一优势在<查找结构专题(1):静态查找结构概论 >中讲到过. (2) 查找的时间复杂度大体维持在O(log(N))数量级上.可能有些结构在最差的情况下效率将

红黑树(3) - 删除操作

在本系列的前面两篇文章中,已经介绍了红黑树以及其插入操作.具体可参考下面两个链接: 红黑树(1) - 介绍 红黑树(2) - 插入操作 1.删除操作介绍 类似于插入操作,红黑树进行删除节点时,也使用重新着色以及旋转这两种方式,来维护它的属性.在插入操作中,我们主要是依靠检测叔节点的颜色来决定哪种场景.在删除操作中,我们使用检测兄弟的颜色,来决定是哪种场景. 在插入操作中,最常见的违反红黑树属性的一种情况是存在两个连续的红色节点.而在删除操作中,常见的情况是,当删除节点是黑色时,会影响从根节点到叶