共同学习Java源代码-数据结构-HashMap(十五)

从这篇文章开始到HashMap系列的结束 都会讲一个内容 那就是HashMap的TreeNode内部类 HashMap每个桶的链表的长度达到8 再想给链表增加元素 就要将链表改成二叉树 这个TreeNode就是红黑树的实现

 static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> 

这个类是静态final的 继承自LinkedHashMap的Entry

TreeNode<K,V> parent;  
TreeNode<K,V> left;
TreeNode<K,V> right;
TreeNode<K,V> prev;

这四个属性分别是父节点,左节点,右节点和前一个节点

boolean red;

这个属性是确定是红树节点 还是黑树节点


        final TreeNode<K,V> root() {
            for (TreeNode<K,V> r = this, p;;) {
                if ((p = r.parent) == null)
                    return r;
                r = p;
            }
        }

这个是求根节点的方法 就是不停地获取parent节点 直到parent为空的时候


        static <K,V> void moveRootToFront(Node<K,V>[] tab, TreeNode<K,V> root) {
            int n;
            if (root != null && tab != null && (n = tab.length) > 0) {
                int index = (n - 1) & root.hash;
                TreeNode<K,V> first = (TreeNode<K,V>)tab[index];
                if (root != first) {
                    Node<K,V> rn;
                    tab[index] = root;
                    TreeNode<K,V> rp = root.prev;
                    if ((rn = root.next) != null)
                        ((TreeNode<K,V>)rn).prev = rp;
                    if (rp != null)
                        rp.next = rn;
                    if (first != null)
                        first.prev = root;
                    root.next = first;
                    root.prev = null;
                }
                assert checkInvariants(root);
            }
        }

这个方法是将根节点放入哈希桶的方法 

先定义临时变量n 

判断传入的根元素不为空 且 传入的哈希桶数组不为空 且传入的哈希桶数组的长度大于0

如果上述条件成立 计算一下传入的根元素应该放在哈希桶的哪个下标处 计算方法还是那个 用数组长度减一的值和根元素的哈希值进行按位与的结果 作为下标 TreeNode直接继承自LinkedHashMap的Entry 而这个Entry又继承自HashMap的Node 所以TreeNode其实和Node是有继承关系的

然后获取哈希桶数组的指定下标元素 判断是否和根元素为同一元素 

如果哈希桶数组的指定下标元素不是这个根元素 那就先创建普通节点类变量rn 

然后将哈希桶数组制定下标赋为传入的根元素 

然后获取根元素的上一个元素prev 赋给变量rp 

判断根元素的下一个元素不为空 将这个下一个元素的prev节点指向刚才获取的上一个元素prev

然后判断根元素的上一个元素不为空的话 就将根元素的上一个元素的next节点指向根元素的下一个节点 

挺绕口的 其实就是一旦链表转换成了红黑树 实际上为了方便遍历 这颗红黑树仍然保留链表顺序的 刚才的做法就是将跟元素从之前的链表顺序中剔除 让根元素之前之后的元素建立"连接" 可以理解为将根元素从链表中拆出来放在第一位 

接下来根元素的下一个元素开水奇偶first 根元素的上一个元素置空

最后断言一下根元素的前后左右元素 都是不是正确的 具体代码如下

        static <K,V> boolean checkInvariants(TreeNode<K,V> t) {
            TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right,
                tb = t.prev, tn = (TreeNode<K,V>)t.next;
            if (tb != null && tb.next != t)
                return false;
            if (tn != null && tn.prev != t)
                return false;
            if (tp != null && t != tp.left && t != tp.right)
                return false;
            if (tl != null && (tl.parent != t || tl.hash > t.hash))
                return false;
            if (tr != null && (tr.parent != t || tr.hash < t.hash))
                return false;
            if (t.red && tl != null && tl.red && tr != null && tr.red)
                return false;
            if (tl != null && !checkInvariants(tl))
                return false;
            if (tr != null && !checkInvariants(tr))
                return false;
            return true;
        }
    }

这个方法是断言传入的树元素

先判断如果上一个元素不为空 且上一个元素的下一个元素不是本元素 就返回false 换句话说就是本元素和上一个元素之间的链条断了

再判断下一个元素的上一个元素不是本元素 就返回false 这个是本元素和下一个元素之间的链条断了

再判断这个元素不是父元素的左元素且也不是右元素 就返回false 这个是本元素和父元素的链条断了

再判断左元素的父元素不是本元素 或 左元素的哈希值大于本元素的哈希值 就返回false 这个是本元素和本元素的左元素的链条断了

再判断右元素的父元素不是本元素 或 右元素的哈希值小于本元素的哈希值 就返回false 这个是本元素和本元素的右元素的链条断了

再判断如果左元素 本元素 右元素都是红的 就返回false

然后先后递归判断左元素和右元素是否合法

最后返回true

ESP芯片:ESP32S3N16R8IDF版本:V5.3.1LVGL版本:V8.3.11LCD驱动IC: ST7789V触摸屏驱动IC:CST816T实现:移植好LVGL,并成功运行LVGL里面的music demo!!!ESP32S3N16R8是Espressif公司生产的ESP32系列的微控制器。ESP32S3N16R8具有16MB的内部Flash存储器,使得它可以用来执行更为复杂的程序和存储大量的数据。它使用的是双核处理器,并支持Wi-Fi和蓝牙,使其成为物联网应用的理想选择。ESP32S3N16R8还具有丰富的外设接口,可以连接各种外设,如传感器、显示屏等。LVGL,全称为Light and Versatile Graphics Library,是一个开源的嵌入式图形库。它为开发者提供了丰富的图形元素,如按钮、滑块、图表等,使开发者能够轻松地创建美观的用户界面。LVGL适用于小尺寸的显示屏,如OLED、TFT LCD等。ST7789V是一款彩色TFT LCD驱动芯片,广泛应用于各种中小尺寸的彩色显示屏。ST7789V支持SPI通信协议,能够实现高速的数据传输,从而快速刷新显示画面。ST7789V具有色彩丰富、反应速度快、分辨率高的特点,能够提供高质量的视觉效果。CST816T是一款高灵敏度、高精度的电容式触摸屏控制器。它能够检测多点触摸,并提供高分辨率的触摸位置坐标。CST816T支持手势识别,使其能够识别出滑动、旋转等手势,从而提供更为便捷的交互方式。本次介绍的ESP32S3N16R8_with_LVGLv8.3.11_ST7789V+CST816T_20250213是一个压缩包文件,里面包含了ESP32S3N16R8微控制器、LVGL图形库V8.3.11版本、ST7789V LCD驱动IC和CST816T触摸屏驱动IC的相关内容。在这个文件中,开发者已经成功地将LVGL移植到了ESP32S3N16R8,并运行了LVGL中的music demo。这意味着开发者可以在此基础上,利用ESP32S3N16R8强大的处理能力和丰富的外设接口,结合LVGL的图形显示能力和ST7789V、CST816T的显示和触摸功能,开发出更多具有丰富交互和视觉效果的应用。以上是对标题、描述、标签和文件名称列表中涉及的ESP32S3N16R8微控制器、LVGL图形库、ST7789V LCD驱动IC和CST816T触摸屏驱动IC的详细介绍。这些信息对于理解ESP32S3N16R8_with_LVGLv8.3.11_ST7789V+CST816T_20250213文件的内容以及如何在此基础上进行开发具有重要的意义。开发者可以在此基础上,开发出更多具有丰富交互和视觉效果的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值