研磨数据结构与算法-14红黑树

红黑树:

public class RBTree {

private final Node NIL = new Node(null,null,null,Color.BLACK,-1);

private Node root;

public RBTree() {

root = NIL;

}

public RBTree(Node  root) {

this.root = root;

}

//插入节点

public void rbInsert(Node node) {

Node previous = NIL;

Node temp = root;

while (temp != NIL) {

previous = temp;

if (temp.getValue() < node.getValue()) {

temp = temp.getRight();

} else {

temp = temp.getLeft();

}

}

node.setParent(previous);

if (previous == NIL) {

root = node;

root.setParent(NIL);

} else  if (previous.getValue() > node.getValue()) {

previous.setLeft(node);

} else {

previous.setRight(node);

}

node.setLeft(NIL);

node.setRight(NIL);

node.setColor(Color.RED);

rb_Insert_Fixup(node);

}

//插入节点后的调整

private void rb_Insert_Fixup(Node node) {

while (node.getParent().getColor() == Color.RED) {

if (node.getParent() == node.getParent().getParent().getLeft()) {

Node rightNuncle = node.getParent().getParent().getRight();

if (rightNuncle.getColor() == Color.RED) {         //Case 1

rightNuncle.setColor(Color.BLACK);

node.getParent().setColor(Color.BLACK);

node.getParent().getParent().setColor(Color.RED);

node = node.getParent().getParent();

} else if (node == node.getParent().getRight()) {  //case 2

node = node.getParent();

leftRotate(node);

} else {                                          //case 3

node.getParent().setColor(Color.BLACK);

node.getParent().getParent().setColor(Color.RED);

rightRotate(node.getParent().getParent());

}

} else {

Node leftNuncle = node.getParent().getParent().getLeft();

if (leftNuncle.getColor() == Color.RED) {     //case 4

leftNuncle.setColor(Color.BLACK);

node.getParent().setColor(Color.BLACK);

node.getParent().getParent().setColor(Color.RED);

node = node.getParent().getParent();

} else if (node == node.getParent().getLeft()) { //case 5

node = node.getParent();

rightRotate(node);

} else {                                          // case 6

node.getParent().setColor(Color.BLACK);

node.getParent().getParent().setColor(Color.RED);

leftRotate(node.getParent().getParent());

}

}

}

root.setColor(Color.BLACK);

}

//删除节点

public Node rbDelete(int data) {

Node node = search(data);

Node temp = NIL;

Node child = NIL;

if (node == null) {

return null;

} else {

if (node.getLeft() == NIL || node.getRight() == NIL) {

temp = node;

} else {

temp = successor(node);

}

if (temp.getLeft() != NIL) {

child = temp.getLeft();

} else {

child = temp.getRight();

}

child.setParent(temp.getParent());

if (temp.getParent() == NIL) {

root = child;

} else if (temp == temp.getParent().getLeft()) {

temp.getParent().setLeft(child);

} else {

temp.getParent().setRight(child);

}

if (temp != node) {

node.setValue(temp.getValue());

}

if (temp.getColor() == Color.BLACK) {

rb_Delete_Fixup(child);

}

return temp;

}

}

//删除节点后的调整

private void rb_Delete_Fixup(Node node) {

while (node != root && node.getColor() == Color.BLACK) {

if (node == node.getParent().getLeft()) {

Node rightBrother = node.getParent().getRight();

if (rightBrother.getColor() == Color.RED) {          //case 1 node节点为左孩子,node节点的兄弟为RED

rightBrother.setColor(Color.BLACK);

node.getParent().setColor(Color.RED);

leftRotate(node.getParent());

rightBrother = node.getParent().getRight();

}

if (rightBrother.getLeft().getColor() == Color.BLACK && rightBrother.getRight().getColor() == Color.BLACK) {

rightBrother.setColor(Color.RED);

node = node.getParent();

} else if (rightBrother.getRight().getColor() == Color.BLACK) {

rightBrother.getLeft().setColor(Color.BLACK);

rightBrother.setColor(Color.RED);

rightRotate(rightBrother);

rightBrother = node.getParent().getRight();

} else {

rightBrother.setColor(node.getParent().getColor());

node.getParent().setColor(Color.BLACK);

rightBrother.getRight().setColor(Color.BLACK);

leftRotate(node.getParent());

node = root;

}

} else {

Node leftBrother = node.getParent().getLeft();

if (leftBrother.getColor() == Color.RED) {

leftBrother.setColor(Color.BLACK);

node.getParent().setColor(Color.RED);

rightRotate(node.getParent());

leftBrother = node.getParent().getLeft();

}

if (leftBrother.getLeft().getColor() == Color.BLACK && leftBrother.getRight().getColor() == Color.BLACK) {

leftBrother.setColor(Color.RED);

node = node.getParent();

} else if (leftBrother.getLeft().getColor() == Color.BLACK) {

leftBrother.setColor(Color.RED);

leftBrother.getRight().setColor(Color.BLACK);

leftRotate(leftBrother);

leftBrother = node.getParent().getLeft();

} else {

leftBrother.setColor(node.getParent().getColor());

node.getParent().setColor(Color.BLACK);

leftBrother.getLeft().setColor(Color.BLACK);

rightRotate(node.getParent());

node = root;

}

}

}

node.setColor(Color.BLACK);

}

//查找节点node的后继节点

public Node successor(Node node) {

Node rightChild = node.getRight();

if  (rightChild != NIL) {

Node previous = null;

while (rightChild != NIL) {

previous = rightChild;

rightChild = rightChild.getLeft();

}

return previous;

} else {

Node parent = node.getParent();

while (parent != NIL && node != parent.getLeft()) {

node = parent;

parent = parent.getParent();

}

return parent;

}

}

//查找节点

public Node search(int data) {

Node temp = root;

while (temp != NIL) {

if (temp.getValue() == data) {

return temp;

} else  if (data < temp.getValue()) {

temp = temp.getLeft();

} else {

temp = temp.getRight();

}

}

return null;

}

//左转函数

private void leftRotate(Node node) {

Node rightNode = node.getRight();

node.setRight(rightNode.getLeft());

if (rightNode.getLeft() != NIL) {

rightNode.getLeft().setParent(node);

}

rightNode.setParent(node.getParent());

if (node.getParent() == NIL) {

rightNode = root;

} else if (node == node.getParent().getLeft()) {

node.getParent().setLeft(rightNode);

} else {

node.getParent().setRight(rightNode);

}

rightNode.setLeft(node);

node.setParent(rightNode);

}

//右转函数

private void rightRotate(Node node) {

Node leftNode = node.getLeft();

node.setLeft(leftNode.getRight());

if (leftNode.getRight() != null) {

leftNode.getRight().setParent(node);

}

leftNode.setParent(node.getParent());

if (node.getParent() == NIL) {

root = leftNode;

} else if (node == node.getParent().getLeft()) {

node.getParent().setLeft(leftNode);

} else {

node.getParent().setRight(leftNode);

}

leftNode.setRight(node);

node.setParent(leftNode);

}

//中序遍历红黑树

public void printTree() {

inOrderTraverse(root);

}

private void inOrderTraverse(Node node) {

if (node != NIL) {

inOrderTraverse(node.getLeft());

System.out.println(" 节点:"+node.getValue() + "的颜色为:" + node.getColor());

inOrderTraverse(node.getRight());

}

}

public Node getNIL() {

return NIL;

}

}

