Java集合類匯總記錄-- apache.commons4(TreeList)


通常。Tree是Tree,List是List,兩者不太可能混在一起。但apache-commons庫卻用tree實現了實現了List的接口,也就是TreeList類。與標准的LinkedList相比。TreeList略微浪費一點空間,但經常使用操作的時間復雜度均減少到了O(log N),值得在開發中權衡利弊、合理應用。

內部數據結構

TreeList內部包括了一個Thread AVL Tree。AVL Tree非經常見了,是一種典型的Balanced Binary Tree,但以下簡介下Thread Binary Tree。

Thread Binary Tree對Binary Tree添加了下面特性:(1)假設一個節點X沒有左子樹。則把本來應指向左子樹的指針,指向中序遍歷的前節點。(2)假設一個節點X沒有右子樹,則把本來應指向右子樹的指針,指向中序遍歷的后節點。

下圖就是一個Thread Binary Tree,以節點5為例:(1) 節點5沒有左子樹,但節點5的中序遍歷的前節點是4(2) 節點5沒有右子樹,但節點5的中序遍歷的后節點是6

這兩個特性提高了二叉樹依序訪問的速度。


下面是TreeList中AVL樹節點的定義

    static class AVLNode<E> {
        /** 左子樹或者中序遍歷的前節點.*/
        private AVLNode<E> left;
        /** true表示left字段是左子樹;false表示left字段是中序遍歷的前節點 */
        private boolean leftIsPrevious;
        /** 右子樹或者中序遍歷的后節點 */
        private AVLNode<E> right;
        /** true表示right字段是右子樹;false表示right字段是中序遍歷的后節點 */
        private boolean rightIsNext;
        /** How many levels of left/right are below this one. */
        private int height;
        /** 在List中的索引相對於父節點索引的偏移量。根節點就是根節點的索引*/
        private int relativePosition;
        /** 節點所保存的有效荷載 */
        private E value;
    }

在邏輯上。TreeList中的節點是依據節點在List中的索引來比較大小的。在實現上,AVLNode類保存的是當前節點的索引相對於父節點的偏移量,也就是relativePosition這個字段。這樣做的長處是,當向List中間插入一個節點時。插入點之后的全部節點的索引值都變大了,但由於AVLNode保存的是相對值。因此僅僅須要改動特定子樹的根節點的relativePosition值,整個子樹全部節點的索引值都會發生變化。

時空復雜度

TreeList既然是用AVL樹實現,則其在特定位置進行插入、刪除和get操作的時間復雜度都是O(log N),另外還要加上較大的時間常量。

LinkedList是採用雙向鏈表實現的。其在特定位置進行插入、刪除和get操作的時間復雜度都是O(N)。

空間復雜度

首先看一下LinkedList中每一個節點的定義:

private static class Entry<E> {
	E element;
	Entry<E> next;
	Entry<E> previous;
}

依據以上定義。在32位Hostspot虛擬機下,每一個Entry對象占用6*4=24個byte(這包含8個byte的對象頭、12個byte的真實字段和4個byte的對齊填充)。

依據AVLNode的定義,每一個AVLNode節點占用8*4=32個byte(包含8個byte的對象頭、22個byte的真實字段和2個byte的對齊填充)。

因此,TreeList的每一個節點比LinkedLists多占領8個byte。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM