• Java数据结构-HashMap


    Java数据结构-HashMap

    1. HashMap数据结构

    没有哈希冲突时,为数组,支持动态扩容

    哈希冲突时,分为两种情况:

    1. 当冲突长度小于8或数组长度小于64(MIN_TREEIFY_CAPACITY默认值为64)时,为数组+链表(Node)

    2. 当冲突长度大于8时,为数组+红黑树/链表(TreeNode)。

    红黑树用于快速查找,链表用于遍历。

    2. 红黑树

     HashMap中的TreeNode是红黑树的实现。

    TreeNode几个方法

    1. 左旋转

            static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,
                                                  TreeNode<K,V> p) {
                TreeNode<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;
            }

    实现效果如图

    2. 右旋转

           static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root,
                                                   TreeNode<K,V> p) {
                TreeNode<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.right == p)
                        pp.right = l;
                    else
                        pp.left = l;
                    l.right = p;
                    p.parent = l;
                }
                return root;
            }

    实现效果如图

     3. 插入

     static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
                                                        TreeNode<K,V> x) {
                x.red = true;
                for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
                    if ((xp = x.parent) == null) {
                        x.red = false;
                        return x;
                    }
                    else if (!xp.red || (xpp = xp.parent) == null) //
                        return root;
                    if (xp == (xppl = xpp.left)) {
                        if ((xppr = xpp.right) != null && xppr.red) { //
                            xppr.red = false;
                            xp.red = false;
                            xpp.red = true;
                            x = xpp;
                        }
                        else {
                            if (x == xp.right) {  //
                                root = rotateLeft(root, x = xp);
                                xpp = (xp = x.parent) == null ? null : xp.parent;
                            }
                            if (xp != null) {  //
                                xp.red = false;
                                if (xpp != null) {
                                    xpp.red = true;
                                    root = rotateRight(root, xpp);
                                }
                            }
                        }
                    }
                    else {
                        if (xppl != null && xppl.red) {  //
                            xppl.red = false;
                            xp.red = false;
                            xpp.red = true;
                            x = xpp;
                        }
                        else {
                            if (x == xp.left) {       //
                                root = rotateRight(root, x = xp);
                                xpp = (xp = x.parent) == null ? null : xp.parent;
                            }
                            if (xp != null) {   //
                                xp.red = false;
                                if (xpp != null) {
                                    xpp.red = true;
                                    root = rotateLeft(root, xpp);
                                }
                            }
                        }
                    }
                }
            }

    实现效果如下:

  • 相关阅读:
    201805140815_《缓存操作函数封装》
    201802071223_《更换两个二进制》
    201801301359——《注意Javascript这种形式》
    201708310807_《算法-Javascript实现最大公约数》
    重拾java openjdk1.8 语法小试
    代码轮子之很简单但是挺管用的基于C# Task的模拟并发的代码
    docker1.12 安装pxc(Percona XtraDB Cluster )测试
    .net orm比较之dapper和Entity Framework6的简单测试比较
    StackExchange.Redis使用和封装小试
    docker1.12 安装redis3官方集群 攻略
  • 原文地址:https://www.cnblogs.com/huiyao/p/10549752.html
Copyright © 2020-2023  润新知