跳跃表结构

image.png

  1. //跳跃表节点
  2. typedef struct zskiplistNode {
  3. sds ele;
  4. double score;
  5. struct zskiplistNode *backward;
  6. struct zskiplistLevel {
  7. struct zskiplistNode *forward;
  8. unsigned long span;
  9. } level[];
  10. } zskiplistNode;
  11. //跳跃表
  12. typedef struct zskiplist {
  13. struct zskiplistNode *header, *tail;
  14. unsigned long length;
  15. int level;
  16. } zskiplist;

跳跃表的插入

  1. zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
  2. //存储插入节点
  3. zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
  4. //存储span
  5. unsigned int rank[ZSKIPLIST_MAXLEVEL];
  6. int i, level;
  7. serverAssert(!isnan(score));
  8. x = zsl->header;
  9. //找到forward节点
  10. for (i = zsl->level-1; i >= 0; i--) {
  11. /* store rank that is crossed to reach the insert position */
  12. rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
  13. while (x->level[i].forward && (x->level[i].forward->score < score || (x->level[i].forward->score == score && sdscmp(x->level[i].forward->ele,ele) < 0)))
  14. {
  15. rank[i] += x->level[i].span;
  16. x = x->level[i].forward;
  17. }
  18. update[i] = x;
  19. }
  20. //随机生成level==> (生成的level: 2, 当前的level: 1)
  21. level = zslRandomLevel();
  22. //生成的level大于跳跃表当前的level
  23. if (level > zsl->level) {
  24. //1-->2, 新生成的level直接指向null,span为跳跃表的长度
  25. for (i = zsl->level; i < level; i++) {
  26. rank[i] = 0;
  27. update[i] = zsl->header;
  28. update[i]->level[i].span = zsl->length;
  29. }
  30. zsl->level = level;
  31. }
  32. //创建跳跃表节点
  33. x = zslCreateNode(level,score,ele);
  34. //从最底层一直处理到最高层
  35. for (i = 0; i < level; i++) {
  36. //原来 a-->b
  37. //现在 a-->c-->b
  38. //a = update[i]->level[i]--> b=update[i]->level[i].forward
  39. //处理链表的逻辑,只不过切换成了多层链表 层=level[i].forward==next指针
  40. x->level[i].forward = update[i]->level[i].forward;
  41. update[i]->level[i].forward = x;
  42. /* update span covered by update[i] as x is inserted here */
  43. x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
  44. update[i]->level[i].span = (rank[0] - rank[i]) + 1;
  45. }
  46. /* increment span for untouched levels */
  47. for (i = level; i < zsl->level; i++) {
  48. update[i]->level[i].span++;
  49. }
  50. x->backward = (update[0] == zsl->header) ? NULL : update[0];
  51. if (x->level[0].forward)
  52. x->level[0].forward->backward = x;
  53. else
  54. zsl->tail = x;
  55. zsl->length++;
  56. return x;
  57. }

