最新做了一些题,碰巧看到一道题是实现一个跳表, 对 跳表 早有耳闻,从 ES, Redis 的一些资料中隐约看到过这个名字,以前粗略了解了一下跳表的接口和复杂度,觉得是个小平衡树,真正学习后发现它比平衡树简单多了,但是性能却不差平衡树,真是一种代码性价比极高的数据结构。
    看别人题解实现跳表代码很少,觉得是我上我也行的程度。就找了几篇文章学习,自己动手实现,写完一对比,行也不行,行的是功能都实现了,不行的是别人的版本速度比我的版本快10倍!而且代码巧妙又优雅。
    先贴一下我的实现

    1. import random
    2. MAX_LEVEL = 16
    3. class Node:
    4. def __init__(self, val=0):
    5. self.val = val
    6. self.right = None
    7. self.down = None
    8. def get_level():
    9. # 1/2 是最下层,1/4是第二层。。。。
    10. init_num = 1
    11. p = 1 / 2
    12. while random.random() < p and init_num < MAX_LEVEL:
    13. init_num += 1
    14. return init_num
    15. class Skiplist:
    16. def __init__(self):
    17. self.left = [Node(-1) for _ in range(16)]
    18. for i in range(15):
    19. self.left[i].down = self.left[i + 1]
    20. self.head = self.left[0]
    21. def search(self, target: int) -> bool:
    22. prv = self.head
    23. while prv:
    24. if prv.val == target:
    25. return True
    26. elif not prv.right or prv.right.val > target:
    27. prv = prv.down
    28. else:
    29. prv = prv.right
    30. return False
    31. def add(self, num: int) -> None:
    32. level = get_level() # 3 self.left[13]
    33. print(level)
    34. level_head = self.head
    35. for _ in range(MAX_LEVEL - level):
    36. level_head = level_head.down
    37. self._add(level_head, num)
    38. def _add(self, prv_head, num):
    39. while prv_head:
    40. if not prv_head.right or num < prv_head.right.val:
    41. right = prv_head.right
    42. node = Node(num)
    43. prv_head.right = node
    44. node.right = right
    45. node.down = self._add(prv_head.down, num)
    46. return node
    47. else:
    48. prv_head = prv_head.right
    49. def erase(self, num: int) -> bool:
    50. is_removed = False
    51. prv = self.head
    52. while prv:
    53. if not prv.right or prv.right.val > num:
    54. prv = prv.down
    55. elif prv.right.val == num:
    56. prv.right = prv.right.right
    57. prv = prv.down
    58. is_removed = True
    59. else:
    60. prv = prv.right
    61. return is_removed
    62. def print(self):
    63. _list = [[] for _ in range(MAX_LEVEL)]
    64. for i in range(MAX_LEVEL):
    65. cur = self.left[i]
    66. while cur:
    67. _list[i].append(cur.val)
    68. cur = cur.right
    69. print(_list[i], len(_list[i]))
    70. sk = Skiplist()
    71. for i in range(1, 100):
    72. sk.add(i)
    73. print(sk.erase(0))
    74. sk.print()

    别人的实现

    1. import random
    2. class Node:
    3. def __init__(self, val=0):
    4. self.val = val
    5. self.right = None
    6. self.down = None
    7. class Skiplist:
    8. def __init__(self):
    9. self.left = [Node(-1) for _ in range(16)]
    10. self.right = [Node(20001) for _ in range(16)]
    11. for i in range(15):
    12. self.left[i].right = self.right[i]
    13. self.left[i].down = self.left[i + 1]
    14. self.right[i].down = self.right[i + 1]
    15. self.left[-1].right = self.right[-1]
    16. self.head = self.left[0]
    17. def search(self, target: int) -> bool:
    18. cur = self.head
    19. while cur:
    20. if cur.right.val > target:
    21. cur = cur.down
    22. elif cur.right.val < target:
    23. cur = cur.right
    24. else:
    25. return True
    26. return False
    27. def add(self, num: int) -> None:
    28. cur = self.head
    29. stack = []
    30. while cur:
    31. if cur.right.val >= num:
    32. stack.append(cur)
    33. cur = cur.down
    34. else:
    35. cur = cur.right
    36. pre = None
    37. while stack:
    38. cur = stack.pop()
    39. node = Node(num)
    40. node.right = cur.right
    41. cur.right = node
    42. if pre:
    43. node.down = pre
    44. pre = node
    45. if random.randint(0, 1):
    46. break
    47. def erase(self, num: int) -> bool:
    48. cur = self.head
    49. is_removed = False
    50. while cur:
    51. if cur.right.val >= num:
    52. if cur.right.val == num:
    53. is_removed = True
    54. cur.right = cur.right.right
    55. cur = cur.down
    56. else:
    57. cur = cur.right
    58. return is_removed
    59. def print(self):
    60. _list = [[] for _ in range(16)]
    61. for i in range(16):
    62. cur = self.left[i]
    63. while cur:
    64. _list[i].append(cur.val)
    65. cur = cur.right
    66. print(_list[i], len(_list[i]))
    67. sk = Skiplist()
    68. for i in range(1, 100):
    69. sk.add(i)
    70. print(sk.search(99))
    71. sk.print()