企业注册查询网/网站内部seo优化包括

企业注册查询网,网站内部seo优化包括,网站建设常用字体,莱州网站建设包年TreeMap继承自AbstractMap,并实现了NavigableMap接口(NavigableMap继承自SortedMap接口)。底层的数据结构是红黑树,按照键的自然排序或者自定义实现的规则排序,实现元素的有序性。 特点 元素是有序的:按照key的自然排序或者是自…

TreeMap继承自AbstractMap,并实现了NavigableMap接口(NavigableMap继承自SortedMap接口)。底层的数据结构是红黑树,按照键的自然排序或者自定义实现的规则排序,实现元素的有序性。

特点

  1. 元素是有序的:按照key的自然排序或者是自定义的比较器进行排序(并不是按照插入顺序排序)
  2. 键不能重复,值可以重复:key不能重复,value可以重复
  3. 键不能为null,值可以为null
  4. 红黑树是一种自平衡的二叉树,通过规则维持树的高度近似平衡,保证查询的时间复杂度为O(log n)

红黑树底层原理

  • TreeMap是基于红黑树实现的键值对集合
  • 树的根节点为黑色
  • 树里面的节点不是黑色的就是红色的
  • 相邻的两个节点不能都是红色
  • 从任意一个节点到其叶子节点的路径上黑色节点数相同
  • 红黑树的所有叶子节点都是黑色(叶子节点是Nil节点)

参考博主:

红黑树插入: https://www.cnblogs.com/GNLin0820/p/9120337.html最终还是决定把红黑树的篇章一分为二,插入操作一篇,删除操作一篇,因为合在一起写篇幅实在太长了,写起来都觉得累,何况是阅读并理解的读者。 红黑树删除操作请参考 数据结构 - 红黑树(Red Black Tree)删除详解与实现(Java) 现在网络上最不缺的就是对某个知识点的讲解博文,各种花https://www.cnblogs.com/GNLin0820/p/9120337.html

红黑树删除: https://www.cnblogs.com/GNLin0820/p/9668378.html本篇要讲的就是红黑树的删除操作 红黑树插入操作请参考 数据结构 - 红黑树(Red Black Tree)插入详解与实现(Java) 红黑树的删除是红黑树操作中比较麻烦且比较有意思的一部分。 在此之前,重申一遍红黑树的五个定义: 1. 红黑树的节点不是黑色的就是红色的 2. 红黑树的根节点https://www.cnblogs.com/GNLin0820/p/9668378.html

添加节点

第一种情况

添加的节点(500)和它的父节点(400)也是红色,并且它的叔叔节点(Nil1)是黑色(Nil是不存在的叶子节点)

添加的节点(500)是叔叔节点(Nil1)的远亲(是父节点的右节点)

就以父节点(400)为中心点,左旋。旋转后:

  1. 父节点变成黑色,祖父节点变成红色
  2. 祖父节点(300)的父节点变成400,祖父节点(300)的左子节点是Nil1,右子节点是Nil2
  3. 父节点(400)的左子节点变成了300,右子节点是500
  4. 祖父节点(300)有父节点的话,父节点(400)的父节点 变成 祖父节点(300)的父节点

 第二种情况

添加的节点(350)是父节点(400)的左子节点,父节点是红色;它的叔叔节点(Nil1)是黑色

添加的节点(350)是叔叔节点(Nil1)的近亲(父节点的左子节点)

就以父节点(400)为中心,先右旋。旋转后:

  1. 父节点(400)变成了插入节点(350)的右节点,400的父节点变成了350,400的左节点变成了Nil4
  2. 插入节点(350)的右节点变成了400,它的父节点变成了300

再左旋:以350作为中心点,左旋

第三种情况

添加节点(100)是父节点的左子节点,父节点(200)是红色,它的叔叔节点(Nil4)是黑色

添加的节点(100)是叔叔节点的远亲(挨的远)