Java实现跳跃表

  1. package io.github.chenshun00.data.list;
  2. import java.util.Arrays;
  3. /**
  4. * <ul>
  5. * <li>1、一个跳表应该有几个层组成,第一层包含所有的元素</li>
  6. * <li>2、每一层都是有序链表</li>
  7. * <li>3、如果元素x出现在第i层,则所有比i小的层都包含x</li>
  8. * <li>4、第i层的元素通过一个down指针指向下一层拥有相同值的元素</li>
  9. * </ul>
  10. *
  11. * @author chenshun00@gmail.com
  12. * @since 2022/2/12 3:37 下午
  13. */
  14. public class SkipList<E> {
  15. private static final double p = 0.25D;
  16. int MAX_LEVEL = 32;
  17. /**
  18. * 跳表实际层数
  19. */
  20. int level;
  21. /**
  22. * 跳表头节点
  23. */
  24. SkipListNode<E> header;
  25. /**
  26. * 创建节点
  27. *
  28. * @param level 节点所在层数
  29. * @param key 节点key
  30. * @param value 节点value
  31. * @return {@link SkipListNode<E>}
  32. */
  33. private SkipListNode<E> createNode(int level, int key, E value) {
  34. return new SkipListNode<E>(key, value, level);
  35. }
  36. /**
  37. * 初始化跳跃表
  38. * 1、初始化level为1级
  39. * 2、填充header的的next指针为null
  40. */
  41. public SkipList() {
  42. this.level = 0;
  43. this.header = createNode(MAX_LEVEL, Integer.MIN_VALUE, null);
  44. for (int i = 0; i < MAX_LEVEL; i++) {
  45. this.header.forwards[i] = null;
  46. }
  47. }
  48. /**
  49. * 添加节点到跳跃表
  50. *
  51. * @param key ke3y
  52. * @param value value
  53. */
  54. public void add(int key, E value) {
  55. final int randomLevel = getRandomLevel();
  56. final SkipListNode<E> node = createNode(randomLevel, key, value);
  57. //从高层开始向底层遍历,为每一层补充节点信息,操作方式同链表
  58. for (int i = level - 1; i >= 0; i--) {
  59. SkipListNode<E> closable = header;
  60. //找到这一层的下一个节点
  61. while (closable.forwards[i] != null) {
  62. if (key == closable.forwards[i].key) {
  63. closable.forwards[i].value = value;
  64. return;
  65. } else if (key > closable.forwards[i].key) {
  66. closable = closable.forwards[i];
  67. } else {
  68. break;
  69. }
  70. }
  71. if (randomLevel > i) {
  72. if (closable.forwards[i] == null) {
  73. closable.forwards[i] = node;
  74. } else {
  75. final SkipListNode<E> next = closable.forwards[i];
  76. closable.forwards[i] = node;
  77. node.forwards[i] = next;
  78. }
  79. }
  80. }
  81. if (randomLevel > level) { //如果随机出来的层数比当前的层数还大,那么超过currentLevel的head 直接指向newNode
  82. for (int i = level; i < randomLevel; i++) {
  83. header.forwards[i] = node;
  84. }
  85. this.level = randomLevel;
  86. }
  87. }
  88. public E get(int key) {
  89. SkipListNode<E> closable = header;
  90. for (int i = level - 1; i >= 0; i--) {
  91. //找到这一层的下一个节点
  92. while (closable.forwards[i] != null) {
  93. if (key == closable.forwards[i].key) {
  94. return closable.forwards[i].value;
  95. } else if (key > closable.forwards[i].key) {
  96. closable = closable.forwards[i];
  97. } else {
  98. break;
  99. }
  100. }
  101. if (closable.forwards[i] != null && closable.forwards[i].key == key) {
  102. return closable.forwards[i].value;
  103. }
  104. }
  105. return null;
  106. }
  107. public void remove(int key) {
  108. SkipListNode<E> closable = header;
  109. for (int i = level - 1; i >= 0; i--) {
  110. //找到这一层的下一个节点
  111. while (closable.forwards[i] != null) {
  112. if (key > closable.forwards[i].key) {
  113. closable = closable.forwards[i];
  114. } else {
  115. break;
  116. }
  117. }
  118. if (closable.forwards[i] != null && closable.forwards[i].key == key) {
  119. final SkipListNode<E> current = closable.forwards[i];
  120. final SkipListNode<E> next = current.forwards[i];
  121. closable.forwards[i] = next;
  122. }
  123. }
  124. }
  125. public void printList() {
  126. for (int i = level - 1; i >= 0; i--) {
  127. SkipListNode<E> curNode = this.header.forwards[i];
  128. System.out.print("HEAD->");
  129. while (curNode != null) {
  130. String line = String.format("(%s,%s)->", curNode.key, curNode.value);
  131. System.out.print(line);
  132. curNode = curNode.forwards[i];
  133. }
  134. System.out.println("NIL");
  135. }
  136. }
  137. private int getRandomLevel() {
  138. int lvl = 1;
  139. //Math.random() 返回一个介于 [0,1) 之间的数字
  140. while (lvl < MAX_LEVEL && Math.random() < p) {
  141. lvl++;
  142. }
  143. return lvl;
  144. }
  145. private static class SkipListNode<E> {
  146. /**
  147. * key 信息
  148. * <p>
  149. * 这个是什么?index 吗?
  150. */
  151. int key;
  152. /**
  153. * 存放的元素
  154. */
  155. E value;
  156. /**
  157. * 向前的指针
  158. * <p>
  159. * 跳表是多层的,这个向前的指针,最多和层数一样。
  160. *
  161. * @since 0.0.4
  162. */
  163. SkipListNode<E>[] forwards;
  164. @SuppressWarnings("all")
  165. public SkipListNode(int key, E value, int level) {
  166. this.key = key;
  167. this.value = value;
  168. this.forwards = new SkipListNode[level];
  169. }
  170. @Override
  171. public String toString() {
  172. return "SkipListNode{" +
  173. "key=" + key +
  174. ", value=" + value +
  175. ", forwards=" + Arrays.toString(forwards) +
  176. '}';
  177. }
  178. }
  179. }