- 浏览: 122596 次
- 性别:
- 来自: 上海
最新评论
红黑树是一种二叉平衡树搜索树,相关背景知识此处不再叙述。
节点与关键值之间的关系与普通二叉树 一致,只是在插入时要保证红黑规则,如果插入过程中违反了红黑规则,树则会通过自我调整,改变树的结构和节点的颜色,使之满足红黑规则。满足红黑规则的树是平衡树。
红黑规则如下:
1. 每一个节点不是黑的就是红的
2. 根总是黑的
3. 红色节点的子节点必定是黑的,反之未必
4. 从根到叶节点或空子节点的每条路径中必然包含同样高度的黑色节点(从根到叶节点或空子节点的每条路径中必然有同样的高度)
为了保证红黑规则,程序按照如下方式工作:
新插入的节点(除了根以外)的是红的
插入过程中如果有一个黑色节点且它有两个红色节点,就需要颜色变化,如果该节点是根节点,则根节点不变化
右旋必须有一个左子节点,左旋必须有一个右子节点
旋转时,外侧子孙上升,内侧子孙断开其与父节点的连接,并成为其祖父节点的子节点
向下查找子节点的时候,发现一个黑色节点有两个红色节点时候,就执行一次颜色变化。
之后检查红黑冲突,发生冲突时
红色节点为X,红色节点的父节点为P,祖父节点为G,
旋转后继续向下查找
插入子节点X后
如果P为红色
如果X为G的外侧子孙,旋转一次
以G为顶点作一次旋转
如果X为G的内侧子孙,旋转两次
红黑树与Tree-2-3-4 原理非常相似,事实上可以相互转换。
Node为辅助类,充当树节点,并记录红黑。
Tree尽提供插入算法,且假设插入的数据不重复。
Tree.ordinal: 打印数据,为测试服务
Tree.main: 提供简单测试。
其他平衡树见:Tree-2-3 , Tree-2-3-4
class Node { private int value; //数值 private Node parent; private Node left; private Node right; private boolean isBlack; Node(int value) { this.value = value; } Node insert(int value) { Node node = new Node(value); if(value < this.value) left(node); else right(node); return node; } boolean isCorrect() { //返回当前节点是否与父节点都是红色,如果是,则返回fasle return !(parent != null && !parent.isBlack && !isBlack); } Node getNext(int value) { //根据给定的值返回下一个可以插入数据的节点 if(value < this.value) return left; else return right; } void left(Node node) { left = node; if(node != null) node.parent = this; } Node left() { return left; } void right(Node node) { right = node; if(node != null) node.parent = this; } Node right() { return right; } int value() { return value; } Node getParent() { return parent; } boolean isOuter(Node node) { //判断父节点与当前节点,当前节点与给定子节点是否在同一方向 return parent.isLeft(this) && this.isLeft(node) || !parent.isLeft(this) && !this.isLeft(node); } boolean isLeft(Node node) { return node == left; } void changeColor() { isBlack = !isBlack; } boolean isBlack() { return isBlack; } } class Tree { private Node root; //根节点 public void insert(int value) { if(root == null) { //添加根节点,并将根置为黑色 root = new Node(value); root.changeColor(); } else { Node current = root; //从根节点开始向下遍历,寻找可以插入新值的节点 while(current.getNext(value) != null) { fixColor(current); //如果需要,则修正颜色 if(!current.isCorrect()) fix(current); //如果发生红黑冲突,则修正 current = current.getNext(value); //继续寻找可以插入新值的下一个节点 } current = current.insert(value); //在找到的节点下插入新值 if(!current.isCorrect()) fix(current); //如果发生红黑冲突,则修正 } } private void fixColor(Node node) { //如果当前节点是红色,且两个子节点是黑色,则翻转颜色 if(node.isBlack() && node.left() != null && !node.left().isBlack() && node.right() != null && !node.right().isBlack()) { if(node != root) node.changeColor(); //根始终保持黑色 node.left().changeColor(); node.right().changeColor(); } } private void fix(Node node) { //修正红黑冲突 Node p = node.getParent(); //获得父节点 Node g = p.getParent(); //获得祖父节点 if(p.isOuter(node)) { //如果是祖父的外孙,则需要变化两次颜色,做一次旋转 g.changeColor(); p.changeColor(); if(p.isLeft(node)) turnRight(g); //以祖父节点为中心做一次右旋 else turnLeft(g); } else { //如果是祖父的内孙,则需要变化两次颜色,做两次旋转 g.changeColor(); node.changeColor(); if(!p.isLeft(node)) { turnLeft(p); //以父节点为中心作一次左旋 turnRight(g); //以祖父节点为中心做一次右旋 } else { turnRight(p); turnLeft(g); } } } private void turnLeft(Node node) { //左旋算法 Node p = node.getParent(); Node right = node.right(); node.right(right.left()); right.left(node); if(node == root) root = right; else if (p.isLeft(node)) p.left(right); else p.right(right); } private void turnRight(Node node) { //右旋算法 Node p = node.getParent(); Node left = node.left(); node.left(left.right()); left.right(node); if(node == root) root = left; else if (p.isLeft(node)) p.left(left); else p.right(left); } public void ordinal() { System.out.println("==============="); ordinal(root,0); System.out.println("==============="); } private void ordinal(Node node, int level) { //打印 if(node == null) return; ordinal(node.left() , level + 1); System.out.println(node.value() + (node.isBlack() ? " black" : " red") + " " + level); ordinal(node.right() , level + 1); } public static void main(String[] args) { Tree t = new Tree(); t.insert(50); t.ordinal(); t.insert(60); t.ordinal(); t.insert(70); t.ordinal(); t.insert(80); t.ordinal(); t.insert(40); t.ordinal(); t.insert(30); t.ordinal(); t.insert(20); t.ordinal(); t.insert(10); t.ordinal(); t.insert(35); t.ordinal(); t.insert(55); t.ordinal(); t.insert(75); t.ordinal(); t.insert(73); t.ordinal(); t.insert(53); t.ordinal(); t.insert(33); t.ordinal(); } }
发表评论
-
Tree 2-3 平衡搜索树
2008-04-25 00:21 2327与2-3-4树 相似,2-3 平衡树是 ... -
Tree 2-3-4 平衡搜索树
2008-04-20 10:53 34932-3-4 平衡树是一种搜索树。每个节点可能会有2,3,4个子 ... -
Graph 图-邻接表法
2008-04-17 00:08 3004用邻接表法表示的双向图(改单向容易,只要修改connect,d ... -
Graph 图-邻接矩阵法
2008-04-16 22:56 3533用邻接矩阵法表示的双向图(改单向容易,只要修改connect, ... -
Heap 堆
2008-04-16 00:28 1471这里的堆不是java中内存分配的堆。只是一种数据结构。 堆是二 ... -
HashTable 基于链表地址法
2008-04-15 00:49 1647功能上于前面两个HashTable(-) ,HashTable ... -
HashTable 基于开放地址法(二)
2008-04-14 19:40 2013与前一个HashTable 基本相同(方法说明请参照它),只是 ... -
HashTable 基于开放地址法
2008-04-13 22:59 1584该HashTable基于定常数组的开放地址法,搜索时采用线性探 ... -
Tree 二叉搜索树
2008-04-11 00:03 1712每个节点最多两个子节点,其中左边节点的值小于该节点的值,右边节 ... -
PriorityQueue 优先级队列
2008-04-06 17:57 3449提供一个基于链表的优先级队列,为了简便,只存储整数,假设数值越 ... -
PriorityQueue 优先级队列
2008-04-06 16:57 4347提供一个基于定长数组的优先级队列,为了简便,只存储整数,假设数 ... -
Queue 队
2008-04-06 13:36 1549指定最大值的队,底层用数组实现构造函数:指定最大容量put:放 ... -
ArrayStack 栈
2008-04-06 12:00 1300用Array实现的栈结构,功能与LinkedStack一致编程 ... -
Array 可变长可变维数组
2008-04-06 11:25 1841一个可以变长,变维的数组(只可以变大),用来替代多维数组基本做 ... -
StackDLink 双向链表
2008-04-05 23:20 1152用LinkedStack实现的双向链表,功能与DLink一致就 ... -
LinkedList 列表
2008-04-05 19:16 1460列表的简单实现,只能存储非负整数List 也属于ADT(抽象数 ... -
ArrayList 列表
2008-04-05 19:01 1206列表的简单实现,只能存储非负整数List 也属于ADT(抽象数 ... -
LinkedQueue 队
2008-04-05 18:43 1855实现了队的最简单功能:先进现出队属于ADT(抽象数据类型),其 ... -
DLink 双向双端链表
2008-04-05 18:06 1502DLink 实现一个简单的双向双端链表与Link一样,假定其之 ... -
LinkedStack 栈
2008-04-05 17:45 1122LinkedStack栈属于ADT(抽象数据类型),其提供同样 ...
相关推荐
红黑树C语言代码: #include "redblack.h" #include #include "fatal.h" 头文件: #include #include "fatal.h" typedef int ElementType; #define NegInfinity (-10000) #ifndef _RedBlack_H #define _Red...
• 点击上传资源即表示您确认该资源不违反资源分享的使用条款,并且您拥有该资源的所有版权或者上传资源的授权 • 您上传的资源如果因版权、使用、内容完整度 等原因被举报并通过官方审核,将扣除通过该资源获得的...
红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家鲁道夫·贝尔在1978年提出。它在保持二叉查找树特性的同时,通过引入颜色属性来确保树的平衡,从而提高了数据操作的效率。红黑树的主要目标是保证在...
红黑树(Red-Black Tree)是一种自平衡二叉查找树,它的每个节点都带有颜色属性,可以是红色或黑色。这种数据结构被广泛应用于计算机科学的许多领域,特别是操作系统、数据库系统以及编译器中,用于高效地执行插入、...
红黑树(Red-Black Tree)是一种自平衡的二叉查找树,由Rudolf Bayer在1972年提出,它的设计目标是为了在插入、删除和查找等操作时保持较好的性能。红黑树的名字来源于它节点的颜色属性,每个节点可以是红色或黑色。...
通用红黑树 说明: 用Linux内核红黑树封装的一个通用型的红黑树 如何使用该红黑树: 见rbtest1.c和rbtest2.c 直接make生成rbtest1和rbtest2 作者:rcyh 日期:2011年7月21日 ---------------------------------...
红黑树(Red Black Tree)是一种自平衡二叉查找树,由计算机科学家Rudolf Bayer在1972年提出。这种数据结构在现代计算机科学中广泛应用,特别是在各种需要高效查找、插入和删除操作的场景中。红黑树的主要特点是通过...
红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中扮演着重要的角色,尤其是在实现高效的数据结构和算法时。在Java中,虽然标准库并未直接提供红黑树的类,但我们可以自定义实现,如提供的`Red...
红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中用于实现关联数组。这种数据结构最初由Rudolf Bayer在1972年发明,当时称为“对称二叉B树”,但在1978年由Leonidas J. Guibas和Robert Sedgewick...
红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家鲁道夫·贝尔在1978年提出。它在保持二叉查找树特性的同时,通过引入颜色属性来确保树的平衡,从而提高数据操作的效率。在C++中实现红黑树,通常...
红黑树是一种自平衡二叉查找树,它的设计目的是为了在保持查找效率的同时,尽可能地减少插入和删除操作带来的性能损失。在计算机科学中,它是一种广泛应用的数据结构,特别是在动态排序和高效查找方面。 二叉搜索树...
红黑树是一种自平衡二叉查找树(self-balancing binary search tree),由计算机科学家Rudolf Bayer在1972年提出。它在保持二叉查找树特性的同时,通过引入颜色属性来确保树的平衡,从而提高数据操作的效率。在红黑...
这是本人写的一个红黑树的模版,只需要改一下接口就可以用了。基本操作查找,删除,修改都是O(logn).
红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中扮演着重要的角色,尤其是在数据结构和算法领域。红黑树的名字来源于它的节点颜色属性:红色或黑色。这种颜色属性被用来确保树的某些关键性质,...
在实验中,`RedBlackTree.c`和`RedBlackTree.h`文件包含了红黑树的实现,包括插入、删除、旋转、查找等操作。`Tree.dot`文件用于生成红黑树的图形表示,通过graphviz工具可视化。 区间树是一种特殊的树形数据结构,...
"红黑树的代码实现" 红黑树是一种自平衡的二叉查找树,它具有良好的查找、插入和删除性能。红黑树的代码实现是使用C++语言编写的,使用模板实现,可以对任意类型的数据进行处理。 红黑树的节点结构体定义为: ```...
红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中扮演着重要的角色,尤其是在数据结构和算法领域。红黑树的名字来源于它的节点颜色属性:红色或黑色。这种颜色属性用于确保树的平衡,使得在树中的...
红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家Rudolf Bayer在1972年提出。它在数据结构和算法领域具有重要地位,被广泛应用于各种系统和软件中,包括数据库索引、编译器、虚拟机等。在Delphi编程...
红黑树(Red-Black Tree)是一种自平衡二叉查找树,由IBM的研究员鲁道夫·贝尔在1972年提出。它的设计目标是在插入、删除和查找操作上保持近似最坏情况下的O(log n)时间复杂度,同时通过特定的颜色规则保证树的平衡...
红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家Rudolf Bayer在1972年提出。它在数据结构和算法领域具有重要地位,广泛应用于数据库索引、编译器符号表、虚拟内存管理等多个场景。红黑树的主要特点...