算法导论 红黑树 实现(一)

首先实现插入 左旋转 右旋转 并测试
暂时未考虑颜色转换

// rbTreeTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <memory>
#include <iostream>

using namespace std;

enum Color {
    red = 1,
    black
};

struct node {
    Color color_;
    std::shared_ptr<node> left_;
    std::shared_ptr<node> right_;
    std::shared_ptr<node> parent_;
    int value_;
    node() {
        left_ = right_ = parent_ = nullptr;
        value_ = -1;
        color_ = black;
    }
};

std::shared_ptr<node> nil(new node);

std::shared_ptr<node> CreateNode(Color color, int i) {
    std::shared_ptr<node> p(new node);
    p->color_ = color;
    p->left_ = nil;
    p->right_ = nil;
    p->parent_ = nil;
    p->value_ = i;
    return p;
}

void RightRotate(std::shared_ptr<node>& root, std::shared_ptr<node>& x) {
    std::shared_ptr<node> y = x->left_;
    x->left_ = y->right_;
    if (y->right_ != nil)
        y->right_->parent_ = x;
    y->parent_ = x->parent_;
    if (x->parent_ == nil){
        root = y;
    }
    else if (x->parent_->left_ == x) {
        x->parent_->left_ = y;
    }
    else {
        x->parent_->right_ = y;
    }

    y->right_ = x;
    x->parent_ = y;
}

void LeftRotate(std::shared_ptr<node>& root, std::shared_ptr<node>& x) {
    std::shared_ptr<node> y = x->right_;
    x->right_ = y->left_;
    if (y->left_ != nil)
        y->left_->parent_ = x;

    y->parent_ = x->parent_;
    if (x->parent_ == nil) {
        root = y;
    }
    else if (x->parent_->left_ == x) {
        x->parent_->left_ = y;
    }
    else {
        x->parent_->right_ = y;
    }
    y->left_ = x;
    x->parent_ = y;
}

void PrinTree(std::shared_ptr<node> root) {
    if (root == nil) {
        return;
    }
    std::cout << root->value_ << " ";
    if(root->left_!=nil)
        PrinTree(root->left_);
    if(root->right_ != nil)
        PrinTree(root->right_);
}

void test11() {
    std::shared_ptr<node> root = CreateNode(black, 2);
    root->parent_ = nil;
    std::shared_ptr<node> x = root;
    std::shared_ptr<node> y = CreateNode(red, 1);
    root->left_ = y;
    y->parent_ = x;

    PrinTree(root);
    std::cout << std::endl;
    RightRotate(root, x);
    PrinTree(root);
    std::cout << std::endl;

    std::cout << std::endl;
}

void test1() {
    //构建测试1,2
    std::shared_ptr<node> root = CreateNode(black, 1);
    root->parent_ = nil;
    std::shared_ptr<node> x = root;
    root->right_ = CreateNode(red, 2);
    root->right_->parent_ = root;

    PrinTree(root);
    std::cout << std::endl;
    LeftRotate(root, x);
    PrinTree(root);
    std::cout << std::endl;

    std::cout << std::endl;
}

void test22() {
    std::shared_ptr<node> root = CreateNode(black, 4);
    root->parent_ = nil;
    std::shared_ptr<node> x = root;

    std::shared_ptr<node> y = CreateNode(black, 3);
    x->left_ = y;
    y->parent_ = x;

    std::shared_ptr<node> z = CreateNode(black, 2);
    y->left_ = z;
    z->parent_ = y;

    PrinTree(root);
    std::cout << std::endl;

    RightRotate(root, x);
    PrinTree(root);
    std::cout << std::endl;

    std::cout << std::endl;
}

void test2() {
    std::shared_ptr<node> root = CreateNode(black, 1);
    root->parent_ = nil;
    root->right_ = CreateNode(red, 2);
    root->right_->parent_ = root;

    std::shared_ptr<node> x = root->right_;

    std::shared_ptr<node> y = CreateNode(red, 3);
    x->right_ = y;
    y->parent_ = x;
    PrinTree(root);
    std::cout << std::endl;

    LeftRotate(root, x);
    PrinTree(root);
    std::cout << std::endl;

    std::cout << std::endl;
}

