背景 等值查找,有數組、列表、HashMap等,已經足夠了,範圍查找,該用什麼數據結構呢?下麵介紹java中非常好用的兩個類TreeMap和ConcurrentSkipListMap。 TreeMap的實現基於紅黑樹 每一棵紅黑樹都是一顆二叉排序樹,又稱二叉查找樹(Binary Search Tre ...
背景
等值查找,有數組、列表、HashMap等,已經足夠了,範圍查找,該用什麼數據結構呢?下麵介紹java中非常好用的兩個類TreeMap和ConcurrentSkipListMap。
TreeMap的實現基於紅黑樹
每一棵紅黑樹都是一顆二叉排序樹,又稱二叉查找樹(Binary Search Tree),亦稱二叉搜索樹。是數據結構中的一類。在一般情況下,查詢效率比鏈表結構要高。
紅黑樹是一種特化的AVL樹(平衡二叉樹),都是在進行插入和刪除操作時通過特定操作保持二叉查找樹的平衡,從而獲得較高的查找性能。 [2] 它雖然是複雜的,但它的最壞情況運行時間也是非常良好的,並且在實踐中是高效的: 它可以在O(log n)時間內做查找,插入和刪除,這裡的n 是樹中元素的數目。 ConcurrentSkipListMap的實現基於跳錶 跳錶是一個隨機化的數據結構,可以被看做二叉樹的一個變種,它在性能上和紅黑樹,AVL樹不相上下,但是跳錶的原理非常簡單,目前在Redis和LeveIDB中都有用到。 它採用隨機技術決定鏈表中哪些節點應增加向前指針以及在該節點中應增加多少個指針。跳錶結構的頭節點需有足夠的指針域,以滿足可能構造最大級數的需要,而尾節點不需要指針域。 採用這種隨機技術,跳錶中的搜索、插入、刪除操作的時間均為O(logn),然而,最壞情況下時間複雜性卻變成O(n)。相比之下,在一個有序數組或鏈表中進行插入/刪除操作的時間為O(n),最壞情況下為O(n)。 範圍查找代碼import java.util.*; import java.util.concurrent.ConcurrentSkipListMap; public class TreeMapAndSkipListMapTest { public static void main(String[] args) { Map<Long, String> map = new HashMap<>(); map.put(2L, "aaa2"); map.put(1L, "aaa1"); map.put(5L, "aaa5"); map.put(3L, "aaa3"); map.put(4L, "aaa4"); treeMapTest(map); skipListMapTest(map); } private static void treeMapTest(Map<Long, String> map) { TreeMap<Long, String> treeMap = new TreeMap<>(); treeMap.putAll(map); //自然序輸出 System.out.println("TreeMap自然序輸出"); for (Map.Entry<Long, String> entry : treeMap.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); } //尋找範圍 System.out.println("TreeMap輸出2-3的值"); SortedMap<Long, String> sortedMap = treeMap.subMap(2L, 4L); for (Map.Entry<Long, String> entry : sortedMap.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); } } private static void skipListMapTest(Map<Long, String> map) { ConcurrentSkipListMap<Long, String> skipListMap = new ConcurrentSkipListMap(); skipListMap.putAll(map); //自然序輸出 System.out.println("ConcurrentSkipListMap自然序輸出"); for (Map.Entry<Long, String> entry : skipListMap.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); } //尋找範圍 System.out.println("ConcurrentSkipListMap輸出2-3的值"); SortedMap<Long, String> sortedMap = skipListMap.subMap(2L, 4L); for (Map.Entry<Long, String> entry : sortedMap.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); } } }
跳錶原理:https://blog.csdn.net/belalds/article/details/113175003