`
shenyu
  • 浏览: 122596 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Tree 红黑树

阅读更多

红黑树是一种二叉平衡树搜索树,相关背景知识此处不再叙述。

节点与关键值之间的关系与普通二叉树 一致,只是在插入时要保证红黑规则,如果插入过程中违反了红黑规则,树则会通过自我调整,改变树的结构和节点的颜色,使之满足红黑规则。满足红黑规则的树是平衡树。

红黑规则如下:

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();
       
    }
}

 

4
3
分享到:
评论

相关推荐

    redblack tree 红黑树代码

    红黑树C语言代码: #include "redblack.h" #include #include "fatal.h" 头文件: #include #include "fatal.h" typedef int ElementType; #define NegInfinity (-10000) #ifndef _RedBlack_H #define _Red...

    RB-Tree红黑树

    • 点击上传资源即表示您确认该资源不违反资源分享的使用条款,并且您拥有该资源的所有版权或者上传资源的授权 • 您上传的资源如果因版权、使用、内容完整度 等原因被举报并通过官方审核,将扣除通过该资源获得的...

    红黑树-动态演示生成红黑树

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家鲁道夫·贝尔在1978年提出。它在保持二叉查找树特性的同时,通过引入颜色属性来确保树的平衡,从而提高了数据操作的效率。红黑树的主要目标是保证在...

    红黑树的源码与测试函数

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,它的每个节点都带有颜色属性,可以是红色或黑色。这种数据结构被广泛应用于计算机科学的许多领域,特别是操作系统、数据库系统以及编译器中,用于高效地执行插入、...

    hongheishu.rar_binary tree_红黑树

    红黑树(Red-Black Tree)是一种自平衡的二叉查找树,由Rudolf Bayer在1972年提出,它的设计目标是为了在插入、删除和查找等操作时保持较好的性能。红黑树的名字来源于它节点的颜色属性,每个节点可以是红色或黑色。...

    Linux内核红黑树封装的通用红黑树

    通用红黑树 说明: 用Linux内核红黑树封装的一个通用型的红黑树 如何使用该红黑树: 见rbtest1.c和rbtest2.c 直接make生成rbtest1和rbtest2 作者:rcyh 日期:2011年7月21日 ---------------------------------...

    红黑树(Red Black Tree)

    红黑树(Red Black Tree)是一种自平衡二叉查找树,由计算机科学家Rudolf Bayer在1972年提出。这种数据结构在现代计算机科学中广泛应用,特别是在各种需要高效查找、插入和删除操作的场景中。红黑树的主要特点是通过...

    红黑树java操作代码 红黑树是java里面遍历性能最好数据结构

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中扮演着重要的角色,尤其是在实现高效的数据结构和算法时。在Java中,虽然标准库并未直接提供红黑树的类,但我们可以自定义实现,如提供的`Red...

    关于红黑树(Red-Black Tree)英文论文

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中用于实现关联数组。这种数据结构最初由Rudolf Bayer在1972年发明,当时称为“对称二叉B树”,但在1978年由Leonidas J. Guibas和Robert Sedgewick...

    RBT.rar_red black tree_红黑树

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家鲁道夫·贝尔在1978年提出。它在保持二叉查找树特性的同时,通过引入颜色属性来确保树的平衡,从而提高数据操作的效率。在C++中实现红黑树,通常...

    gcc 红黑树(二叉搜索树 红黑树 动态排序树 精确计时)

    红黑树是一种自平衡二叉查找树,它的设计目的是为了在保持查找效率的同时,尽可能地减少插入和删除操作带来的性能损失。在计算机科学中,它是一种广泛应用的数据结构,特别是在动态排序和高效查找方面。 二叉搜索树...

    红黑树-数据结构

    红黑树是一种自平衡二叉查找树(self-balancing binary search tree),由计算机科学家Rudolf Bayer在1972年提出。它在保持二叉查找树特性的同时,通过引入颜色属性来确保树的平衡,从而提高数据操作的效率。在红黑...

    红黑树(RB_Tree) 模版

    这是本人写的一个红黑树的模版,只需要改一下接口就可以用了。基本操作查找,删除,修改都是O(logn).

    红黑树实现源码

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中扮演着重要的角色,尤其是在数据结构和算法领域。红黑树的名字来源于它的节点颜色属性:红色或黑色。这种颜色属性被用来确保树的某些关键性质,...

    红黑树与区间树算法实现

    在实验中,`RedBlackTree.c`和`RedBlackTree.h`文件包含了红黑树的实现,包括插入、删除、旋转、查找等操作。`Tree.dot`文件用于生成红黑树的图形表示,通过graphviz工具可视化。 区间树是一种特殊的树形数据结构,...

    红黑树的代码实现

    "红黑树的代码实现" 红黑树是一种自平衡的二叉查找树,它具有良好的查找、插入和删除性能。红黑树的代码实现是使用C++语言编写的,使用模板实现,可以对任意类型的数据进行处理。 红黑树的节点结构体定义为: ```...

    红黑树Java实现

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,它在计算机科学中扮演着重要的角色,尤其是在数据结构和算法领域。红黑树的名字来源于它的节点颜色属性:红色或黑色。这种颜色属性用于确保树的平衡,使得在树中的...

    delphi红黑树源码

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家Rudolf Bayer在1972年提出。它在数据结构和算法领域具有重要地位,被广泛应用于各种系统和软件中,包括数据库索引、编译器、虚拟机等。在Delphi编程...

    RED-BLACK-tree-and-2-3-4tree.rar_234树到红黑树_红黑树

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,由IBM的研究员鲁道夫·贝尔在1972年提出。它的设计目标是在插入、删除和查找操作上保持近似最坏情况下的O(log n)时间复杂度,同时通过特定的颜色规则保证树的平衡...

    红黑树.源码

    红黑树(Red-Black Tree)是一种自平衡二叉查找树,由计算机科学家Rudolf Bayer在1972年提出。它在数据结构和算法领域具有重要地位,广泛应用于数据库索引、编译器符号表、虚拟内存管理等多个场景。红黑树的主要特点...

Global site tag (gtag.js) - Google Analytics