void test33() {
    std::shared_ptr<node> root = CreateNode(black, 9);
    root->parent_ = nil;
    std::shared_ptr<node> a = root;

    std::shared_ptr<node> b = CreateNode(black, 10);
    a->right_ = b;
    b->parent_ = a;

    std::shared_ptr<node> c = CreateNode(black, 6);
    a->left_ = c;
    c->parent_ = a;

    std::shared_ptr<node> d = CreateNode(black, 8);
    c->right_ = d;
    d->parent_ = c;

    std::shared_ptr<node> e = CreateNode(black, 4);
    c->left_ = e;
    e->parent_ = c;

    std::shared_ptr<node> f = CreateNode(black, 2);
    e->left_ = f;
    f->parent_ = e;

    std::shared_ptr<node> g = CreateNode(black, 5);
    e->right_ = g;
    g->parent_ = e;

    PrinTree(root);
    std::cout << std::endl;

    RightRotate(root, c);

    PrinTree(root);
    std::cout << std::endl;

    std::cout << std::endl;
}

void test3() {
    std::shared_ptr<node> root = CreateNode(black, 1);
    root->parent_ = nil;

    root->right_ = CreateNode(red, 3);
    root->right_->parent_ = root;

    std::shared_ptr<node> x = root->right_;

    std::shared_ptr<node> y = CreateNode(red, 2);
    x->left_ = y;
    y->parent_ = x;

    std::shared_ptr<node> z = CreateNode(red, 4);
    x->right_ = z;
    z->parent_ = x;

    PrinTree(root);
    std::cout << std::endl;

    LeftRotate(root, x);
    PrinTree(root);
    std::cout << std::endl;

    std::cout << std::endl;
}

void test4() {
    std::shared_ptr<node> root = CreateNode(black, 5);
    root->parent_ = nil;

    std::shared_ptr<node> a = CreateNode(red, 2);
    root->left_ = a;
    a->parent_ = root;

    std::shared_ptr<node> b = CreateNode(red, 7);
    root->right_ = b;
    b->parent_ = root;

    std::shared_ptr<node> c = CreateNode(red, 6);
    b->left_ = c;
    c->parent_ = b;

    std::shared_ptr<node> d = CreateNode(red, 9);
    b->right_ = d;
    d->parent_ = b;

    std::shared_ptr<node> e = CreateNode(red, 8);
    d->left_ = e;
    e->parent_ = d;

    std::shared_ptr<node> f = CreateNode(red, 10);
    d->right_ = f;
    f->parent_ = d;

    PrinTree(root);
    std::cout << std::endl;

    LeftRotate(root, b);
    PrinTree(root);
    std::cout << std::endl;

    std::cout << std::endl;
}

void RBInsert(std::shared_ptr<node>& root, std::shared_ptr<node>& ins) {
    std::shared_ptr<node> y = nil;
    std::shared_ptr<node> x = root;

    while (x != nil) {
        y = x;
        if (ins->value_ < x->value_) {
            x = x->left_;
        }
        else {
            x = x->right_;
        }
    }
    ins->parent_ = y;
    if (y == nil) {
        root = ins;
    }
    else if (ins->value_ < y->value_) {
        y->left_ = ins;
    }
    else {
        y->right_ = ins;
    }
    ins->left_ =ins->right_ = nil;
    ins->color_ = red;
    // todo  fixup
}

void TestInsert() {
    std::shared_ptr<node> root = nil;
    std::shared_ptr<node> x = CreateNode(red, 7);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red,4);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 11);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 3);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 6);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 9);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 18);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 2);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 14);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 19);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 12);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 17);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 22);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    x = CreateNode(red, 20);
    RBInsert(root, x);
    PrinTree(root);
    std::cout << std::endl;

    std::cout << std::endl;
}

int main()
{
    TestInsert();
    test1();
    test2();
    test3();
    test4();
    test11();
    test22();
    test33();

    return 0;
}

时间: 2024-12-14 02:18:30

算法导论 红黑树 实现(一)的相关文章

算法导论 红黑树 学习 旋转(二)

学习算法 还是建议看看算法导论 算法导论第三版 如果不看数学推导 仅看伪代码 难度还是适中 本系列只是记录我的学习心得 和伪代码转化代码的过程 深入学习 还是建议大家看看算法书籍 教程更加系统. 本文参考算法导论第13章节 红黑树 代码由本人写成 转载请标明出处 红黑树是一个带颜色的二叉树 有以下5点性能 1 每个节点或者红色或者黑色 2 根节点黑色 3 每个叶子节点(nil)为黑色 4 如果一个节点是红色的则它的两个子节点都是黑色 5 每个节点 该节点到子孙节点的路径上 黑色节点数目相同 如图