节点:

class Node {

private Node left;

private Node right;

private Node parent;

private Color color;

private int value;

public Node(Node left, Node right, Node parent, Color color, int value) {

super();

this.left = left;

this.right = right;

this.parent = parent;

this.color = color;

this.value = value;

}

public Node() {

}

public Node(int value) {

this(null,null,null,null,value);

}

public Node getLeft() {

return left;

}

public void setLeft(Node left) {

this.left = left;

}

public Node getRight() {

return right;

}

public void setRight(Node right) {

this.right = right;

}

public Node getParent() {

return parent;

}

public void setParent(Node parent) {

this.parent = parent;

}

public Color getColor() {

return color;

}

public void setColor(Color color) {

this.color = color;

}

public int getValue() {

return value;

}

public void setValue(int value) {

this.value = value;

}

}

enum Color {

RED,BLACK

}

测试:

public class RBTreeTest {

/**

* @param args

*/

public static void main(String[] args) {

RBTree rbTree = new RBTree();

rbTree.rbInsert(new Node(41));

rbTree.rbInsert(new Node(38));

rbTree.rbInsert(new Node(31));

rbTree.rbInsert(new Node(12));

rbTree.rbInsert(new Node(19));

rbTree.rbInsert(new Node(8));

//rbTree.printTree();

rbTree.rbDelete(19);

rbTree.printTree();

}

}

时间: 2024-10-07 03:52:22

研磨数据结构与算法-14红黑树的相关文章

Java数据结构和算法(八)--红黑树与2-3树

红黑树规则: 1.根节点与叶节点都是黑色节点 2.每个红色节点的两个子节点都是黑色节点,反之,不做要求,换句话说就是不能有连续两个红色节点 3.从根节点到所有叶子节点上的黑色节点数量是相同的 一般对红黑树的讲述都是先给出这样的定义,这样想对不太容易理解的,而在算法4一书中,直接跳过这些规则,而讲述了红黑树与2-3树的等价性 如果我们先了解2-3树,理解了红黑树与2-3树之间的关系,回过头就会发现红黑树不难 2-3树: 2-3树满足二分搜索树的基本性质,但是不是二叉树 2-3树节点可以存放一个元素

数据结构与算法简记--红黑树

红黑树 平衡二叉树 定义:二叉树中任意一个节点的左右子树的高度相差不能大于 1. 完全二叉树.满二叉树其实都是平衡二叉树,非完全二叉树也有可能是平衡二叉树. 平衡二叉查找树 任何节点的左右子树高度相差不超过 1,是一种高度平衡的二叉查找树. 符合二叉查找树的特点:左子节点小于父节点,右子节点大于父节点. 发明的初衷是:解决普通二叉查找树在频繁的插入.删除等动态更新的情况下,出现时间复杂度退化的问题. “平衡”的意思,其实就是让整棵树左右看起来比较“对称”.比较“平衡”,不要出现左子树很高.右子树

算法之红黑树

红黑树(一) 原理和算法详细介 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年写的一篇论文中获得的. 红黑树本质上是一种二叉查找树,但它在二叉查找树的基础上额外添加了一个标记(颜色),同时具有一定的规则.这些规则使红黑树保证了一种平衡,插入.删除.查找的最坏时

算法导论—红黑树

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

【C/C++学院】0828-STL入门与简介/STL容器概念/容器迭代器仿函数算法STL概念例子/栈队列双端队列优先队列/数据结构堆的概念/红黑树容器

STL入门与简介 #include<iostream> #include <vector>//容器 #include<array>//数组 #include <algorithm>//算法 using namespace std; //实现一个类模板,专门实现打印的功能 template<class T> //类模板实现了方法 class myvectorprint { public: void operator ()(const T &

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

学习算法 还是建议看看算法导论 算法导论第三版 如果不看数学推导 仅看伪代码 难度还是适中 本系列只是记录我的学习心得 和伪代码转化代码的过程 深入学习 还是建议大家看看算法书籍 教程更加系统. 本文参考算法导论第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章节 红黑树 代码由本人写成 转载请标明出处 先看看不做