package practice;

public class TestMain {
public static void main(String[] args) {
int[] ao = {5, 1, 18, 3, 8, 20, 13, 16, 12};
Integer[] a = new Integer[9];
for (int i = 0; i < a.length; i++) {
a[i] = new Integer(ao[i]);
}
RedBlackBST<Integer,String> tree= new RedBlackBST<Integer,String>();
for (int i = 0; i < a.length; i++) {
tree.put(a[i], a[i].toString());
} tree.print();
}
}
/*
 * 红黑树
 * 与2-3树比较,红链接即表示像2-3树中的3-节点4-节点一样在"同一位置"(将红链接画平)
 */
class RedBlackBST <K extends Comparable<K>, V> {
private static final boolean RED = true;
private static final boolean BLACK = false; private Node root; private class Node{
K key;
V value;
Node left, right;
int N;
boolean color; public Node(K key, V value, int N, boolean color) {
this.key = key;
this.value = value;
this.N = N;
this.color = color;
}
}
/*
* 插入节点
*/
public void put(K key, V value) {
root = put(root, key, value);
}
private Node put(Node node, K key, V value) {
if (node == null) { return new Node(key, value, 1, RED);}
/*
* 前面部分与二叉树插入一致,红黑树就是像二叉树一样插入后进行调整(旋转,颜色转换)
*/
if (compare(key, node.key) < 0) { node.left = put(node.left, key, value);}
else if (compare(key, node.key) > 0) { node.right = put(node.right, key, value);}
else { node.value = value;}
/*
   * 这里的旋转就是为了保证"同一位置"(即一个节点有两条红链接)的三个节点由从小到大排序且中间的节点连着他们的父节点
   * 颜色转换即是2-3树中的"向上增长"
   */
if (!isRed(node.left)&&isRed(node.right)) { node = rorateLeft(node);} //左旋
if (isRed(node.left)&&isRed(node.left.left)) { node = rorateRight(node);} //右旋
if (isRed(node.left)&&isRed(node.right)) { flipColors(node);} //颜色转换 node.N = size(node.left) + size(node.right) + 1;
return node;
}
/*
* 节点左旋 父节点为dad 红节点为son(dad为动图中的E son为图中的S)
* 当右子节点是红色而左子节点是黑色,就以本节点为dad,右子节点为son进行左旋
*/
private Node rorateLeft(Node dad) {
Node son = dad.right;
dad.right = son.left;
son.left = dad;
son.color = dad.color;
dad.color = RED;
son.N = dad.N;
dad.N = size(dad.left) + size(dad.right) +1;
return son;
}
/*
* 节点右旋 父节点为dad 红节点为son
* 当左子节点是红色且它的左子节点也是红色,就以本节点为dad,左子节点为son进行右旋
*/
private Node rorateRight(Node dad) {
Node son = dad.left;
dad.left = son.right;
son.right = dad;
son.color = dad.color;
dad.color = RED;
son.N = dad.N;
dad.N = size(dad.left) + size(dad.right) +1;
return son;
}
/*
* 颜色转换
* 如果这个节点的左右子节点都为红色,就把他们都变为黑色,然后把自己变成红色
*/
private void flipColors(Node node) {
node.color = RED;
node.left.color = BLACK;
node.right.color =BLACK;
}
/*
* 是否为红
*/
private boolean isRed(Node node) {
if (node == null) { return false;}
return node.color == RED;
}
/*
* 树的大小
*/
private int size(Node node) {
if (node == null) { return 0;}
else { return node.N;}
}
/*
* key1 < key2 -1
* key1 > key2 1
* key1 == key2 0
*/
private int compare(K key1, K key2) {
return key1.compareTo(key2);
}
public void print() {
print(root);
}
private void print(Node node) {
if (node == null) {
return;
}
print(node.left);
System.out.println("key = "+node.key+" node.N = "+node.N);
print(node.right);
} }

插入图示(S,E,A,R,C,H,X,M,P对应5,1,18,3,8,20,13,16)

左旋转

右旋转

颜色转换