则以父节点(200)为中心点,右旋,旋转后:

  1. 父节点(200)变成黑色,祖父节点(300)变成红色
  2. 300的父节点变成了200,左子节点变成了Nil3,右子节点变成了Nil4
  3. 200的右子节点变成了300,左子节点变成了100
  4. 如果祖父节点(300)不是根节点,父节点(200)的父节点 变成 祖父节点(300)的父节点

第四种情况

插入节点(250)是父节点的右子节点,父节点为祖父节点(300)的左子节点,父节点(200)是红色

插入节点(250)的叔叔节点(Nil4)是黑色

250与Nil4是近亲(挨的近)

以父节点(200)为中心点,先左旋:

  1. 200的父节点变成250,200的左子节点是Nil1,右子节点是Nil2
  2. 250的父节点变成300,250的左子节点变成200

再按照第三种情况,以250为中心点右旋

第五种情况

插入节点为红色,它的父节点也为红色,它的叔叔节点也是红色

直接将父节点和叔叔节点变成黑色,祖父节点变成红色

如果祖父节点是根节点,则祖父节点最后要变成黑色

  1. 首先确认插入节点位置,定位好插入节点的父节点,祖父节点,叔叔节点

  2. 看自己和父节点颜色,都是红色就需要修复树平衡(相邻节点不能都是红色)

  3. 确认要修复平衡后,看叔叔节点颜色

    1. 叔叔是红色,直接改变叔叔和父亲的颜色(变成黑色),再改变祖父节点颜色(变为红色)

    2. 叔叔是黑色,就要左旋或者右旋

      1. 自己是左节点,父亲也是左节点:自己是红色,父节点变成黑色,祖父节点变成红色。以父亲为中心右旋

      2. 自己是左节点,父亲是右节点:以父亲为中心,先右旋再左旋,旋转完之后变换颜色,自己变成黑色,父亲节点和祖父节点变成红色

      3. 自己是右节点,父亲也是右节点:自己是红色,父节点变成黑色,祖父节点变成红色。以父亲为中心左旋

      4. 自己是右节点,父亲是左节点:以父亲为中心,先左旋再右旋,旋转完之后变换颜色,自己变成黑色,父亲节点和祖父节点变成红色

    3. 完成当次平衡后,如果叔叔是红色节点:把祖父节点作为下一次平衡的插入点;如果叔叔是黑色节点:把父亲节点作为下一次平衡的插入点

    4. 直到遍历到根节点或者是当前插入点的父节点是黑色,结束平衡操作

删除节点(部分)

首先要确认删除节点时不存在的情况

第二,四种:不满足条件:相邻的两个节点不能为红色

第一,三,五,六种:不满足条件:从任意节点到叶子节点路径上的黑色节点数要相同

也就是说:

在第一五种情况下:父节点是红色,只有一个子节点且是黑色,这时候必然会有另一个子节点也是黑色

在第二六种情况下:父节点是黑色,只有一个子节点且是黑色,这时候必然会有另一个子节点也是黑色

以下是会发生的删除情况

第一种情况

被删除的节点是黑色,并且只有一个子节点是红色

  1. 100这个节点作为修复树的起点(代码中设置为replacement)
  2. 100的父节点改为400
  3. 200的所有指针都置为空
  4. 100作为平衡树的起点去做平衡修复:100的颜色是红色,没有其他操作,直接将100这个节点的颜色变为黑色

第二种情况

要删除的节点p有左右子节点

  1. 找到500的后继节点:就是600,被确认为要删除的节点
  2. 将600节点里面的key-value复制到500节点
  3. p指针变成指向600节点
  4. 600节点没有子节点,所以没有replacement作为作为修复平衡树的起点
  5. 600节点有父节点:600节点自己作为修复平衡树的起点
  6. 600节点是红色,不需要修复平衡,直接将600节点中的指针清空

第三种情况

