紅黑樹及Java實(shí)現(xiàn)

紅黑樹(Red-Black Tree)试溯,一種特殊的二叉查找樹弓乙,紅黑樹的每個(gè)節(jié)點(diǎn)上都有存儲(chǔ)位表示節(jié)點(diǎn)的顏色渊抄,可以是紅(Red)或黑(Black);
紅黑樹主要是用它來(lái)存儲(chǔ)有序的數(shù)據(jù)巢块,它的時(shí)間復(fù)雜度是O(lgn)礁阁,效率非常高;
紅黑樹是一種近似平衡的二叉查找樹族奢,它能夠確保任何一個(gè)節(jié)點(diǎn)的左右子樹的高度差不會(huì)超過(guò)二者中較低那個(gè)的一倍姥闭;
例如Java集合中TreeMap,TreeSet越走,HashMap等棚品,以及Linux虛擬內(nèi)存的管理


紅黑樹的特性:

  • 每個(gè)節(jié)點(diǎn)或者是黑色靠欢,或者是紅色;
  • 根節(jié)點(diǎn)是黑色铜跑;
  • 每個(gè)葉子節(jié)點(diǎn)(NIL)是黑色门怪。 [注意:這里葉子節(jié)點(diǎn),是指為空(NIL或NULL)的葉子節(jié)點(diǎn)]锅纺;
  • 如果一個(gè)節(jié)點(diǎn)是紅色的掷空,則它的子節(jié)點(diǎn)必須是黑色的;
  • 從一個(gè)節(jié)點(diǎn)到該節(jié)點(diǎn)的子孫節(jié)點(diǎn)的所有路徑上包含相同數(shù)目的黑節(jié)點(diǎn)囤锉。

性質(zhì)3中指定紅黑樹的每個(gè)葉子節(jié)點(diǎn)都是空節(jié)點(diǎn)拣帽,而且并葉子節(jié)點(diǎn)都是黑色。但 Java 實(shí)現(xiàn)的紅黑樹將使用 null 來(lái)代表空節(jié)點(diǎn)嚼锄,因此遍歷紅黑樹時(shí)將看不到黑色的葉子節(jié)點(diǎn),反而看到每個(gè)葉子節(jié)點(diǎn)都是紅色的蔽豺。

性質(zhì)4的意思是:從每個(gè)根到節(jié)點(diǎn)的路徑上不會(huì)有兩個(gè)連續(xù)的紅色節(jié)點(diǎn)区丑,但黑色節(jié)點(diǎn)是可以連續(xù)的。 因此若給定黑色節(jié)點(diǎn)的個(gè)數(shù) N修陡,最短路徑的情況是連續(xù)的 N 個(gè)黑色沧侥,樹的高度為 N - 1;最長(zhǎng)路徑的情況為節(jié)點(diǎn)紅黑相間,樹的高度為 2(N - 1) 魄鸦。

性質(zhì)5是成為紅黑樹最主要的條件宴杀,紅黑樹的插入、刪除操作都是為了遵守這個(gè)規(guī)定拾因。紅黑樹是相對(duì)是接近平衡的二叉樹旺罢。它以性質(zhì) 5 作為一種平衡方法,使自己的性能得到了提升绢记。特性5確保沒有一條路徑會(huì)比其他路徑長(zhǎng)出倆倍扁达。


當(dāng)對(duì)紅黑樹進(jìn)行增刪操作時(shí),以上約束條件可能被破壞蠢熄,需要通過(guò)調(diào)整使得查找樹重新滿足紅黑樹的約束條件跪解。調(diào)整可以分為兩類:一類是顏色調(diào)整,即改變某個(gè)節(jié)點(diǎn)的顏色签孔;另一類是結(jié)構(gòu)調(diào)整叉讥,集改變檢索樹的結(jié)構(gòu)關(guān)系。結(jié)構(gòu)調(diào)整過(guò)程包含兩個(gè)基本操作:左旋右旋饥追。
一個(gè)不錯(cuò)的在線演示添加图仓、刪除紅黑樹:http://sandbox.runjs.cn/show/2nngvn8w


紅黑樹node定義:

class Entry<K extends Comparable<K>,V> {
        private static final boolean RED   = false;
        private static final boolean BLACK = true;
        K key; 
        V value;
        Entry<K,V> left;
        Entry<K,V> right;
        Entry<K,V> parent;
        boolean color;
        
        Entry(K key, V value, Entry<K,V> parent) {
            this.key = key;
            this.value = value;
            this.parent = parent;
        }
        
