From f92c2ee6bc0453b30cc438e8e9314eb1730457ec Mon Sep 17 00:00:00 2001 From: Wenru Dong Date: Sun, 28 Oct 2018 20:46:23 +0000 Subject: [PATCH] Implementation of SkipList in python --- python/17_skiplist/skip_list.py | 91 +++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 python/17_skiplist/skip_list.py diff --git a/python/17_skiplist/skip_list.py b/python/17_skiplist/skip_list.py new file mode 100644 index 00000000..52069eb1 --- /dev/null +++ b/python/17_skiplist/skip_list.py @@ -0,0 +1,91 @@ +""" + An implementation of skip list. + The list stores positive integers without duplicates. + + 跳表的一种实现方法。 + 跳表中储存的是正整数,并且储存的是不重复的。 + + Author: Wenru +""" + +from typing import Optional +import random + +class ListNode: + + def __init__(self, data: Optional[int] = None): + self._data = data + self._forwards = [] # Forward pointers + +class SkipList: + + _MAX_LEVEL = 16 + + def __init__(self): + self._level_count = 1 + self._head = ListNode() + self._head._forwards = [None] * type(self)._MAX_LEVEL + + def find(self, value: int) -> Optional[ListNode]: + p = self._head + for i in range(self._level_count - 1, -1, -1): # Move down a level + while p._forwards[i] and p._forwards[i]._data < value: + p = p._forwards[i] # Move along level + + return p._forwards[0] if p._forwards[0] and p._forwards[0]._data == value else None + + def insert(self, value: int): + level = self._random_level() + if self._level_count < level: self._level_count = level + new_node = ListNode(value) + new_node._forwards = [None] * level + update = [self._head] * level # update is like a list of prevs + + p = self._head + for i in range(level - 1, -1, -1): + while p._forwards[i] and p._forwards[i]._data < value: + p = p._forwards[i] + + update[i] = p # Found a prev + + for i in range(level): + new_node._forwards[i] = update[i]._forwards[i] # new_node.next = prev.next + update[i]._forwards[i] = new_node # prev.next = new_node + + def delete(self, value): + update = [None] * self._level_count + p = self._head + for i in range(self._level_count - 1, -1, -1): + while p._forwards[i] and p._forwards[i]._data < value: + p = p._forwards[i] + update[i] = p + + if p._forwards[0] and p._forwards[0]._data == value: + for i in range(self._level_count - 1, -1, -1): + if update[i]._forwards[i] and update[i]._forwards[i]._data == value: + update[i]._forwards[i] = update[i]._forwards[i]._forwards[i] # Similar to prev.next = prev.next.next + + def _random_level(self, p: float = 0.5) -> int: + level = 1 + while random.random() < p and level < type(self)._MAX_LEVEL: + level += 1 + return level + + def __repr__(self) -> str: + values = [] + p = self._head + while p._forwards[0]: + values.append(str(p._forwards[0]._data)) + p = p._forwards[0] + return "->".join(values) + + +if __name__ == "__main__": + l = SkipList() + for i in range(10): + l.insert(i) + print(l) + p = l.find(7) + print(p._data) + l.delete(3) + print(l) \ No newline at end of file