要删除的节点为450,有左右节点。

  1. 确认其后继节点为600,将600节点的key-value复制给450节点,600被确认为要删除的节点
  2. 600(p指针指向的节点,以下皆为p指向)没有子节点,则600作为修复树的起点
  3. 600节点的颜色为黑色(被删除的节点是黑色,破坏了树的平衡),修复树
  4. 600的兄弟节点只有一个子节点,并且和600是近亲,420和440节点颜色互换
  5. 以420为中心左旋
  6. 以440为中心右旋
  7. 清空p指针指向的节点

第四种情况

方法

构造方法

public class TreeMap<K,V>extends AbstractMap<K,V>implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{//比较器private final Comparator<? super K> comparator;//根节点private transient Entry<K,V> root;//树中节点个数private transient int size = 0;//树的修改次数private transient int modCount = 0;public TreeMap() {comparator = null;}//创建一个TreeMap,自定义比较器public TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}//创建一个TreeMap,将传入集合中的元素复制到TreeMap中public TreeMap(Map<? extends K, ? extends V> m) {comparator = null;putAll(m);}//创建一个TreeMap,将传入的集合复制到TreeMap中,使用传入集合中的比较器public TreeMap(SortedMap<K, ? extends V> m) {comparator = m.comparator();try {buildFromSorted(m.size(), m.entrySet().iterator(), null, null);} catch (java.io.IOException | ClassNotFoundException cannotHappen) {}}
}

查找当前节点的后继节点

    //查找当前节点的后继节点(比当前节点大的最小节点)static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {if (t == null)return null;//如果t节点的右节点不为空,则查找该右节点的最小左节点else if (t.right != null) {Entry<K,V> p = t.right;while (p.left != null)p = p.left;return p;} //如果t节点的右节点为空,则查找该节点的父节点,若t是父节点的左节点,则返回该父节点else {Entry<K,V> p = t.parent;Entry<K,V> ch = t;//若t是p(父节点)的右节点,则继续向上查找,直到查找到p,其中t是p的左节点,返回pwhile (p != null && ch == p.right) {ch = p;p = p.parent;}return p;}}

删除节点后自平衡

x节点是修复平衡的起点

    //x为删除方法中计算出的后继者节点的子节点或者是后继者节点本身//如果x节点不是根节点且它的颜色是黑色,则需要左旋或者右旋//否则直接将x节点的颜色变为黑色private void fixAfterDeletion(Entry<K,V> x) {//如果x节点不是根节点且它的颜色是黑色while (x != root && colorOf(x) == BLACK) {//如果x节点是左节点if (x == leftOf(parentOf(x))) {Entry<K,V> sib = rightOf(parentOf(x));//同一个父节点,x作为左节点是黑色,sib作为右节点是红色//将sib设置为黑色,父节点设置为红色//以x的父节点为中心点左旋if (colorOf(sib) == RED) {setColor(sib, BLACK);setColor(parentOf(x), RED);rotateLeft(parentOf(x));sib = rightOf(parentOf(x));}//sib的左节点是黑色,sib的右节点也是黑色,设置sib为红色//设置完成后将x的父节点赋值给xif (colorOf(leftOf(sib))  == BLACK &&colorOf(rightOf(sib)) == BLACK) {setColor(sib, RED);x = parentOf(x);} //如果sib的左右节点其中一个是红色else {//如果sib的右节点是黑色,设置sib的左节点为黑色,sib为红色,以sib为中心右旋//将x节点的父节点的右节点赋值给sibif (colorOf(rightOf(sib)) == BLACK) {setColor(leftOf(sib), BLACK);setColor(sib, RED);rotateRight(sib);sib = rightOf(parentOf(x));}//上面if条件执行与否都会执行下面的代码//将sib的颜色设置为x父节点的颜色//将x父节点的颜色设置为黑色//将sib的右节点颜色设置为黑色//以x的父节点为中心左旋setColor(sib, colorOf(parentOf(x)));setColor(parentOf(x), BLACK);setColor(rightOf(sib), BLACK);rotateLeft(parentOf(x));//将x设置为根节点,跳出循环x = root;}} //如果x是右节点,与是左节点的情况是对称的else {Entry<K,V> sib = leftOf(parentOf(x));if (colorOf(sib) == RED) {setColor(sib, BLACK);setColor(parentOf(x), RED);rotateRight(parentOf(x));sib = leftOf(parentOf(x));}if (colorOf(rightOf(sib)) == BLACK &&colorOf(leftOf(sib)) == BLACK) {setColor(sib, RED);x = parentOf(x);} else {if (colorOf(leftOf(sib)) == BLACK) {setColor(rightOf(sib), BLACK);setColor(sib, RED);rotateLeft(sib);sib = leftOf(parentOf(x));}setColor(sib, colorOf(parentOf(x)));setColor(parentOf(x), BLACK);setColor(leftOf(sib), BLACK);rotateRight(parentOf(x));x = root;}}}setColor(x, BLACK);}

