红黑树的插入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)是一棵二叉树,它的左子节点的值比父节点的值要小, ...
随机推荐
- ubuntu上安装nginx+mysql+php5-fpm(PHP5 - FastCGI Process Manager)
题外话:由于近段时间测试环境ssh链路质量不大好,经常短线.故我把整个安装过程放到screen里去执行,以防止断线中断了安装过程.执行screen -S install,这样断线后,只要再执行scre ...
- RequireJs加载Codemirror,配合AngularJS的坑
requireJS加载codemirror,并且配合angularJs一起使用的时候,高亮显示代码编辑器.要注意以下几点: 1:普通Js加载CodeMirror 代码如下: <!DOCTYPE ...
- Android学习笔记-TextView(文本框)(一)
1.基础属性详解: id:为TextView设置一个组件id,根据id,我们可以在Java代码中通过findViewById()的方法获取到该对象,然后进行相关属性的设置,又或者使用RelativeL ...
- Go的基本环境配置
参考 https://golang.org/doc/install?download=go1.7.1.linux-amd64.tar.gz https://github.com/qlshine/the ...
- S2-032代码执行
Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架.其全新的Struts 2的体系结构与Struts 1的体系结构差别 ...
- AndroidTv开发中常用的adb命令
盒子应用开发时,调试比手机上的开发比较麻烦一点,而且需要经常跟 adb 打交道,不管是 wifi 连接调试,还是应用删除安装等.这里记录一些常用的操作,方便查阅. adb wifi连接调试 方法一:需 ...
- 虚拟机安装linux系统不能上网解决方法
周末闲来无事,用虚拟机安装了centos6.5系统,安装成功后发现不能连接网络,然后我就一脸蒙蔽了,无奈之下,只能百度查找问题,幸运的是,我还真找到了解决的方法,根据教程一步步操作,成功了!为了避免以 ...
- python之禅 the zen of python
>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is ...
- nodejs 文件读取一行
作者QQ:1095737364 QQ群:123300273 欢迎加入! 废话没有,直接上代码: app.get('/company', function (req, res, nex ...
- 友盟崩溃日志分析工具 - dSYMTools
公司的项目中集成了UM的统计功能,UM统计可以统计app的用户新增,版本分布,日志崩溃等信息,打开错误分析按钮,则可能会看到很多崩溃的日志信息 选择编辑可以选择更多的版本号 点击列表中的一个崩溃日志, ...