package class36; import java.util.ArrayList; public class Code02_SkipListMap { // 跳表的节点定义 public static class SkipListNode, V> { public K key; public V val; public ArrayList> nextNodes; public SkipListNode(K k, V v) { key = k; val = v; nextNodes = new ArrayList>(); } // 遍历的时候,如果是往右遍历到的null(next == null), 遍历结束 // 头(null), 头节点的null,认为最小 // node -> 头,node(null, "") node.isKeyLess(!null) true // node里面的key是否比otherKey小,true,不是false public boolean isKeyLess(K otherKey) { // otherKey == null -> false return otherKey != null && (key == null || key.compareTo(otherKey) < 0); } public boolean isKeyEqual(K otherKey) { return (key == null && otherKey == null) || (key != null && otherKey != null && key.compareTo(otherKey) == 0); } } public static class SkipListMap, V> { private static final double PROBABILITY = 0.5; // < 0.5 继续做,>=0.5 停 private SkipListNode head; private int size; private int maxLevel; public SkipListMap() { head = new SkipListNode(null, null); head.nextNodes.add(null); // 0 size = 0; maxLevel = 0; } // 从最高层开始,一路找下去, // 最终,找到第0层的 mostRightLessNodeInTree(K key) { if (key == null) { return null; } int level = maxLevel; SkipListNode cur = head; while (level >= 0) { // 从上层跳下层 // cur level -> level-1 cur = mostRightLessNodeInLevel(key, cur, level--); } return cur; } // 在level层里,如何往右移动 // 现在来到的节点是cur,来到了cur的level层,在level层上,找到 mostRightLessNodeInLevel(K key, SkipListNode cur, int level) { SkipListNode next = cur.nextNodes.get(level); while (next != null && next.isKeyLess(key)) { cur = next; next = cur.nextNodes.get(level); } return cur; } public boolean containsKey(K key) { if (key == null) { return false; } SkipListNode less = mostRightLessNodeInTree(key); SkipListNode next = less.nextNodes.get(0); return next != null && next.isKeyEqual(key); } // 新增、改value public void put(K key, V value) { if (key == null) { return; } // 0层上,最右一个,< key 的Node -> >key SkipListNode less = mostRightLessNodeInTree(key); SkipListNode find = less.nextNodes.get(0); if (find != null && find.isKeyEqual(key)) { find.val = value; } else { // find == null 8 7 9 size++; int newNodeLevel = 0; while (Math.random() < PROBABILITY) { newNodeLevel++; } // newNodeLevel while (newNodeLevel > maxLevel) { head.nextNodes.add(null); maxLevel++; } SkipListNode newNode = new SkipListNode(key, value); for (int i = 0; i <= newNodeLevel; i++) { newNode.nextNodes.add(null); } int level = maxLevel; SkipListNode pre = head; while (level >= 0) { // level 层中,找到最右的 < key 的节点 pre = mostRightLessNodeInLevel(key, pre, level); if (level <= newNodeLevel) { newNode.nextNodes.set(level, pre.nextNodes.get(level)); pre.nextNodes.set(level, newNode); } level--; } } } public V get(K key) { if (key == null) { return null; } SkipListNode less = mostRightLessNodeInTree(key); SkipListNode next = less.nextNodes.get(0); return next != null && next.isKeyEqual(key) ? next.val : null; } public void remove(K key) { if (containsKey(key)) { size--; int level = maxLevel; SkipListNode pre = head; while (level >= 0) { pre = mostRightLessNodeInLevel(key, pre, level); SkipListNode next = pre.nextNodes.get(level); // 1)在这一层中,pre下一个就是key // 2)在这一层中,pre的下一个key是>要删除key if (next != null && next.isKeyEqual(key)) { // free delete node memory -> C++ // level : pre -> next(key) -> ... pre.nextNodes.set(level, next.nextNodes.get(level)); } // 在level层只有一个节点了,就是默认节点head if (level != 0 && pre == head && pre.nextNodes.get(level) == null) { head.nextNodes.remove(level); maxLevel--; } level--; } } } public K firstKey() { return head.nextNodes.get(0) != null ? head.nextNodes.get(0).key : null; } public K lastKey() { int level = maxLevel; SkipListNode cur = head; while (level >= 0) { SkipListNode next = cur.nextNodes.get(level); while (next != null) { cur = next; next = cur.nextNodes.get(level); } level--; } return cur.key; } public K ceilingKey(K key) { if (key == null) { return null; } SkipListNode less = mostRightLessNodeInTree(key); SkipListNode next = less.nextNodes.get(0); return next != null ? next.key : null; } public K floorKey(K key) { if (key == null) { return null; } SkipListNode less = mostRightLessNodeInTree(key); SkipListNode next = less.nextNodes.get(0); return next != null && next.isKeyEqual(key) ? next.key : less.key; } public int size() { return size; } } // for test public static void printAll(SkipListMap obj) { for (int i = obj.maxLevel; i >= 0; i--) { System.out.print("Level " + i + " : "); SkipListNode cur = obj.head; while (cur.nextNodes.get(i) != null) { SkipListNode next = cur.nextNodes.get(i); System.out.print("(" + next.key + " , " + next.val + ") "); cur = next; } System.out.println(); } } public static void main(String[] args) { SkipListMap test = new SkipListMap<>(); printAll(test); System.out.println("======================"); test.put("A", "10"); printAll(test); System.out.println("======================"); test.remove("A"); printAll(test); System.out.println("======================"); test.put("E", "E"); test.put("B", "B"); test.put("A", "A"); test.put("F", "F"); test.put("C", "C"); test.put("D", "D"); printAll(test); System.out.println("======================"); System.out.println(test.containsKey("B")); System.out.println(test.containsKey("Z")); System.out.println(test.firstKey()); System.out.println(test.lastKey()); System.out.println(test.floorKey("D")); System.out.println(test.ceilingKey("D")); System.out.println("======================"); test.remove("D"); printAll(test); System.out.println("======================"); System.out.println(test.floorKey("D")); System.out.println(test.ceilingKey("D")); } }