添加单个元素

   public V put(K key, V value) {Entry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}int cmp;Entry<K,V> parent;Comparator<? super K> cpr = comparator;//比较器不为空,根据比较器规则查找元素,若key已存在,更新key对应的value值if (cpr != null) {do {parent = t;cmp = cpr.compare(key, t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}//比较器为空,则按照自然顺序排序比较,查找key,若key存在,则更新key对应的value值else {if (key == null)throw new NullPointerException();@SuppressWarnings("unchecked")Comparable<? super K> k = (Comparable<? super K>) key;do {parent = t;cmp = k.compareTo(t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}//key不存在,新建一个节点存放键值对,放入红黑树中Entry<K,V> e = new Entry<>(key, value, parent);if (cmp < 0)parent.left = e;elseparent.right = e;//添加完成后,调用函数保证红黑树的自平衡fixAfterInsertion(e);size++;modCount++;return null;}

添加多个元素

    //按照map的比较器添加元素或者是按照默认自然排序规则添加元素public void putAll(Map<? extends K, ? extends V> map) {int mapSize = map.size();if (size==0 && mapSize!=0 && map instanceof SortedMap) {Comparator<?> c = ((SortedMap<?,?>)map).comparator();if (c == comparator || (c != null && c.equals(comparator))) {++modCount;try {buildFromSorted(mapSize, map.entrySet().iterator(),null, null);} catch (java.io.IOException | ClassNotFoundException cannotHappen) {}return;}}super.putAll(map);}

