当前位置: 首页 > news >正文

工作室暴利项目南京网站优化方案

工作室暴利项目,南京网站优化方案,网站搭建制作公司,西宁 网站建设#x1f525;博客主页#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞#x1f44d;收藏⭐评论✍ 文章目录 1.0 红黑树的说明 2.0 红黑树的特性 3.0 红黑树的成员变量及其构造方法 4.0 实现红黑树的核心方法 4.1 红黑树内部类的核心方法 #xff08;1#xff09;判断当前…  博客主页 【小扳_-CSDN博客】 ❤感谢大家点赞收藏⭐评论✍   文章目录 1.0 红黑树的说明 2.0 红黑树的特性 3.0 红黑树的成员变量及其构造方法 4.0 实现红黑树的核心方法 4.1 红黑树内部类的核心方法 1判断当前节点是否为左孩子节点 - isLeftChild( 2获取叔叔节点 - uncle() 3获取兄弟节点 - brother() 4.2 红黑树外部类的核心方法 1判断是否为红色节点 isRed - (TreeNode node) 2判断是否为黑色节点 isBlack - (TreeNode node) 3右旋 - rightRotate(TreeNode node) 4左旋 - leftRotate(TreeNode node) 5更新、添加节点 - put(int keyObject value) 6删除节点 - remove(int key) 5.0 实现红黑树核心方法的完整代码 1.0 红黑树的说明 红黑树是一种自平衡的二叉搜索树它在每个节点上增加了一个存储位来表示节点的颜色可以是红色或黑色。 与 AVL 树相比之下红黑树放宽了对平衡的要求通过牺牲一定的平衡性能来换取更高的插入、删除和查找操作的性能。红黑树的旋转操作相对较少因此在实际应用中红黑树更常用于需要高效的动态数据结构如集合、映射等。而 AVL 树则更适用于对平衡性要求较高的场景如数据库索引等。 总的来说红黑树也是一种自平衡的二叉搜索树较之 AVL 树插入和删除时旋转次数更少。 2.0 红黑树的特性 - 所有节点都有两种颜色红与黑 - 所有 null 视为黑色 - 红色节点不能相邻 - 根节点是黑色 - 从根节点到任意一个叶子节点路径中的黑色节点数一样黑色完美平衡 前四个规则都很容易理解接下来详细说明一下最后一个规则到底什么是从根节点到叶子节点的所有路径都要保证黑色节点数一样 如图 1         从根节点出发到叶子节点首先从左子树方向开始6 - 2 - 1 - null 这一条路径的黑色节点一共有 3 个现在从左子树方向出发6 - 2 - null 这一条路径的黑色节点一共有 3 个现在从右子树方向开始6 - 8 - null 这一条路径的黑色节点一共也是有 3 个黑色节点这几条路径的黑色节点都为 3 。因此满足红黑树的最后一条规则。 如图 2         同理从根节点出发到叶子节点先从左子树方向开始6 - 2 - 1 - null 这一条路径的黑色节点一共有三个再从 6 - 2 - null 但是这一条路径的黑色节点只有 2 个黑色节点不满足红黑树的最后一个规则。 在构建红黑树需要满足以上规则无论插入、删除等都要满足红黑树的特性。 3.0 红黑树的成员变量及其构造方法 节点类 TreeNode 作为内部类该内部类的成员变量有 int key : 关键字用于比较大小 Object value : 值 TreeNode left : 左节点 TreeNode right : 右节点 Color color 颜色默认设置为红色 TreeNode parent 该节点的父亲节点 该内部类的构造方法 节点类的构造方法主要是参数为 (int key, Object value) 的构造方法 红黑树的外部类的成员变量主要为 TreeNode root 根节点一般默认为 null   红黑树的外部类的构造方法 主要采取默认的参数为 null 的构造方法 代码如下 import static TreeNode.RedBlackTree.Color.BLACK; import static TreeNode.RedBlackTree.Color.RED;public class RedBlackTree {enum Color {RED,BLACK;}private TreeNode root;private static class TreeNode {int key;Object value;TreeNode left;TreeNode right;TreeNode parent;Color color RED;//构造方法public TreeNode(int key, Object value) {this.key key;this.value value;}} 4.0 实现红黑树的核心方法 为了更好的实现插入、删除等方法需要先实现基础的方法 打好基础。主要分为实现内部类与外部类的核心方法。 4.1 红黑树内部类的核心方法 1判断当前节点是否为左孩子节点 - isLeftChild( 实现思路为先判断该父亲节点是否为 null 若 parent null 时则当前节点为根节点若 parent ! null 则需要继续判断 this parent.left 若满足则说明当前节点为左孩子节点若不满足则说明当前节点为右孩子节点。 代码如下 //判断是否为左孩子public boolean isLeftChild() {return parent ! null parent.left this;} 2获取叔叔节点 - uncle() 叔叔节点即为跟父亲节点的同一辈的节点跟父亲节点的父亲是同一个父亲。 实现思路为需要先判断该爷爷节点是否为 null 与 父亲节点是否为 null 因为该两种情况都不具备叔叔节点。若以上情况都不为 null 时接着还需要判断当前节点的父亲节点的位置若父亲节点为左孩子则叔叔节点为右孩子若父亲节点为右孩子则叔叔节点为左孩子。 代码如下 //获取叔叔节点public TreeNode uncle() {if (this.parent null || this.parent.parent null) {return null;}if (this.isLeftChild()) {return this.parent.parent.right;} else {return this.parent.parent.left;}} 3获取兄弟节点 - brother() 跟当前节点是同一辈的节点同一个父亲节点。 实现思路为先判断当前节点的父亲节点是否为 null 若 parent null 时说明该节点不存在兄弟节点若 parent ! null 时说明该节点存在兄弟节点然后继续判断当前节点的位置若当前节点为左孩子则兄弟节点为parent.right 若当前节点为右孩子则兄弟节点为parent.left 。 代码如下 //获取兄弟节点public TreeNode brother() {if (this.parent null) {return null;}if (this.isLeftChild()) {return this.parent.right;}else {return this.parent.left;}} 4.2 红黑树外部类的核心方法 1判断是否为红色节点 isRed - (TreeNode node) 实现思路为根据红黑的规则可以知道除了根节点与 null 之外 当前节点的 color RED 时则该节点为红色节点。 代码如下 //判断是否为红色节点private boolean isRed(TreeNode node) {return node ! null node.color RED;} 2判断是否为黑色节点 isBlack - (TreeNode node) 实现思路为有两种情况下 null 或者 color BLACK 的节点为黑色节点。 代码如下 //判断是否为黑色节点private boolean isBlack(TreeNode node) {return node null || node.color BLACK;} 3右旋 - rightRotate(TreeNode node) 实现思路为跟 AVL 树的右旋会有一定的区别因为新添加了 parent 成员所以正常右旋完之后需要维护 parent 变量。 1. parent 的处理 2. 旋转后新根的父子关系 如图         现需要将节点 8 进行右旋假设节点 8 为 node 那么先记录节点5、节点6nodeLeft node.left、nodeLeftRight nodeLeft.right 。接着更新节点 5 的右孩子将其更新为节点 8 作为右孩子。还需要更新节点 8 的左孩子 将其更新为节点 6 作为左孩子。从表面上已经完成右旋但还需要维护节点的父亲节点 parent 。对于节点 6 来说之前的父亲节点为节点 5 现在需要更新父亲节点为节点8不过需要先判断节点 6 是否为 null 若节点 6 为 null 则不需要更新父亲节点的操作。若节点 6 不为 null则需要更新父亲节点这一操作。对于节点 5 来说节点 5 的父亲节点之前为节点 8先父亲节点更新为节点 8 的父亲节点因此还需要记录节点 8 的父亲节点。对于节点 8 来说将其父亲节点更新为节点 5 。最后由于现在的节点与节点之间时双互的所以还需要维护新根的父子关系不过需要判断节点 8 的父亲节点是否为 null 若为 parent null 时则说明节点 5 为根节点因此需要进行 root node.left 调整若 parent ! null 需要判断 node 的位置若 node 是左孩子那么 parent.left node.left 进行链接若 node 是右孩子那么 parent.right node.left 进行链接。那么现在就可以根据这个逻辑写代码了。 最后调整完之后的图 代码如下 //右旋//1.考虑旋转后节点的维护parent 2.重新与上一个节点建立联系private void rightRotate(TreeNode node) {TreeNode parent node.parent;TreeNode nodeLeft node.left;TreeNode nodeLeftRight nodeLeft.right;if (nodeLeftRight ! null) {nodeLeftRight.parent node;}nodeLeft.right node;nodeLeft.parent parent;node.left nodeLeftRight;node.parent nodeLeft;if (parent null) {root nodeLeft;} else if (parent.left node) {parent.left nodeLeft;}else {parent.right nodeLeft;}} 4左旋 - leftRotate(TreeNode node) 跟右旋的逻辑是一摸一样的这里就不多赘述了。 代码如下 //左旋//1.考虑旋转后节点的维护parent 2.重新与上一个节点建立联系private void leftRotate(TreeNode node) {TreeNode parent node.parent;TreeNode nodeRight node.right;TreeNode nodeRightLeft nodeRight.left;if (nodeRightLeft ! null) {nodeRightLeft.parent node;}nodeRight.left node;nodeRight.parent parent;node.right nodeRightLeft;node.parent nodeRight;//2.重新与上一个节点建立联系if (parent null) {root nodeRight;} else if (parent.left node) {parent.left nodeRight;}else {parent.right nodeRight;}} 5更新、添加节点 - put(int keyObject value) 实现思路为正常删除节点、更新节点若遇到红红节点不平衡则需要进行调整 对于正常删除、更新节点的逻辑为根据 key 来寻找需要更新或者删除的节点、若找到了 key 的节点那么直接更新该节点的 value 即可若没有找到 key 的节点需要进行添加节点。需要用到 parent 变量记录每一次的当前节点一旦当前节点为 node null 时找到了相应的空位接着判断 key 与 parent.key 的大小。若 parent.key key 则 parent.left node;若 parent.key key 则 parent.right node;若 parent null 时说明该红黑树为空树所以 root node 。最后对于更新来说不会改变红黑树的平衡关系对于添加完节点很有可能会改变红黑树的平衡关系所以需要进行红红修复。 接下来详细聊一下红红节点不平衡后进行的调整 插入节点均视为红色 - case 1插入节点为根节点将根节点变为黑色 - case 2插入节点的父亲若为黑色树的红黑性质不变无需调整 插入节点的父亲节点为红色触发红红相邻 - case3叔叔为红色 将父亲节点变为黑色为了保证黑色平衡连带的叔叔也变为黑色祖父如果是黑色不变色会造成这颗子树黑色过多因此祖父节点变为红色。但是祖父变为红色可能也会继续触发红红相邻因此对讲祖父进行递归调整。 如图 对于 case 3 详细说明                          插入节点为节点 1 设为 node 该父亲节点为节点 2 设为 parent 。对于 node 节点来说遇到了红红不平衡的情况且该节点 4 即为叔叔节点为红色。         调整红黑树平衡需要将父亲节点、叔叔节点的颜色都要置为黑色parent.color BLACKuncle.color BALCK 将节点 3 即祖父节点的颜色置为红色parent.parent.color RED 。可以发现节点 3 与节点 5 又再一次出现了触发了红红相邻了那么利用递归来解决这一情况一旦遇到 node root 时即可停止递归了。 最后调整后之后的图 - case 4叔叔为黑色 1. 父亲为左孩子插入节点也是左孩子此时即 LL 不平衡 2. 父亲为左孩子插入节点是右孩子此时即 LR 不平衡 3. 父亲为右孩子插入节点也是右孩子此时即 RR 不平衡 4. 父亲为右孩子插入节点是左孩子此时即 RL 不平衡 如图对于 case 4 中  LL 不平衡的详细说明                          插入节点为节点 2 设为 node父亲节点为节点 3 设为 parent 该叔叔节点为 null 该节点为黑色又满足 node 为左孩子parent 也为左孩子 LL 不平衡。该调整需要将 parent.color BLACKparent.parent.color RED把爷爷节点 rightRotate(parent.parent) 右旋一次即可。 调整完之后的图为 如图对于 case 4 中 LR 不平衡的详细说明                插入节点为节点 4 设为 node父亲节点为节点 3 设为 parentnode 的叔叔节点为 null 所以该颜色为黑色。又 parent 是左孩子node 是右孩子满足 LR 不平衡。 需要做的第一步将 LR 转变为 LL 只需要将 node 节点左旋。         接着将 node.color BLACKparent.parent.color RED 处理再将爷爷节点右旋rightRotate(parent.parent) 即可。 调整完之后的图 其余的 case 4 的情况大致与以上的情况相同所以这里不再过多赘述了。   代码如下 //更新、增添节点//正常更新、删除遇到红红不平衡则需要进行调整public void put (int key, Object value) {TreeNode p root;TreeNode parent null;while (p ! null) {parent p;if (p.key key) {p p.left;}else if (p.key key) {p p.right;}else {p.value value;return;}}TreeNode node new TreeNode(key,value);if (parent null) {root node;}else {if (node.key parent.key) {parent.right node;}else {parent.left node;}node.parent parent;}//可能会发生红红不平衡则需要调整fixRedRed(node);}//调整红红不平衡private void fixRedRed(TreeNode node) {//case1: 插入节点为根节点将根节点变黑if(node root) {node.color BLACK;return;}if (isBlack(node.parent)) {//case2:插入节点的父亲若为黑树的红黑性质不变无需调整//无需调整return;}// 插入节点的父亲为红色触发红红相邻//case3:叔叔为红色TreeNode parent node.parent;TreeNode grandparent parent.parent;TreeNode uncle node.uncle();if (isRed(uncle)) {//进行变色处理即可//将其父亲、叔叔变为黑色爷爷变为红色//若爷爷触发了红红则继续递归调用该函数parent.color BLACK;uncle.color BLACK;grandparent.color RED;fixRedRed(grandparent);return;}//case4:叔叔为黑色//该父亲为左孩子该插入点也为左孩子则触发 llif (parent.isLeftChild() node.isLeftChild()) {//先将父亲变为黑色、爷爷变为红色再右旋转parent.color BLACK;grandparent.color RED;rightRotate(grandparent);}else if (parent.isLeftChild()) {//该插入节点为右孩子、该父亲为左孩子则触发 lr//先左旋变为 ll 情况leftRotate(parent);node.color BLACK;grandparent.color RED;rightRotate(grandparent);} else if (!node.isLeftChild()) {//插入节点为右孩子、父亲节点也为右孩子 rrparent.color BLACK;grandparent.color RED;leftRotate(grandparent);}else {//插入节点为左孩子、父亲节点为右孩子 rlrightRotate(parent);node.color BLACK;grandparent.color RED;leftRotate(grandparent);}} 6删除节点 - remove(int key) 实现思路正常删除节点若遇到黑黑不平衡则需要进行调整 正常删除节点的逻辑先找到需要删除的节点为了后续的代码简洁因此单独实现寻找删除节点的方法寻找代码的逻辑这里就不过多展开了。又单独实现寻找删除节点的替代节点的方法这个方法的简单逻辑为若删除节点没有左右孩子则替代的节点为 null ;若删除节点只有一个孩子则返回不为 null 的孩子若删除节点有两个节点则找到右子树的最小节点返回即可。 现在找到了删除节点判断该删除节点是否为 null 若 delete null 则说明没有找到删除节点结束删除过程若 delete ! null 则说明可以找到删除节点则继续通过根据删除节点查找替换节点的方法找到替换节点最后就可以删除节点了。对于删除节点是一个复杂的操作所以单独为一个方法 doRemove(TreeNode deleted) 。 对于实现 doRemove(TreeNode deleted) 方法需要考虑以下情况 - case0: 对于删除节点有两个孩子来说需要将其转换为只有一个孩子或者没有孩子情况。这里用到了李代桃僵技巧例如需要删除节点 deleted 替代节点 replace 将该两个节点的关键字 key 与值 value 交换那么现在需要删除的节点不再是 deleted 了而是 replace 。递归调用 doRemove(replace) 。这样子就可以将两个孩子的情况转变为一个孩子或者没有孩子的情况了。 - case1: 删除节点为根节点的情况。先考虑根节点没有左右孩子的情况则直接将 root null 。再考虑根节点有一个孩子的情况则利用到李代桃僵的技巧将孩子节点的关键字 key 与值 value 跟root 节点的关键字 key 与值 value 分别进行交换这样删除的节点就是孩子节点了将根节点的左右孩子置为 null 即可。最后要不要考虑根节点有两个孩子的情况呢 其实是不用的因为已经通过李代桃僵的技巧将有两个孩子节点转换为一个孩子或者没有孩子的节点。 - case2: 删除节点不为根节点的情况。同样先考虑删除的节点没有左右孩子的情况也说明删除的节点就是叶子节点所以先判断该删除节点的位置若删除节点是左孩子那么父亲节点的左孩子置为 null parent.left null若删除节点是右孩子那么父亲节点的右孩子置为 null parent.right null 。最后还需要将删除节点的父亲节点置为 null 方便后续的内存自动回收。 接着再来考虑删除节点有一个孩子的情况删除节点设为 deleted替换节点设为 repalce 。 先判断 deleted 的位置若 deleted 是左孩子则 parent.left repalce 进行链接若 deleted 是右孩子则 parent.right replace 进行链接。由于红黑树的节点与节点之间链接是相互的所以replace 节点的父亲节点需要链接到 parent 上 replace.parent parent 。最后需要将删除节点删除干净方便内存自动回收所以 deleted.left deleted.right deleted.parent null 。同样对于删除节点有两个孩子的情况不需要考虑已经转换为一个孩子或者没有孩子的情况了。 删除节点之后很有可能会导致红黑树的性质改变所以删除节点之前或者删除节点之后需要进行调整使其红黑树确保性质不会发生改变。主要有以下情况 对于删除节点没有左右孩子来说如果删除节点的颜色是红色且没有左右孩子则直接删除完之后不会发生红黑树性质改变如果删除节点的颜色是黑色且没有左右孩子则会触发黑黑相邻直接删除会导致红黑树性质发生改变所以需要进行复杂调整。 对于删除节点有一个节点来说如果删除节点的颜色为黑色替换节点为红色则删除节点之后需要将替换节点的颜色变为黑色即可如果删除节点的颜色为黑色替换节点也为黑色则触发了黑黑相邻需要进行复杂的调整。 进行复杂的调整修复黑黑不平衡的方法 fixBlackBlack(TreeNode node) 删除节点与剩下节点颜色都是黑色触发双黑双黑意思是少了一个黑。 - case3: 删除节点或者剩余节点的兄弟为红色此时两个侄子定位黑色。 如图         删除节点为节点 4 设为 deletde 兄弟节点为节点 8 设为 brother父亲节点为节点 6 设为 parent 。现在删除节点 4 的颜色为黑色且剩余节点为 null 该颜色为黑色触发双黑又兄弟节点为红色。满足以上情况时先判断兄弟节点的置为若兄弟节点为右孩子则需要将该父亲节点进行左旋若兄弟节点为左孩子则需要将该父亲节点进行右旋。旋转完之后需要变色处理将父亲节点的颜色变为红色兄弟节点的颜色变为黑色。最后继续将删除节点递归调用该函数。该方法的目的就是将删除节点的兄弟节点的颜色由红色变为黑色好对以下两种情况处理。简单说明这个方法就是一个过度的方法。 - case4: 被调整节点的兄弟为黑色两个侄子都为黑色 步骤一将兄弟节点的颜色变为红目的是将删除节点和兄弟那边的黑色高度同时减少1 步骤二如果父亲是红则需要将父亲变为黑色避免红红相邻此时路径黑色节点数目不变。 步骤三如果父亲是黑色说明这条路径则少了一个黑再次让父亲节点触发双黑。 如图         调整节点为节点 1 设为 node 兄弟节点为节点 2 设为 brother父亲节点为节点 2 设为 parent 。该情况满足了删除节点与剩余节点都是黑色触发双黑且兄弟节点的颜色也为黑色父亲节点的颜色为红色。调整的方法为将兄弟节点的颜色变为红色将父亲节点的颜色变为黑色即可。 调整完之后的图          如图         调整节点为节点 1 设为 node 兄弟节点为节点 3 设为 brother 父亲节点为节点 2 设为 parent 。该情况满足调整节点与剩余节点的颜色都为黑色触发双黑且兄弟节点的颜色也为黑色父亲节点也都为黑色。调整方法将兄弟节点的颜色变为红色再让父亲节点递归调用该函数继续触发双黑。 调整完之后的图 - case5: 被调整节点的兄弟为黑色至少有一个红色节点的侄子节点。 如果兄弟是左孩子左侄子是红色触发 LL 不平衡 如果兄弟是左孩子右侄子是红色触发 LR 不平衡 如果兄弟是右孩子右侄子是红色触发 RR 不平衡 如果兄弟是右孩子左侄子是红色触发 RL 不平衡 如图 触发 LL 不平衡情况         调整节点为节点 4 设为 node 兄弟节点为节点 2 设为 brother 父亲节点为节点 3 设为 parent 侄子节点为节点 1 。兄弟节点与侄子节点都是左孩子且侄子节点为红色。调整方法将父亲节点进行右旋再把侄子节点的颜色变为黑色兄弟节点的颜色变为原来父亲节点的颜色父亲节点的颜色变为黑色。 调整完之后的图 如图触发 LR 不平衡情况         调整节点为节点 4 设为 node 父亲节点为节点 3 设为 parent 兄弟节点为节点 1 设为 brother 侄子节点为节点 2 。兄弟节点是左孩子侄子为右孩子触发了 LR 不平衡。调整方法先将兄弟节点左旋变成了 LL 不平衡情况。         再把侄子节点的颜色变为原来父亲节点的颜色再到父亲节点的颜色变为黑色最后右旋父亲节点即可。 调整完之后的图          还有 RR 、RL 的情况与以上的情况大致是一样的所以这里就不过多赘述了。 删除节点的代码如下 //查找删除节点private TreeNode findDelete(int key) {TreeNode p root;while(p ! null) {if (p.key key) {p p.left;} else if (p.key key) {p p.right;}else {return p;}}//若没有找到则返回nullreturn null;}//查找剩余节点private TreeNode findReplaced(TreeNode deleted) {//没有孩子的情况:if (deleted.left null deleted.right null) {return null;}if (deleted.left null) {return deleted.right;}if (deleted.right null) {return deleted.left;}//有两个孩子的情况,找后继节点即可TreeNode p deleted.right;while(p.left ! null) {p p.left;}return p;}//删除节点//正常删除节点遇到黑黑不平衡则需要进行调整public void remove(int key) {TreeNode delete findDelete(key);if (delete null) {return;}doRemove(delete);}private void doRemove(TreeNode deleted) {TreeNode replaced findReplaced(deleted);TreeNode parent deleted.parent;//没有孩子的情况:if (replaced null) {//删除的节点为根节点情况下:if (deleted root) {root null;return;}else {if (isRed(deleted)) {//无需任何操作}else {//触发黑黑不平衡需要进行复杂的操作fixBlackBlack(deleted);}if (deleted.isLeftChild()) {parent.left null;}else {parent.right null;}deleted.parent null;}return;}//有一个孩子的情况if (deleted.left null || deleted.right null) {if (deleted root) {root.key replaced.key;root.value replaced.value;root.left root.right null;}else {if (deleted.isLeftChild()) {parent.left replaced;} else {parent.right replaced;}replaced.parent parent;deleted.left deleted.right deleted.parent null;if (isRed(replaced) isBlack(deleted)) {//却少一个黑色则将替换的节点换为红色即可replaced.color BLACK;}else {//遇到黑黑不平衡情况则需要进行复杂调整fixBlackBlack(replaced);}}return;}//有两个孩子的情况,需要将用到李代桃僵技巧int key deleted.key;deleted.key replaced.key;replaced.key key;Object value deleted.value;deleted.value replaced.value;replaced.value value;doRemove(replaced);}private void fixBlackBlack(TreeNode node) {if (node root) {return;}TreeNode parent node.parent;TreeNode brother node.brother();if (isRed(node.brother())) {//先进行旋转调整再换色暂时达到平衡if (brother.isLeftChild()) {rightRotate(parent);}else {leftRotate(parent);}parent.color RED;brother.color BLACK;fixBlackBlack(node);return;}//两个侄子都为黑色if (brother null) {fixBlackBlack(parent);}else {//case 4 兄弟是黑色两个侄子也是黑色if (isBlack(brother.left) isBlack(brother.right)) {brother.color RED;if (isRed(parent)) {parent.color BLACK;}else {fixBlackBlack(parent);}}//case 5 兄弟是黑色侄子有红色else {//其中某一个侄子不为黑色//兄弟为左孩子、侄子为左孩子触发 llif (brother.isLeftChild() isRed(brother.left)) {rightRotate(parent);brother.left.color BLACK;brother.color parent.color;parent.color BLACK;} else if (brother.isLeftChild() isRed(brother.right)) {//兄弟为左孩子、侄子为右孩子先触发 lr//需要将 lr 转变为 ll 情况再处理brother.right.color parent.color;leftRotate(brother);rightRotate(parent);parent.color BLACK;} else if ( !brother.isLeftChild() isRed(brother.right)) {//兄弟为右孩子侄子为右孩子触发 rrleftRotate(parent);brother.right.color BLACK;brother.color parent.color;parent.color BLACK;}else {//最后一种情况兄弟为右孩子、侄子为左孩子触发 rl//需要将 rl 转变为 rr 情况再处理brother.left.color parent.color;rightRotate(brother);leftRotate(parent);parent.color BLACK;}}}}5.0 实现红黑树核心方法的完整代码 import static TreeNode.RedBlackTree.Color.BLACK; import static TreeNode.RedBlackTree.Color.RED;public class RedBlackTree {enum Color {RED,BLACK;}private TreeNode root;private static class TreeNode {int key;Object value;TreeNode left;TreeNode right;TreeNode parent;Color color RED;//构造方法public TreeNode(int key, Object value) {this.key key;this.value value;}public TreeNode(int key, Object value, TreeNode left, TreeNode right, TreeNode parent) {this.key key;this.value value;this.left left;this.right right;this.parent parent;}//判断是否为左孩子public boolean isLeftChild() {return parent ! null parent.left this;}//获取叔叔节点public TreeNode uncle() {if (this.parent null || this.parent.parent null) {return null;}if (this.isLeftChild()) {return this.parent.parent.right;} else {return this.parent.parent.left;}}//获取兄弟节点public TreeNode brother() {if (this.parent null) {return null;}if (this.isLeftChild()) {return this.parent.right;}else {return this.parent.left;}}}//判断是否为红色节点private boolean isRed(TreeNode node) {return node ! null node.color RED;}//判断是否为黑色节点private boolean isBlack(TreeNode node) {return node null || node.color BLACK;}//右旋//1.考虑旋转后节点的维护parent 2.重新与上一个节点建立联系private void rightRotate(TreeNode node) {TreeNode parent node.parent;TreeNode nodeLeft node.left;TreeNode nodeLeftRight nodeLeft.right;if (nodeLeftRight ! null) {nodeLeftRight.parent node;}nodeLeft.right node;nodeLeft.parent parent;node.left nodeLeftRight;node.parent nodeLeft;if (parent null) {root nodeLeft;} else if (parent.left node) {parent.left nodeLeft;}else {parent.right nodeLeft;}}//左旋//1.考虑旋转后节点的维护parent 2.重新与上一个节点建立联系private void leftRotate(TreeNode node) {TreeNode parent node.parent;TreeNode nodeRight node.right;TreeNode nodeRightLeft nodeRight.left;if (nodeRightLeft ! null) {nodeRightLeft.parent node;}nodeRight.left node;nodeRight.parent parent;node.right nodeRightLeft;node.parent nodeRight;//2.重新与上一个节点建立联系if (parent null) {root nodeRight;} else if (parent.left node) {parent.left nodeRight;}else {parent.right nodeRight;}}//更新、增添节点//正常更新、删除遇到红红不平衡则需要进行调整public void put (int key, Object value) {TreeNode p root;TreeNode parent null;while (p ! null) {parent p;if (p.key key) {p p.left;}else if (p.key key) {p p.right;}else {p.value value;return;}}TreeNode node new TreeNode(key,value);if (parent null) {root node;}else {if (node.key parent.key) {parent.right node;}else {parent.left node;}node.parent parent;}//可能会发生红红不平衡则需要调整fixRedRed(node);}//调整红红不平衡private void fixRedRed(TreeNode node) {//case1: 插入节点为根节点将根节点变黑if(node root) {node.color BLACK;return;}if (isBlack(node.parent)) {//case2:插入节点的父亲若为黑树的红黑性质不变无需调整//无需调整return;}// 插入节点的父亲为红色触发红红相邻//case3:叔叔为红色TreeNode parent node.parent;TreeNode grandparent parent.parent;TreeNode uncle node.uncle();if (isRed(uncle)) {//进行变色处理即可//将其父亲、叔叔变为黑色爷爷变为红色//若爷爷触发了红红则继续递归调用该函数parent.color BLACK;uncle.color BLACK;grandparent.color RED;fixRedRed(grandparent);return;}//case4:叔叔为黑色//该父亲为左孩子该插入点也为左孩子则触发 llif (parent.isLeftChild() node.isLeftChild()) {//先将父亲变为黑色、爷爷变为红色再右旋转parent.color BLACK;grandparent.color RED;rightRotate(grandparent);}else if (parent.isLeftChild()) {//该插入节点为右孩子、该父亲为左孩子则触发 lr//先左旋变为 ll 情况leftRotate(parent);node.color BLACK;grandparent.color RED;rightRotate(grandparent);} else if (!node.isLeftChild()) {//插入节点为右孩子、父亲节点也为右孩子 rrparent.color BLACK;grandparent.color RED;leftRotate(grandparent);}else {//插入节点为左孩子、父亲节点为右孩子 rlrightRotate(parent);node.color BLACK;grandparent.color RED;leftRotate(grandparent);}}//查找删除节点private TreeNode findDelete(int key) {TreeNode p root;while(p ! null) {if (p.key key) {p p.left;} else if (p.key key) {p p.right;}else {return p;}}//若没有找到则返回nullreturn null;}//查找剩余节点private TreeNode findReplaced(TreeNode deleted) {//没有孩子的情况:if (deleted.left null deleted.right null) {return null;}if (deleted.left null) {return deleted.right;}if (deleted.right null) {return deleted.left;}//有两个孩子的情况,找后继节点即可TreeNode p deleted.right;while(p.left ! null) {p p.left;}return p;}//删除节点//正常删除节点遇到黑黑不平衡则需要进行调整public void remove(int key) {TreeNode delete findDelete(key);if (delete null) {return;}doRemove(delete);}private void doRemove(TreeNode deleted) {TreeNode replaced findReplaced(deleted);TreeNode parent deleted.parent;//没有孩子的情况:if (replaced null) {//删除的节点为根节点情况下:if (deleted root) {root null;return;}else {if (isRed(deleted)) {//无需任何操作}else {//触发黑黑不平衡需要进行复杂的操作fixBlackBlack(deleted);}if (deleted.isLeftChild()) {parent.left null;}else {parent.right null;}deleted.parent null;}return;}//有一个孩子的情况if (deleted.left null || deleted.right null) {if (deleted root) {root.key replaced.key;root.value replaced.value;root.left root.right null;}else {if (deleted.isLeftChild()) {parent.left replaced;} else {parent.right replaced;}replaced.parent parent;deleted.left deleted.right deleted.parent null;if (isRed(replaced) isBlack(deleted)) {//却少一个黑色则将替换的节点换为红色即可replaced.color BLACK;}else {//遇到黑黑不平衡情况则需要进行复杂调整fixBlackBlack(replaced);}}return;}//有两个孩子的情况,需要将用到李代桃僵技巧int key deleted.key;deleted.key replaced.key;replaced.key key;Object value deleted.value;deleted.value replaced.value;replaced.value value;doRemove(replaced);}private void fixBlackBlack(TreeNode node) {if (node root) {return;}TreeNode parent node.parent;TreeNode brother node.brother();if (isRed(node.brother())) {//先进行旋转调整再换色暂时达到平衡if (brother.isLeftChild()) {rightRotate(parent);}else {leftRotate(parent);}parent.color RED;brother.color BLACK;fixBlackBlack(node);return;}//两个侄子都为黑色if (brother null) {fixBlackBlack(parent);}else {//case 4 兄弟是黑色两个侄子也是黑色if (isBlack(brother.left) isBlack(brother.right)) {brother.color RED;if (isRed(parent)) {parent.color BLACK;}else {fixBlackBlack(parent);}}//case 5 兄弟是黑色侄子有红色else {//其中某一个侄子不为黑色//兄弟为左孩子、侄子为左孩子触发 llif (brother.isLeftChild() isRed(brother.left)) {rightRotate(parent);brother.left.color BLACK;brother.color parent.color;parent.color BLACK;} else if (brother.isLeftChild() isRed(brother.right)) {//兄弟为左孩子、侄子为右孩子先触发 lr//需要将 lr 转变为 ll 情况再处理brother.right.color parent.color;leftRotate(brother);rightRotate(parent);parent.color BLACK;} else if ( !brother.isLeftChild() isRed(brother.right)) {//兄弟为右孩子侄子为右孩子触发 rrleftRotate(parent);brother.right.color BLACK;brother.color parent.color;parent.color BLACK;}else {//最后一种情况兄弟为右孩子、侄子为左孩子触发 rl//需要将 rl 转变为 rr 情况再处理brother.left.color parent.color;rightRotate(brother);leftRotate(parent);parent.color BLACK;}}}}}- - - 努力要成为自己想要称为的人
文章转载自:
http://www.morning.znrlg.cn.gov.cn.znrlg.cn
http://www.morning.bpmnh.cn.gov.cn.bpmnh.cn
http://www.morning.gqryh.cn.gov.cn.gqryh.cn
http://www.morning.wspjn.cn.gov.cn.wspjn.cn
http://www.morning.kdxzy.cn.gov.cn.kdxzy.cn
http://www.morning.cwskn.cn.gov.cn.cwskn.cn
http://www.morning.wzyfk.cn.gov.cn.wzyfk.cn
http://www.morning.mdtfh.cn.gov.cn.mdtfh.cn
http://www.morning.lqrpk.cn.gov.cn.lqrpk.cn
http://www.morning.zfrs.cn.gov.cn.zfrs.cn
http://www.morning.qwwcf.cn.gov.cn.qwwcf.cn
http://www.morning.trbxt.cn.gov.cn.trbxt.cn
http://www.morning.dnphd.cn.gov.cn.dnphd.cn
http://www.morning.npxcc.cn.gov.cn.npxcc.cn
http://www.morning.jqbmj.cn.gov.cn.jqbmj.cn
http://www.morning.nccqs.cn.gov.cn.nccqs.cn
http://www.morning.jzccn.cn.gov.cn.jzccn.cn
http://www.morning.rpwht.cn.gov.cn.rpwht.cn
http://www.morning.xkwrb.cn.gov.cn.xkwrb.cn
http://www.morning.glcgy.cn.gov.cn.glcgy.cn
http://www.morning.nkcfh.cn.gov.cn.nkcfh.cn
http://www.morning.nlbw.cn.gov.cn.nlbw.cn
http://www.morning.wyppp.cn.gov.cn.wyppp.cn
http://www.morning.srkzd.cn.gov.cn.srkzd.cn
http://www.morning.yrflh.cn.gov.cn.yrflh.cn
http://www.morning.rpth.cn.gov.cn.rpth.cn
http://www.morning.jkpnm.cn.gov.cn.jkpnm.cn
http://www.morning.jykzy.cn.gov.cn.jykzy.cn
http://www.morning.yqkmd.cn.gov.cn.yqkmd.cn
http://www.morning.rdkqt.cn.gov.cn.rdkqt.cn
http://www.morning.wtnyg.cn.gov.cn.wtnyg.cn
http://www.morning.qczpf.cn.gov.cn.qczpf.cn
http://www.morning.qbxdt.cn.gov.cn.qbxdt.cn
http://www.morning.pfbx.cn.gov.cn.pfbx.cn
http://www.morning.zrmxp.cn.gov.cn.zrmxp.cn
http://www.morning.dqcpm.cn.gov.cn.dqcpm.cn
http://www.morning.nkjkh.cn.gov.cn.nkjkh.cn
http://www.morning.xprq.cn.gov.cn.xprq.cn
http://www.morning.spwln.cn.gov.cn.spwln.cn
http://www.morning.bhjyh.cn.gov.cn.bhjyh.cn
http://www.morning.gnfkl.cn.gov.cn.gnfkl.cn
http://www.morning.bfhfb.cn.gov.cn.bfhfb.cn
http://www.morning.blfll.cn.gov.cn.blfll.cn
http://www.morning.nflpk.cn.gov.cn.nflpk.cn
http://www.morning.kphyl.cn.gov.cn.kphyl.cn
http://www.morning.pdmsj.cn.gov.cn.pdmsj.cn
http://www.morning.blfgh.cn.gov.cn.blfgh.cn
http://www.morning.zqkms.cn.gov.cn.zqkms.cn
http://www.morning.rkypb.cn.gov.cn.rkypb.cn
http://www.morning.jqwpw.cn.gov.cn.jqwpw.cn
http://www.morning.jpjxb.cn.gov.cn.jpjxb.cn
http://www.morning.zlxrg.cn.gov.cn.zlxrg.cn
http://www.morning.mmxt.cn.gov.cn.mmxt.cn
http://www.morning.tzcr.cn.gov.cn.tzcr.cn
http://www.morning.sqhtg.cn.gov.cn.sqhtg.cn
http://www.morning.hwnqg.cn.gov.cn.hwnqg.cn
http://www.morning.wnnts.cn.gov.cn.wnnts.cn
http://www.morning.zyytn.cn.gov.cn.zyytn.cn
http://www.morning.sxlrg.cn.gov.cn.sxlrg.cn
http://www.morning.mkczm.cn.gov.cn.mkczm.cn
http://www.morning.mhmcr.cn.gov.cn.mhmcr.cn
http://www.morning.ncqzb.cn.gov.cn.ncqzb.cn
http://www.morning.kdpal.cn.gov.cn.kdpal.cn
http://www.morning.beijingzy.com.cn.gov.cn.beijingzy.com.cn
http://www.morning.yhplt.cn.gov.cn.yhplt.cn
http://www.morning.pqcbx.cn.gov.cn.pqcbx.cn
http://www.morning.kjrp.cn.gov.cn.kjrp.cn
http://www.morning.msfqt.cn.gov.cn.msfqt.cn
http://www.morning.rqnhf.cn.gov.cn.rqnhf.cn
http://www.morning.mrxgm.cn.gov.cn.mrxgm.cn
http://www.morning.smzr.cn.gov.cn.smzr.cn
http://www.morning.tdnbw.cn.gov.cn.tdnbw.cn
http://www.morning.rhnn.cn.gov.cn.rhnn.cn
http://www.morning.tsxg.cn.gov.cn.tsxg.cn
http://www.morning.wmqrn.cn.gov.cn.wmqrn.cn
http://www.morning.banzou2034.cn.gov.cn.banzou2034.cn
http://www.morning.wklmj.cn.gov.cn.wklmj.cn
http://www.morning.wztlr.cn.gov.cn.wztlr.cn
http://www.morning.rnytd.cn.gov.cn.rnytd.cn
http://www.morning.srcth.cn.gov.cn.srcth.cn
http://www.tj-hxxt.cn/news/245412.html