        public Entry(K key, boolean color, Entry<K,V> parent, Entry<K,V> left,Entry<K,V> right) {
            this.key = key;
            this.color = color;
            this.parent = parent;
            this.left = left;
            this.right = right;
        }
    }

紅黑樹插入:
圖解;來(lái)源自:https://github.com/CarpenterLee/JCFInternals/blob/master/markdown/5-TreeSet%20and%20TreeMap.md

add.png

/**
     * put方法 insert到紅黑樹
     */
    public V put(K key, V value) {
        if(key == null) {
            throw new NullPointerException("key不能為空判耕!");
        }
        int cmp;
        Entry<K,V> parent;
        Entry<K,V> t = root;
        // 第一次插入
        if (t == null) {
            root = new Entry<>(key, value, null);
            root.color = BLACK;
            return null;
        }
        do {
            parent = t;
            cmp = key.compareTo(t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else {
                // 找到key的value透绩,更新value并返回舊value
                V oldValue = t.value;
                t.value = value;
                return oldValue;
            }
        } while (t != null);
        // 插入新node
        Entry<K,V> entry = new Entry(key, value, parent);
        // 設(shè)置新增節(jié)點(diǎn)的顏色為紅色
        entry.color = RED;
        if (cmp < 0)
            parent.left = entry;
        else
            parent.right = entry;
        // 將它重新修正為一顆二叉查找樹
        fixAfterInsertion(entry);
        return null;
    }
    

    /* 
     * 對(duì)紅黑樹的節(jié)點(diǎn)進(jìn)行左旋轉(zhuǎn)
     * 左旋示意圖(對(duì)節(jié)點(diǎn)x進(jìn)行左旋)
     *      px                              px
     *     /                               /
     *    x                               y                
     *   /  \      --(左旋)--             / \                
     *  lx   y                          x   ry     
     *     /   \                       /  \
     *    ly   ry                     lx   ly  
     */
    private void leftRotate(Entry<K, V> x) {
        // 設(shè)置x的右孩子為y
        Entry<K, V> y = x.right;

        // 將 “y的左孩子” 設(shè)為 “x的右孩子”;
        // 如果y的左孩子非空,將 “x” 設(shè)為 “y的左孩子的父親”
        x.right = y.left;
        if (y.left != null)
            y.left.parent = x;

        // 將 “x的父親” 設(shè)為 “y的父親”
        y.parent = x.parent;

        if (x.parent == null) {
            this.root = y;            // 如果 “x的父親” 是空節(jié)點(diǎn)帚豪,則將y設(shè)為根節(jié)點(diǎn)
        } else {
            if (x.parent.left == x)
                x.parent.left = y;    // 如果 x是它父節(jié)點(diǎn)的左孩子碳竟,則將y設(shè)為“x的父節(jié)點(diǎn)的左孩子”
            else
                x.parent.right = y;    // 如果 x是它父節(jié)點(diǎn)的左孩子,則將y設(shè)為“x的父節(jié)點(diǎn)的左孩子”
        }
        
        // 將 “x” 設(shè)為 “y的左孩子”
        y.left = x;
        // 將 “x的父節(jié)點(diǎn)” 設(shè)為 “y”
        x.parent = y;
    }
    
    /* 
     * 對(duì)紅黑樹的節(jié)點(diǎn)進(jìn)行右旋轉(zhuǎn)
     * 右旋示意圖(對(duì)節(jié)點(diǎn)y進(jìn)行左旋):
     *            py                               py
     *           /                                /
     *          y                                x                  
     *         /  \                            /  \                     
     *        x   ry                          lx    y  
     *       / \                                   / \                   
     *      lx  rx                                rx  ry
     */
    private void rightRotate(Entry<K, V> y) {
        // 設(shè)置x是當(dāng)前節(jié)點(diǎn)的左孩子狸臣。
        Entry<K, V> x = y.left;
        // 將 “x的右孩子” 設(shè)為 “y的左孩子”莹桅;
        // 如果"x的右孩子"不為空的話,將 “y” 設(shè)為 “x的右孩子的父親”
        y.left = x.right;
        if (x.right != null)
            x.right.parent = y;

        // 將 “y的父親” 設(shè)為 “x的父親”
        x.parent = y.parent;

        if (y.parent == null) {
            this.root = x;            // 如果 “y的父親” 是空節(jié)點(diǎn)烛亦,則將x設(shè)為根節(jié)點(diǎn)
        } else {
            if (y == y.parent.right)
                y.parent.right = x;    // 如果 y是它父節(jié)點(diǎn)的右孩子诈泼,則將x設(shè)為“y的父節(jié)點(diǎn)的右孩子”
            else
                y.parent.left = x;    // (y是它父節(jié)點(diǎn)的左孩子) 將x設(shè)為“x的父節(jié)點(diǎn)的左孩子”
        }
        // 將 “y” 設(shè)為 “x的右孩子”
        x.right = y;
        // 將 “y的父節(jié)點(diǎn)” 設(shè)為 “x”
        y.parent = x;
    }
    /**
     * 紅黑樹插入修正函數(shù)
     * 
     * 在向紅黑樹中插入節(jié)點(diǎn)之后(失去平衡),再調(diào)用該函數(shù)煤禽;
     * 目的是將它重新塑造成一顆紅黑樹铐达。
     * @param entry 新插入的結(jié)點(diǎn)
     */
    private void fixAfterInsertion(Entry<K, V> entry) {
        Entry<K, V> parent,gparent;
        // 若父節(jié)點(diǎn)存在,并且父節(jié)點(diǎn)的顏色是red
        while( (parent = parentOf(entry))!= null && isRed(parent)) {
            gparent = parentOf(parent); // 祖父節(jié)點(diǎn)
            // 父節(jié)點(diǎn)是 祖父節(jié)點(diǎn)的左子樹
            if(gparent.left == parent) {
                Entry<K, V> uncle = gparent.right; // 叔節(jié)點(diǎn)
                // 叔節(jié)點(diǎn) 存在且是紅色
                if( (uncle!=null) && colorOf(uncle) == RED) {
                    uncle.color = BLACK; 
                    parent.color = BLACK;
                    gparent.color = RED;
                    entry = gparent;
                    continue;
                }
                // 叔叔是黑色檬果,且當(dāng)前節(jié)點(diǎn)是右孩子
                if(parent.right == entry) {
                    Entry<K, V> tmp;
                    leftRotate(parent);
                    tmp = parent;
                    parent = entry;
                    entry = tmp;
                }
                // 叔叔是黑色瓮孙,且當(dāng)前節(jié)點(diǎn)是左孩子
                parent.color = BLACK;
                gparent.color = RED;
                rightRotate(gparent);
                
            } else {
            // 父節(jié)點(diǎn)是 祖父節(jié)點(diǎn)的右子樹
                Entry<K, V> uncle = gparent.left; // 叔節(jié)點(diǎn)
                // 叔節(jié)點(diǎn) 存在且是紅色
                if( (uncle!=null) && colorOf(uncle) == RED) {
                    uncle.color = BLACK; 
                    parent.color = BLACK;
                    gparent.color = RED;
                    entry = gparent;
                    continue;
                }
                // 叔叔是黑色,且當(dāng)前節(jié)點(diǎn)是左孩子
                if(parent.left == entry) {
                    Entry<K, V> tmp;
                    rightRotate(parent);
                    tmp = parent;
                    parent = entry;
                    entry = tmp;
                }
                // 叔叔是黑色选脊,且當(dāng)前節(jié)點(diǎn)是右孩子
                parent.color = BLACK;
                gparent.color = RED;
                leftRotate(gparent);
            }
        }
        // 將根節(jié)點(diǎn)設(shè)為黑色
        root.color = BLACK;
    }

測(cè)試添加:

public class Main {

    public static void main(String[] args) {
        RBTree<Integer, String> tree = new RBTree<Integer, String>();
        int[] ins = new int[]{20,5,32,3,10,45,8,16,6};
        for (int i : ins) {
            tree.put(i, ""+ i);
        }
        tree.printZhong();
        tree.printXian();
    }
}

結(jié)果:
中序遍歷:[[3 : 3]+(false), [5 : 5]+(true), [6 : 6]+(true), [8 : 8]+(false), [10 : 10]+(false), [16 : 16]+(false), [20 : 20]+(true), [32 : 32]+(false), [45 : 45]+(true)]
先序遍歷:[[10 : 10]+(false), [5 : 5]+(true), [3 : 3]+(false), [8 : 8]+(false), [6 : 6]+(true), [20 : 20]+(true), [16 : 16]+(false), [32 : 32]+(false), [45 : 45]+(true)]
其中:false為黑杭抠;true為紅


紅黑樹.png

紅黑樹刪除操作:
刪除的節(jié)點(diǎn)的兩種情況:
1)刪除點(diǎn)p的左右子樹都為空,或者只有一棵子樹非空。
2)刪除點(diǎn)p的左右子樹都非空。
對(duì)于上述情況1饺汹,處理起來(lái)比較簡(jiǎn)單借尿,直接將node刪除(左右子樹都為空時(shí)),或者用非空子樹替代node(只有一棵子樹非空時(shí));對(duì)于情況2,可以用node的后繼s(樹中大于node的最小的那個(gè)元素)代替node,然后使用情況1刪除s(此時(shí)s一定滿足情況1)沮峡。
刪除原理示意圖:


