TreeMap 原始碼分析

2021-08-19 23:14:32 字數 4131 閱讀 2256

treemap底層是使用紅黑樹實現的儲存鍵值對的map容器,可以通過比較器進行排序。紅黑樹本質上是一棵弱平衡二叉樹,它的節點有紅色和黑色兩種顏色。主要特性有五點。

(1)每個節點或者是黑色,或者是紅色。

(2)根節點是黑色。

(3)每個葉子節點(nil)是黑色。 [注意:這裡葉子節點,是指為空(nil或null)的葉子節點!]

(4)如果乙個節點是紅色的,則它的子節點必須是黑色的。

(5)從乙個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。

treemap中重要引數及結構。

/**

* treemap中包含乙個比較器,可以用來定義順序

*/private final comparator<? super k> comparator;

private transient entryroot;

/*** 樹中鍵值對的個數

*/private transient int size = 0;

/*** 用於快速失敗,記錄修改次數,不是執行緒安全

*/private transient int modcount = 0;

/*** 構造乙個空樹,比較器為空,key值按照自然順序排序。

*/public treemap()

/*** 構造乙個空樹,根據所給的比較器進行排序 ,所有key值在插入時都要使用比較器。

*/public treemap(comparator<? super k> comparator)

/*** 使用所給的map進行插入,key值按照自然順序進行排序。

*/public treemap(map<? extends k, ? extends v> m)

/*** 構造一棵和排序樹相同順序的樹。鍵值對一樣,比較器相等。

*/public treemap(sortedmapm)

}

查詢。根據key值來進行查詢,從根上開始,依次進行遍歷。

/**

* 根據所給的key值進行查詢,首先看比較器是否空,然後判斷key是否為null,然後根據自然順序查詢。

*/final entrygetentry(object key)

return null;//沒找到返回null

}/**

* 使用比較器的版本

*/final entrygetentryusingcomparator(object key)

}return null;

}/**

* 獲取大於等於key的最小節點

*/final entrygetceilingentry(k key) else if (cmp > 0) else

return parent;

}} else

return p;

}return null;

}/**

* 獲取小於等於key最大的節點

*/final entrygetfloorentry(k key) else if (cmp < 0) else

return parent;

}} else

return p;

}return null;

}

增加乙個鍵值對。判斷是否是根節點,然後使用比較器進行判斷找到要插入的位置,根據比較器取得要插入的位置後判斷是否是修改操作,如果不是修改操作那麼就把這個節點放在相應位置。

/**

* *

*/public v put(k key, v value)

int cmp;

entryparent;

// 根據是否有比較器進行再次判斷。

comparator<? super k> cpr = comparator;

if (cpr != null) while (t != null);

}else while (t != null);

}entrye = new entry<>(key, value, parent);//如果不是修改的話,那麼就把這個e放在相應的樹分支上即可。

if (cmp < 0)

parent.left = e;

else

parent.right = e;

fixafterinsertion(e);//調整樹結構,滿足紅黑樹的性質。

size++;

modcount++;

return null;

}

刪除乙個節點。 

/**

* 刪除乙個節點,然後重新使樹變的平衡。

*/private void deleteentry(entryp)

// 記錄p的替代節點。也就是p的左節點,如果為空則是右節點。

entryreplacement = (p.left != null ? p.left : p.right);

if (replacement != null) else if (p.parent == null) else

}}

/**

* 返回當前節點的繼任節點。也就是整個樹上的比當前節點小的下乙個節點。

*/static treemap.entrysuccessor(entryt) else

return p;

}}

調整樹結構,左旋右旋操作。

//對乙個節點進行左旋操作

private void rotateleft(entryp)

}//對乙個節點進行右旋操作

private void rotateright(entryp)

}//插入乙個節點後保證紅黑樹依舊是紅黑樹。

private void fixafterinsertion(entryx) else

setcolor(parentof(x), black);

setcolor(parentof(parentof(x)), red);

rotateright(parentof(parentof(x)));

}} else else

setcolor(parentof(x), black);

setcolor(parentof(parentof(x)), red);

rotateleft(parentof(parentof(x)));}}

}root.color = black;

}

treemap的使用:常用的方法示例。

treemapmap=new treemap<>(new comparator() 

});//構建乙個treemap,key值從小到大排序

map.put(3,"22");

map.put(2,"333");

map.put(5,"333");

map.put(2,"77777");//向treemap中新增鍵值對

system.out.println(map.tostring());

system.out.println(map.ceilingkey(4));//大於等於key值為4的下乙個key

system.out.println(map.floorkey(4));//小於等於key值為4 的下乙個key

system.out.println(map.containskey(1));//是否包含key值為1的鍵值對

system.out.println(map.keyset());

system.out.println(map.firstkey());//最開始的乙個鍵值對

system.out.println(map.lastentry());//最後的乙個鍵值對

system.out.println(map.descendingkeyset());//逆序key

system.out.println(map.get(2));//獲取key為2的value

system.out.println(map.higherkey(3));//key大於3的下乙個key

參考部落格:

紅黑樹的概念)

紅黑樹左旋右旋)

TreeMap原始碼分析

public v put k key,v value int cmp entryparent split comparator and comparable paths comparator cpr comparator if cpr null while t null else while t n...

TreeMap原始碼分析

基於紅黑樹的實現,根據key的自然順序排序,或者根據構造方法傳入的排序方式。構造方法傳入的比較器 藉此維護鍵的順序 private final comparator super k comparator private transient entry root 根節點 private transie...

TreeMap原始碼分析

treemap是基於紅黑樹結構實現的一種map。紅黑樹是一種自平衡二叉查詢樹。二叉查詢樹 若左子樹不為空,則左子樹上所有節點的值均小於它的根節點的值 若右子樹不為空,則右子樹上所有節點的值均大於它的根節點的值 左 右子樹也分別為二叉查詢樹 沒有鍵值相等的節點。treemap 利用了紅黑樹左節點小,右...