相关文章:

  • 建手机wap网站大概多少钱长沙室内设计学校
  • vps如何创建网站公众号平台app
  • 自己做免费手机网站吗网站建设服务那一个便宜
  • 做一般的公司门户网站投资额本科毕业设计代做网站
  • 资源下载类网站源码做淘客网站用什么程序
  • 网站服务器提供什么服务网络营销带来的效果
  • 网站建设公司销售招聘电子商务网站与建设课件
  • 大连网站建设设计公司哪家好wordpress配置搜索引擎优化
  • 出版社网站建设方案关键词优化排名软件哪家好
  • 做网站 公司 个体模版型网站
  • 多米诺网站建设中国交通建设网官方网站
  • 龙岗网站建设短视频投放方案
  • 秦皇岛网站制作电话婚纱摄影东莞网站建设技术支持
  • wordpress建站版本推荐微平台网站开发
  • 网站策划书的要点一朋友做网站网站被抓了
  • 德邦公司网站建设特点网页广告图片
  • nodejs做网站能保护源代码吗山东建筑公司实力排名
  • 手机网站经典案例微信带颜色的公众号
  • 网站建设基础知识怎么做网站搜索
  • 网页好看的网站设计网站死链处理
  • 中山大学精品课程网站山东省工程建设信息网
  • 做图海报网站网站建设管理ppt
  • php商业网站制作快速网站仿制
  • 怎么对自己做的网站进行加密论坛是做网站还是app好
  • vue做网站的好处wordpress菜单不现实
  • 网站做弹幕广告网站版式设计说明
  • 松原做招聘的网站有哪些静态网站托管平台
  • 3d网站开发成本建站之星模板怎么设置
  • 合肥哪个公司做网站好郑州汉狮做网站多少钱
  • 通过模版做网站网站建设dw站点建设