TreeMap_fixAfterDeletion.png

刪除節(jié)點(diǎn)程序:

  /**
     * 刪除節(jié)點(diǎn)
     */
    public void remove(K key) {
        Entry<K, V> node; 
        if ((node = search(root, key)) != null)
            remove(node);
    }
    private void remove(Entry<K, V> node) {
        Entry<K, V> child, parent;
        boolean color;
        // 刪除的node不為空
        if (node.left != null && node.right != null) {// 2. 刪除點(diǎn)p的左右子樹都非空。
            Entry<K,V> s = successor(node);// 得到后繼
            node.key = s.key;
            node.value = s.value;
            
            node = s; // 為了刪除后繼節(jié)點(diǎn)亿柑,不用遞歸邢疙,這么賦值的;
        } 
        Entry<K,V> replacement = (node.left != null ? node.left : node.right);
        if (replacement != null) {  // 刪除點(diǎn)node只有一棵子樹非空望薄;
            Entry<K, V> parentNode = parentOf(node);
            if(parentNode == null) {
                this.root = replacement;
            }
            if(parentNode.left == node) {
                parentNode.left = replacement;
            } else {
                parentNode.right = replacement;
            }
            replacement.parent = parentNode;
            node.left = node.right = node.parent = null; // 置為null疟游;
            if (node.color == BLACK)
                fixAfterDeletion(replacement);// 調(diào)整
        } else if (node.parent == null) { // node沒有子節(jié)點(diǎn),并且沒有父節(jié)點(diǎn)
            this.root = null;
        } else {
            if (node.color == BLACK)
                fixAfterDeletion(node);// 調(diào)整
            if (node.parent != null) {
                if (node == node.parent.left)
                    node.parent.left = null;
                else if (node == node.parent.right)
                    node.parent.right = null;
                node.parent = null;
            }
        }
        
    }
    /**
     * 紅黑樹刪除修正函數(shù)
     * 
     * 在從紅黑樹中刪除節(jié)點(diǎn)之后(紅黑樹失去平衡)痕支,再調(diào)用該函數(shù)颁虐;
     * 目的是將它重新塑造成一顆紅黑樹。
     * @param node 待修正的節(jié)點(diǎn)
     */
    private void fixAfterDeletion(Entry<K,V> node) {
        while (node != root && colorOf(node) == BLACK) {
            // node為其父節(jié)點(diǎn)的左子樹
            if (node == leftOf(parentOf(node))) {
                Entry<K,V> bro = rightOf(parentOf(node));
                // node的兄弟節(jié)點(diǎn)為紅 
                if (colorOf(bro) == RED) {
                    setColor(bro, BLACK);
                    setColor(parentOf(node), RED);
                    leftRotate(parentOf(node));
                    bro = rightOf(parentOf(node));
                }
                // node的兄弟節(jié)點(diǎn)的兩個(gè)子樹為黑
                if (colorOf(leftOf(bro))  == BLACK && colorOf(rightOf(bro)) == BLACK) {
                    setColor(bro, RED);
                    node = parentOf(node);
                } else {
                    // node的兄弟節(jié)點(diǎn)的左子樹為紅卧须,右子樹為黑
                    if (colorOf(rightOf(bro)) == BLACK) {
                        setColor(leftOf(bro), BLACK);
                        setColor(bro, RED);
                        rightRotate(bro);
                        bro = rightOf(parentOf(node));
                    }
                    // node的兄弟節(jié)點(diǎn)的右子樹為紅另绩,左子樹隨意
                    setColor(bro, colorOf(parentOf(node)));
                    setColor(parentOf(node), BLACK);
                    setColor(rightOf(bro), BLACK);
                    leftRotate(parentOf(node));
                    node = root;
                }
            } else { 
                Entry<K,V> sib = leftOf(parentOf(node));

                if (colorOf(sib) == RED) {
                    setColor(sib, BLACK);
                    setColor(parentOf(node), RED);
                    rightRotate(parentOf(node));
                    sib = leftOf(parentOf(node));
                }

                if (colorOf(rightOf(sib)) == BLACK && colorOf(leftOf(sib)) == BLACK) {
                    setColor(sib, RED);
                    node = parentOf(node);
                } else {
                    if (colorOf(leftOf(sib)) == BLACK) {
                        setColor(rightOf(sib), BLACK);
                        setColor(sib, RED);
                        leftRotate(sib);
                        sib = leftOf(parentOf(node));
                    }
                    setColor(sib, colorOf(parentOf(node)));
                    setColor(parentOf(node), BLACK);
                    setColor(leftOf(sib), BLACK);
                    rightRotate(parentOf(node));
                    node = root;
                }
            }
        }
        setColor(node, BLACK);
    }
    
    /**
     * 尋找p的后繼(樹中大于p的key的最小的那個(gè)元素)
     * @param p
     * @return
     */
    private Entry<K, V> successor( Entry<K, V> p) {
        if(p == null) {
            return null;
        }
        Entry<K, V> node = p.right;
        if(node != null) {
            while(node.left != null) {
                node = node.left;
            }
            return node;
        }
        // 因?yàn)樵O(shè)定p左右子樹不為空儒陨,所以不會(huì)走到這一步
        return null;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市笋籽,隨后出現(xiàn)的幾起案子蹦漠,更是在濱河造成了極大的恐慌,老刑警劉巖车海,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笛园,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡侍芝,警方通過(guò)查閱死者的電腦和手機(jī)研铆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)州叠,“玉大人棵红,你說(shuō)我怎么就攤上這事∵掷酰” “怎么了窄赋?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)楼熄。 經(jīng)常有香客問(wèn)我,道長(zhǎng)浩峡,這世上最難降的妖魔是什么可岂? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮翰灾,結(jié)果婚禮上缕粹,老公的妹妹穿的比我還像新娘。我一直安慰自己纸淮,他們只是感情好平斩,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咽块,像睡著了一般绘面。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侈沪,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天揭璃,我揣著相機(jī)與錄音,去河邊找鬼亭罪。 笑死瘦馍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的应役。 我是一名探鬼主播情组,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼燥筷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了院崇?” 一聲冷哼從身側(cè)響起肆氓,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎亚脆,沒想到半個(gè)月后做院,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡濒持,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年键耕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柑营。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屈雄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出官套,到底是詐尸還是另有隱情酒奶,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布奶赔,位于F島的核電站惋嚎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏站刑。R本人自食惡果不足惜另伍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绞旅。 院中可真熱鬧摆尝,春花似錦、人聲如沸因悲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晃琳。三九已至讯检,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卫旱,已是汗流浹背视哑。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留誊涯,地道東北人挡毅。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像暴构,于是被迫代替她去往敵國(guó)和親跪呈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子段磨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 樹的概述 樹是一種非常常用的數(shù)據(jù)結(jié)構(gòu),樹與前面介紹的線性表耗绿,棧苹支,隊(duì)列等線性結(jié)構(gòu)不同,樹是一種非線性結(jié)構(gòu) 1.樹的定...
    Jack921閱讀 4,434評(píng)論 1 31
  • 1误阻、紅黑樹介紹 紅黑樹又稱R-B Tree债蜜,全稱是Red-Black Tree,它是一種特殊的二叉查找樹究反,紅黑樹的...
    文哥的學(xué)習(xí)日記閱讀 9,851評(píng)論 1 35
  • 上一篇:Java集合-ConcurrentHashMap工作原理和實(shí)現(xiàn)JDK8 本文學(xué)習(xí)知識(shí)點(diǎn) 1寻定、二叉查找樹,以...
    Misout閱讀 13,820評(píng)論 9 67
  • 這周末偶然發(fā)現(xiàn)了一個(gè)新番精耐,本周播出第一集狼速,名字叫《在下坂本,有何貴幹卦停?》向胡,根據(jù)同名漫畫改編,還有另外一個(gè)名字叫《我...
    傳說(shuō)中的死神閱讀 343評(píng)論 2 3
  • 當(dāng)七月與安生的影評(píng)在網(wǎng)絡(luò)上涮屏的時(shí)候 當(dāng)大家都在夸贊馬思純和周冬雨演技的時(shí)候 我的內(nèi)心是不屑的 國(guó)產(chǎn)的青春電影無(wú)非...
    意意的星光閱讀 407評(píng)論 0 1