算法导论-------------红黑树

红黑树是一种二叉查找树,但在每个结点上增加了一个存储位表示结点的颜色,可以是RED或者BLACK.通过对任何一条从根到叶子的路径上各个着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的.本章主要介绍了红黑树的性质.左右旋转.插入和删除.重点分析了在红黑树中插入和删除元素的过程,分情况进行详细讨论.一棵高度为h的二叉查找树可以实现任何一种基本的动态集合操作,如SEARCH.PREDECESSOR.SUCCESSOR.MIMMUM.MAXMUM.INSERT.DELETE等

算法导论 红黑树 学习 删除(四)

版权声明:本文为博主原创文章,未经博主允许不得转载.技术博客 http://blog.csdn.net/stecdeng 技术交流群 群号码:324164944 欢迎c c++ windows驱动爱好者 服务器程序员沟通交流 学习算法 还是建议看看算法导论 算法导论第三版 如果不看数学推导 仅看伪代码 难度还是适中 本系列只是记录我的学习心得 和伪代码转化代码的过程 深入学习 还是建议大家看看算法书籍 教程更加系统. 本文参考算法导论第13章节 红黑树 代码由本人写成 转载请标明出处 先看看不做

[[算法导论]红黑树速记

红黑树的性质: 1.每个结点要么是红色要么是黑色的. 2.根结点是黑色的. 3.所有叶结点(nil)是黑色的. 4.每个红色结点的两个孩子都是黑色的. 5.每个结点到其后代叶结点的简单路径上均包含相同数目的黑色结点. INSERT操作按二叉搜索树的方法插入新结点. INSERT-FIXUP(三种情况): 插入后新结点(z)为红色,当z.p==z.p.p.left时. 循环条件:父结点为红色. 情况1:叔结点(z.p.p.right)为红色. 父结点和叔结点改为黑色,祖父结点改为红色并成为新的z结

算法导论 红黑树 实现

由于红黑树的删除用到了二叉树的一些函数 所以我们从二叉树讲起 二叉树 不带颜色的红黑树 看看两张画的有点丑的图 如图 一个节点 记录一个数值 同时还有两个指向该节点两个儿子的标识 儿子有两个 左儿子和右儿子 图中就有两个二叉树示例 一个仅有右儿子  一个左右儿子均有 C语言中或者C++语言中我们这样定义二叉树结构 struct node { std::shared_ptr<node> left_; //智能指针 std::shared_ptr<node> right_; int v

算法导论—红黑树

华电北风吹 天津大学认知计算与应用重点实验室 日期:2015/9/9 红黑树是对二叉树的一种平衡扩展.红黑树采用开放的数据扩张策略,并且对于诸如插入.查询,删除有Θ(lg n)的时间复杂度,因此也是一种应用比较广泛的数据结构. 一.红黑树的节点 节点属性:关键字key,节点颜色,左孩子指针,右孩子指针,父节点指针,卫星数据. 虚拟节点-NIL:对于红黑树中所有节点如果没有父节点或者缺少某个子节点,则把对应的指针指向同一个NIL. 二.红黑树的性质 1.每个节点的颜色是红色或黑色. 2.根节点是黑

[算法导论]红黑树插入实现 @ Python

直接上代码: class RBTree: def __init__(self): self.nil = RBTreeNode(0) self.root = self.nil class RBTreeNode: def __init__(self, x): self.key = x self.left = None self.right = None self.parent = None self.color = 'black' class Solution: def InorderTreeWal

算法之红黑树

红黑树(一) 原理和算法详细介 1 R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为"红黑树",它一种特殊的二叉查找树.红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black). 红黑树的特性:(1)每个节点或者是黑色,或者是红色.(2)根节点是黑色.(3)每个叶子节点(NIL)是黑色. [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!](4)如果一个节点是红色的,则它的子节点必须是黑色的.(5)从一个节点到该节点

算法:红黑树

算法:红黑树 红黑树介绍 红黑树(英语:Red–black tree)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组.它是在1972年由鲁道夫·贝尔发明的,他称之为"对称二叉B树",它现代的名字是在Leo J. Guibas和Robert Sedgewick于1978年写的一篇论文中获得的. 红黑树本质上是一种二叉查找树,但它在二叉查找树的基础上额外添加了一个标记(颜色),同时具有一定的规则.这些规则使红黑树保证了一种平衡,插入.删除.查找的最坏时