红黑树的插入Java实现
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实现的更多相关文章
- 红黑树(五)之 Java的实现
概要 前面分别介绍红黑树的理论知识.红黑树的C语言和C++的实现.本章介绍红黑树的Java实现,若读者对红黑树的理论知识不熟悉,建立先学习红黑树的理论知识,再来学习本章.还是那句老话,红黑树的C/C+ ...
- JDK1.8 HashMap$TreeNode.balanceInsertion 红黑树平衡插入
红黑树介绍 1.节点是红色或黑色. 2.根节点是黑色. 3.每个叶子节点都是黑色的空节点(NIL节点). 4 每个红色节点的两个子节点都是黑色.(从每个叶子到根的所有路径上不能有两个连续的红色节点) ...
- 高级数据结构---红黑树及其插入左旋右旋代码java实现
前面我们说到的二叉查找树,可以看到根结点是初始化之后就是固定了的,后续插入的数如果都比它大,或者都比它小,那么这个时候它就退化成了链表了,查询的时间复杂度就变成了O(n),而不是理想中O(logn), ...
- 第八章 高级搜索树 (xa3)红黑树:插入
- 红黑树插入操作原理及java实现
红黑树是一种二叉平衡查找树,每个结点上有一个存储位来表示结点的颜色,可以是RED或BLACK.红黑树具有以下性质: (1) 每个结点是红色或是黑色 (2) 根结点是黑色的 (3) 如果一个结点是红色的 ...
- 从2-3-4树到红黑树(下) Java与C的实现
欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 相关博客: 从2-3-4树到红黑树(上) 从2-3-4树到红黑树(中) 1. 实现技 ...
- Java红黑树详谈
定义 红黑树的主要是想对2-3查找树进行编码,尤其是对2-3查找树中的3-nodes节点添加额外的信息.红黑树中将节点之间的链接分为两种不同类型,红色链接,他用来链接两个2-nodes节点来表示一个3 ...
- 【深入理解Java集合框架】红黑树讲解(上)
来源:史上最清晰的红黑树讲解(上) - CarpenterLee 作者:CarpenterLee(转载已获得作者许可,如需转载请与原作者联系) 文中所有图片点击之后均可查看大图! 史上最清晰的红黑树讲 ...
- 红黑树深入剖析及Java实现
红黑树是平衡二叉查找树的一种.为了深入理解红黑树,我们需要从二叉查找树开始讲起. BST 二叉查找树(Binary Search Tree,简称BST)是一棵二叉树,它的左子节点的值比父节点的值要小, ...
随机推荐
- JavaSE中线程与并行API框架学习笔记——线程为什么会不安全?
前言:休整一个多月之后,终于开始投简历了.这段时间休息了一阵子,又病了几天,真正用来复习准备的时间其实并不多.说实话,心里不是非常有底气. 这可能是学生时代遗留的思维惯性--总想着做好万全准备才去做事 ...
- struts2上传文件类型列表
'.a' : 'application/octet-stream', '.ai' : 'application/postscript', '.aif' ...
- [bzoj4832]抵制克苏恩 概率dp
考试的时候打了个搜索,时间比较短,样例又非常的弱,实在不太清楚他这个到底是什么意思. 不过lc大神好腻害,讲解了一下非常的清楚了. f[i][j][k][l]表示第i次伤害(啊),一滴血j个,两滴血k ...
- 媒体查询Media Queries详解
@media 标签可以说是响应式网页的开发基础.其主要由媒体类型(Media Type)和 媒体特性(Media Query)两部分组成. Media Type 设定后面规则生效的展示类型,包括all ...
- 【社交系统研发日记】如何在 Laravel 中 “规范” 的开发验证码发送功能
顺便发个小通知:7月15日ThinkSNS+开源版发布,同时非开源的APP也走出内测阶段,体验二维码也全面发布体验. 什么是ThinkSNS ? ThinkSNS(简称TS),一款全平台综合性社交系统 ...
- 【LeetCode】数组-1(643)-返回规定长度k的最大子数组的平均数
好久没有刷LeetCode了,准备重拾并坚持下去,每天刷个两小时.今天算是开始的第一天,不过出师不利,在一道很简单的题目上墨迹半天.不过还好,现在踩过的坑,应该都不会白踩,这些可能都是以后程序员路上稳 ...
- TCP和UDP的区别(Socket)
TCP和UDP区别 TCP和UDP编程区别 TCP编程的服务器端一般步骤是: 1.创建一个socket,用函数socket(): 2.设置socket属性,用函数setsockopt(); * 可 ...
- Javacript的变量和输出
一.js使用的三种方式 1.在HTML标签中,直接内嵌js(并不提倡使用): >>不符合W3C内容与表现分离的要求!!! 2.在HTML页面中使用<script></sc ...
- 你不可错过的二维码生成与解析-java后台与前端js都有
1.二维码分类 二维条码也有许多不同的码制,就码制的编码原理而言,通常分为三种类型. 线性堆叠式二维码 编码原理: 建立在一维条码基础之上,按需要堆积成两行或多行. 图示: 矩阵式二维码 最常用编 ...
- JavaScript之获取节点
JavaScriopt DOM有三大节点:元素节点.属性节点.文本节点. 其中获取元素节点的三种主要方法有: 1.document.getElementById();此方法根据节点的唯一id值获取节点 ...