红黑树的插入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)是一棵二叉树,它的左子节点的值比父节点的值要小, ...
随机推荐
- 感知器算法--python实现
写在前面: 参考: 1 <统计学习方法>第二章感知机[感知机的概念.误分类的判断] http://pan.baidu.com/s/1hrTscza 2 点到面的距离 3 梯度 ...
- get post请求
GET 从指定的资源请求数据 /test/demo_form.asp?name1=value1&name2=value2 请求可被缓存 请求保留在浏览器历史记录中 请求可被收藏为书签 请求不应 ...
- JS正则密码复杂度校验之:至少有多种字符中的其中几种
概述 续接上文的密码校验要求: 这个需求有两个难点,一,是如何使用正则匹配所有半角英文标点符号,二,是如何验证密码段中在要求的四种(大写字母,小写字母,数字,标点符号)类型中至少存在三种. 第一个难点 ...
- Kotlin 初窥门径[1]:基础概念
Kotlin 是由 JetBrains 开发的基于JVM的语言.JetBrains 因为创造了一个强大的Java开发 IDE(Intellij) 而被大家所熟知.Android Studio 就是基于 ...
- Mac OS X下安装和配置Maven
1.下载Maven 打开Maven官网下载页面:http://maven.apache.org/download.cgi 下载:apache-maven-3.5.0-bin.tar.gz 解压下载的安 ...
- 【LeetCode】数组-1(643)-返回规定长度k的最大子数组的平均数
好久没有刷LeetCode了,准备重拾并坚持下去,每天刷个两小时.今天算是开始的第一天,不过出师不利,在一道很简单的题目上墨迹半天.不过还好,现在踩过的坑,应该都不会白踩,这些可能都是以后程序员路上稳 ...
- 01-artDialog4.1.7常用整理
关闭弹出框的几种常见方法: 1,artDialog可以通过鼠标双击关闭对话框,esc关闭对话框等.为了在关闭对话框要执行某一方法,不能仅仅在弹框中的关闭按钮中写.这时提供了一个函数:close.无论在 ...
- QtWebKit/QtWebEngine移植差异(网摘)
QtWebKit/QtWebEngine移植差异 原文出处:[wiki.qt.io] This guide gives an overview of the differences between t ...
- Mac实用操作技巧(四)
在文档编辑状态下更改文件名.保存位置 在编辑文档的时候,有时候想随时更改文件名或者更改文件的保存位置.通常情况下,比如Windows环境中,想要更改文件名,首先需要关闭文档,否则不能修改:想要更改文档 ...
- JMeter之Throughput Controller详解(实验)
Throughput Contoller,直译是吞吐量控制器,它是用来控制该控制器下面元件的执行次数,与控制吞吐量的功能无关.(注:用Constant Throughput Timer可以控制吞吐量. ...