红黑树的插入Java实现的更多相关文章

  1. 红黑树(五)之 Java的实现

    概要 前面分别介绍红黑树的理论知识.红黑树的C语言和C++的实现.本章介绍红黑树的Java实现,若读者对红黑树的理论知识不熟悉,建立先学习红黑树的理论知识,再来学习本章.还是那句老话,红黑树的C/C+ ...

  2. JDK1.8 HashMap$TreeNode.balanceInsertion 红黑树平衡插入

    红黑树介绍 1.节点是红色或黑色. 2.根节点是黑色. 3.每个叶子节点都是黑色的空节点(NIL节点). 4 每个红色节点的两个子节点都是黑色.(从每个叶子到根的所有路径上不能有两个连续的红色节点) ...

  3. 高级数据结构---红黑树及其插入左旋右旋代码java实现

    前面我们说到的二叉查找树,可以看到根结点是初始化之后就是固定了的,后续插入的数如果都比它大,或者都比它小,那么这个时候它就退化成了链表了,查询的时间复杂度就变成了O(n),而不是理想中O(logn), ...

  4. 第八章 高级搜索树 (xa3)红黑树:插入

  5. 红黑树插入操作原理及java实现

    红黑树是一种二叉平衡查找树,每个结点上有一个存储位来表示结点的颜色,可以是RED或BLACK.红黑树具有以下性质: (1) 每个结点是红色或是黑色 (2) 根结点是黑色的 (3) 如果一个结点是红色的 ...

  6. 从2-3-4树到红黑树(下) Java与C的实现

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处   http://www.cnblogs.com/nullzx/ 相关博客: 从2-3-4树到红黑树(上) 从2-3-4树到红黑树(中) 1. 实现技 ...

  7. Java红黑树详谈

    定义 红黑树的主要是想对2-3查找树进行编码,尤其是对2-3查找树中的3-nodes节点添加额外的信息.红黑树中将节点之间的链接分为两种不同类型,红色链接,他用来链接两个2-nodes节点来表示一个3 ...

  8. 【深入理解Java集合框架】红黑树讲解(上)

    来源:史上最清晰的红黑树讲解(上) - CarpenterLee 作者:CarpenterLee(转载已获得作者许可,如需转载请与原作者联系) 文中所有图片点击之后均可查看大图! 史上最清晰的红黑树讲 ...

  9. 红黑树深入剖析及Java实现

    红黑树是平衡二叉查找树的一种.为了深入理解红黑树,我们需要从二叉查找树开始讲起. BST 二叉查找树(Binary Search Tree,简称BST)是一棵二叉树,它的左子节点的值比父节点的值要小, ...

随机推荐

  1. Redis作为消息队列服务场景应用案例(入队和出队)

    http://www.cnblogs.com/leo_wl/p/3831349.html

  2. 解决 CefSharp WPF控件不能使用输入法输入中文的问题(代码已提交到 github)

    首先,本文所有 代码已经提交到github,需要的可以直接从github获取:https://github.com/starts2000/CefSharp,希望可以帮助到有需要的朋友们. CEF 简介 ...

  3. LigerUI LigerGrid getSelectedRows() 多选顺序 不是从上到下修改方法

    1.问题 LigreGrid内部是选中一个,往selected里塞一个, 当执行getSelectedRows() 的时候,会把selected以选中的顺序,返回出来,所以是按照选择顺序返回. 原生代 ...

  4. Python基础学习 -- 列表与元组

    本节学习目的: 掌握数据结构中的列表和元组 应用场景: 编程 = 算法 + 数据结构 数据结构: 通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些元素可以是数字或者字符,或者其他数据 ...

  5. [dubbo实战] dubbo+zookeeper伪集群搭建

    zookeeper作为注册中心,服务器和客户端都要访问,如果有大量的并发,肯定会有等待.所以可以通过zookeeper集群解决. 一.为什么需要zookeeper呢? 大部分分布式应用需要一个主控.协 ...

  6. 小兴趣:修改Hosts文件,禁止访问指定网页

    不知道Hosts文件什么鬼的朋友可以在网上搜索一下(大牛勿喷- -) 访问网址时,先查询本地的Hosts文件,那么如果我们将Hosts文件中的网址与IP的映射修改之后,将访问错误的IP. 如在文件尾追 ...

  7. 【NO.2】Jmeter-安装Jmeter - 在Linux环境安装Jmeter - 在Windows环境安装Jmeter

    当配置完Jmeter运行的环境之后,就可以开始安装Jmeter了. 为什么既要告诉各位"在Linux系统内安装Jmeter",又要告诉各位"在Windows系统内安装Jmeter"?因为当我们在构建1 ...

  8. 阅读:DBA们不得不知的数据库硬件RAID常识

    对于数据库这种特殊应用IOPS往往会成为瓶颈,突破的这个瓶颈的有效方法不多,软件方面主要是读写分离,垂直拆分,分区表技术,cluster.硬件方面主要是raid,和SSD. 通常都是软件和硬件同时优化 ...

  9. OS作业模拟SJF和FCFS

    一个OS的作业, 用于模拟短作业优先 和 先来先服务两种作业调度方式. #!/usr/bin/python3.5 ## Modify the SJF and FCFS algorithm in the ...

  10. MySQL中的数据类型及创建

    MySQL创建: 1.创建数据库create database test2; 2.删除数据库drop database test2;3.创建表create table ceshi(    ids in ...