赞
踩
上面一篇介绍了红黑树的概念、特征和时间复杂度,这里我们进一步讲解红黑树的基础操作和Java代码实现。
数据结构基本操作添加、修改、删除、查询,红黑树做为一种特殊的二叉查找树,其查找和修改同二叉查找树;但是添加、删除和二叉查找树有很大区别。
道理很简单,添加或删除红黑树中的节点之后,红黑树就发生了变化,可能不满足红黑树的5条性质,也就不再是一颗红黑树了,而是一颗普通的树。而通过旋转,可以使这颗树重新成为红黑树。简单点说,旋转的目的是让树保持红黑树的特性。
所有Java代码基本参照HashMap TreeNode完成。
红黑树作为一种数据结构,基本功能-存储数据;作为二叉树,有左右子树(节点);具有自己独特的特点,每个节点都有颜色;为了方便查找某个节点的父级节点,用一个指针指向它 的父节点;
static final class RBNode<K, V> { final K key; // 关键字 V value; // 数据 boolean red; // 是否是红色 private RBNode<K, V> parent; // 父节点指针 private RBNode<K, V> left; // 左子节点指针 private RBNode<K, V> right; // 右子节点指针 // 构造函数 public RBNode(K key, V value, boolean red, RBNode<K, V> parent, RBNode<K, V> left, RBNode<K, V> right) { this.key = key; this.value = value; this.red = red; this.parent = parent; this.left = left; this.right = right; } /** * 以当前节点起始,查找根节点 */ final RBNode<K,V> root() { for (RBNode<K,V> r = this, p;;) { if ((p = r.parent) == null) return r; r = p; } } }
要查看红黑树,需要有一个切入点,就是红黑树的根节点;想要指定存储了几个元素,需要size变量。
完整代码在最后仓库地址。
因为上面我设计用布尔值存储节点的颜色信息,这个很容易实现,通过设置true,节点为红色;false,节点为黑色。
图示:
旋转过程图示:
步骤
// 左旋 static <K, V> RBNode<K, V> rotateLeft(RBNode<K, V> root, RBNode<K, V> p) { RBNode<K, V> r, pp, rl; if (p != null && (r = p.right) != null) { if ((rl = p.right = r.left) != null) rl.parent = p; if ((pp = r.parent = p.parent) == null) (root = r).red = false; else if (pp.left == p) pp.left = r; else pp.right = r; r.left = p; p.parent = r; } return root; }
旋转过程图示:
步骤
// 右旋 static <K, V> RBNode<K, V> rotateRight(RBNode<K, V> root, RBNode<K, V> p) { RBNode<K, V> l, pp, lr; if (p != null && (l = p.left) != null) { if ((lr = p.left = l.right) != null) lr.parent = p; if ((pp = l.parent = p.parent) == null) (root = l).red = false; else if (pp.left == p) pp.left = l; else pp.right = l; l.right = p; p.parent = l; } return root; }
欢迎交流,本人QQ:806797785
项目源代码地址:https://gitee.com/gaogzhen/algorithm.git
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。