删除单个元素

   private void deleteEntry(Entry<K,V> p) {modCount++;size--;//如果要删除的节点,左右节点都不为空,查找到当前节点的后继节点//将后继节点的键值对数据拷贝到要删除的节点中,并且将后继者节点作为被删除的节点if (p.left != null && p.right != null) {Entry<K,V> s = successor(p);p.key = s.key;p.value = s.value;//将后继者节点赋值给p,后续操作的p其实是此处查找到的后继者节点p = s;} // p has 2 children//指定从replacement开始修复树的平衡//从后继者节点的左节点或者右节点开始Entry<K,V> replacement = (p.left != null ? p.left : p.right);//如果replacement节点不为空,后继者节点的父节点与成为replacement节点的父节点if (replacement != null) {replacement.parent = p.parent;//如果后继者节点的父节点为空,则replacement作为根节点if (p.parent == null)root = replacement;//如果后继者节点是其父节点的左节点,则replacement成为父节点的左节点else if (p == p.parent.left)p.parent.left  = replacement;//如果后继者节点是其父节点的右节点,则replacement成为父节点的右节点elsep.parent.right = replacement;//将后继者节点的指针都清空p.left = p.right = p.parent = null;// 修复树的平衡,从replacement节点开始//如果删除的后继者节点是黑色,调用修复if (p.color == BLACK)fixAfterDeletion(replacement);} //如果后继者节点没有父节点,并且也没有子节点(左右节点),那么清空根节点else if (p.parent == null) {root = null;} //如果后继者节点没有子节点但是有父节点,那么后继者节点自己作为树平衡的开始节点else { //修复树平衡if (p.color == BLACK)fixAfterDeletion(p);//删除后继者节点(清除后继者节点的指针,以及后继者节点的父节点指向它的指针)if (p.parent != null) {if (p == p.parent.left)p.parent.left = null;else if (p == p.parent.right)p.parent.right = null;p.parent = null;}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/70823.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端Javascrip后端Net6前后分离文件上传案例(完整源代码)下载

文件上传功能在项目开发中非常实用&#xff0c;本案例前端用Javascrip实现&#xff0c;后端用Net6实现 前端Javascrip后端Net6前后分离文件上传案例&#xff08;完整源代码&#xff09; 下载链接 https://download.csdn.net/download/luckyext/90437795?spm1001.2014.3001.5…

DeepSeek行业应用实践报告-智灵动力【112页PPT全】

DeepSeek&#xff08;深度搜索&#xff09;近期引发广泛关注并成为众多企业/开发者争相接入的现象&#xff0c;主要源于其在技术突破、市场需求适配性及生态建设等方面的综合优势。以下是关键原因分析&#xff1a; 一、技术核心优势 开源与低成本 DeepSeek基于开源架构&#xf…

Day 51 卡玛笔记

这是基于代码随想录的每日打卡 647. 回文子串 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 示例 1&#xff1a; 输入&#xff1a;s &q…

结构型模式---外观模式

概念 外观模式是一种结构型设计模式&#xff0c;它的核心思想是为复杂的子系统提供一个统一的接口&#xff0c;简化客户端与子系统的交互。外观模式通过引入一个高层接口&#xff0c;隐藏子系统的复杂性&#xff0c;使客户端更容易使用。 适用场景 用于客户端无需具体操作子…

多通道数据采集和信号生成的模块化仪器如何重构飞机电子可靠性测试体系?

飞机的核心电子系统包括发电与配电系统&#xff0c;飞机内部所有设备和系统之间的内部数据通信系统&#xff0c;以及用于外部通信的射频设备。其他所有航空电子元件都依赖这些关键总线进行电力传输或数据通信。在本文中&#xff0c;我们将了解模块化仪器&#xff08;无论是PCIe…

【Godot4.3】基于绘图函数的矢量蒙版效果与UV换算

概述 在设计圆角容器时突发奇想&#xff1a; 将圆角矩形的每个顶点坐标除以对应圆角矩形所在Rect2的size&#xff0c;就得到了顶点对应的UV坐标。然后使用draw_colored_polygon&#xff0c;便可以做到用图片填充圆角矩形的效果。而且这种计算的效果就是图片随着其填充的图像缩…

Scrapy:隧道代理中移除 Proxy-Authorization 的原理解析

隧道代理中移除 Proxy-Authorization 的原理解析 背景 在 Scrapy 的 HTTP 下载处理中&#xff0c;当使用隧道代理&#xff08;TunnelingAgent&#xff09;时&#xff0c;会移除请求头中的 Proxy-Authorization。这个操作看似简单&#xff0c;但背后有着重要的安全考虑和技术原…

大中型虚拟化园区网络设计

《大中型虚拟化园区网络设计》属于博主的“园区网”专栏&#xff0c;若想成为HCIE&#xff0c;对于园区网相关的知识需要非常了解&#xff0c;更多关于园区网的内容博主会更新在“园区网”专栏里&#xff0c;请持续关注&#xff01; 一.前言 华为云园区网络解决方案(简称Cloud…

sklearn中的决策树-分类树:剪枝参数

剪枝参数 在不加限制的情况下&#xff0c;一棵决策树会生长到衡量不纯度的指标最优&#xff0c;或者没有更多的特征可用为止。这样的决策树 往往会过拟合。为了让决策树有更好的泛化性&#xff0c;我们要对决策树进行剪枝。剪枝策略对决策树的影响巨大&#xff0c;正确的剪枝策…

几个api

几个api 原型链 可以阅读此文 Function instanceof Object // true Object instanceof Function // true Object.prototype.isPrototypeOf(Function) // true Function.prototype.isPrototypeOf(Object) // true Object.__proto__ Function.prototype // true Function.pro…

【Azure 架构师学习笔记】- Azure Databricks (12) -- Medallion Architecture简介

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (11) – UC搭建 前言 使用ADB 或者数据湖&#xff0c;基本上绕不开一个架构“Medallion”&#xff0c; 它使得数据管理更为简单有效。ADB 通过…

python-leetcode 45.二叉树转换为链表

题目&#xff1a; 给定二叉树的根节点root,请将它展开为一个单链表&#xff1a; 展开后的单链表应该使用同样的TreeNode,其中right子指针指向链表中的下一个节点&#xff0c;而左子指针始终为空 展开后的单链表应该与二叉树先序遍历顺序相同 方法一&#xff1a;二叉树的前序…

【leetcode hot 100 15】三数之和

一、两数之和的扩展 class Solution {public List<List<Integer>> threeSum(int[] nums) {// 将得到的结果存入Set中&#xff0c;保证不重复Set<List<Integer>> set new HashSet<>();// 模拟两数之和&#xff0c;作为第一个循环中的内容for(in…

设备健康管理系统在制造业的深度应用探索

引言 在制造业的数字化转型浪潮中&#xff0c;设备健康管理系统正逐渐成为企业提升竞争力的关键利器。随着工业 4.0 和智能制造概念的不断深入&#xff0c;制造业对设备的高效、稳定运行提出了更高要求。设备健康管理系统借助先进的传感器技术、物联网&#xff08;IoT&#xf…

HTTPS 与 HTTP 的区别在哪?

HTTP与HTTPS作为互联网数据传输的核心协议&#xff0c;其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。本文将解析两者的通信流程、安全机制及核心差异。 一、HTTP的通信机制 先来看看HTTP是什么吧。 HTTP基于TCP/IP协议栈&#xff0c;采用经典客户端-服务…

为什么要将PDF转换为CSV?CSV是Excel吗?

在企业和数据管理的日常工作中&#xff0c;PDF文件和CSV文件承担着各自的任务。PDF通常用于传输和展示静态的文档&#xff0c;而CSV因其简洁、易操作的特性&#xff0c;广泛应用于数据存储和交换。如果需要从PDF中提取、分析或处理数据&#xff0c;转换为CSV格式可能是一个高效…

【JAVAEE】多线程

【JAVAEE】多线程 一、进程1.1 进程的定义1.2 进程和线程的联系 二、线程2.1 JConsole工具2.2 创建线程2.2.1 Thread类&#xff0c;start&#xff08;&#xff09;&#xff0c;run&#xff08;&#xff09;2.2.2 继承Thread类2.2.3 实现Runnable接口2.2.4 匿名内部类2.2.5 使用…

手机打电话时如何识别对方按下的DTMF按键的字符-安卓AI电话机器人

手机打电话时如何识别对方按下的DTMF按键的字符 --安卓AI电话机器人 一、前言 前面的篇章中&#xff0c;使用蓝牙电话拦截手机通话的声音&#xff0c;并对数据加工&#xff0c;这个功能出来也有一段时间了。前段时间有试用的用户咨询说&#xff1a;有没有办法在手机上&#xff…

WiseFlow本地搭建实录---保姆教程

今天从零开始搭建了Wiseflow的本地环境搭建&#xff0c;目前使用的都是免费的API&#xff0c;我建议大家可以一起尝试一下搭建自己的关键信息的数据库&#xff0c;我是windows的环境&#xff0c;但是其他的应该也差不多&#xff0c;踩了很多坑&#xff0c;希望这篇文章能帮大家…

web安全渗透测试 APP安全渗透漏洞测试详情

前言 小小白承包了一块20亩的土地&#xff0c;依山傍水&#xff0c;风水不错。听朋友说去年玉米大卖&#xff0c;他也想尝尝甜头&#xff0c;也就种上了玉米。 看着玉米茁壮成长&#xff0c;别提小小白心里多开心&#xff0c;心里盘算着玉米大买后&#xff0c;吃香喝辣的富贵…