跳跃表结构

//跳跃表节点typedef struct zskiplistNode {sds ele;double score;struct zskiplistNode *backward;struct zskiplistLevel {struct zskiplistNode *forward;unsigned long span;} level[];} zskiplistNode;//跳跃表typedef struct zskiplist {struct zskiplistNode *header, *tail;unsigned long length;int level;} zskiplist;
跳跃表的插入
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {//存储插入节点zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;//存储spanunsigned int rank[ZSKIPLIST_MAXLEVEL];int i, level;serverAssert(!isnan(score));x = zsl->header;//找到forward节点for (i = zsl->level-1; i >= 0; i--) {/* store rank that is crossed to reach the insert position */rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];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))){rank[i] += x->level[i].span;x = x->level[i].forward;}update[i] = x;}//随机生成level==> (生成的level: 2, 当前的level: 1)level = zslRandomLevel();//生成的level大于跳跃表当前的levelif (level > zsl->level) {//1-->2, 新生成的level直接指向null,span为跳跃表的长度for (i = zsl->level; i < level; i++) {rank[i] = 0;update[i] = zsl->header;update[i]->level[i].span = zsl->length;}zsl->level = level;}//创建跳跃表节点x = zslCreateNode(level,score,ele);//从最底层一直处理到最高层for (i = 0; i < level; i++) {//原来 a-->b//现在 a-->c-->b//a = update[i]->level[i]--> b=update[i]->level[i].forward//处理链表的逻辑,只不过切换成了多层链表 层=level[i].forward==next指针x->level[i].forward = update[i]->level[i].forward;update[i]->level[i].forward = x;/* update span covered by update[i] as x is inserted here */x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);update[i]->level[i].span = (rank[0] - rank[i]) + 1;}/* increment span for untouched levels */for (i = level; i < zsl->level; i++) {update[i]->level[i].span++;}x->backward = (update[0] == zsl->header) ? NULL : update[0];if (x->level[0].forward)x->level[0].forward->backward = x;elsezsl->tail = x;zsl->length++;return x;}
Java实现跳跃表
package io.github.chenshun00.data.list;import java.util.Arrays;/*** <ul>* <li>1、一个跳表应该有几个层组成,第一层包含所有的元素</li>* <li>2、每一层都是有序链表</li>* <li>3、如果元素x出现在第i层,则所有比i小的层都包含x</li>* <li>4、第i层的元素通过一个down指针指向下一层拥有相同值的元素</li>* </ul>** @author chenshun00@gmail.com* @since 2022/2/12 3:37 下午*/public class SkipList<E> {private static final double p = 0.25D;int MAX_LEVEL = 32;/*** 跳表实际层数*/int level;/*** 跳表头节点*/SkipListNode<E> header;/*** 创建节点** @param level 节点所在层数* @param key 节点key* @param value 节点value* @return {@link SkipListNode<E>}*/private SkipListNode<E> createNode(int level, int key, E value) {return new SkipListNode<E>(key, value, level);}/*** 初始化跳跃表* 1、初始化level为1级* 2、填充header的的next指针为null*/public SkipList() {this.level = 0;this.header = createNode(MAX_LEVEL, Integer.MIN_VALUE, null);for (int i = 0; i < MAX_LEVEL; i++) {this.header.forwards[i] = null;}}/*** 添加节点到跳跃表** @param key ke3y* @param value value*/public void add(int key, E value) {final int randomLevel = getRandomLevel();final SkipListNode<E> node = createNode(randomLevel, key, value);//从高层开始向底层遍历,为每一层补充节点信息,操作方式同链表for (int i = level - 1; i >= 0; i--) {SkipListNode<E> closable = header;//找到这一层的下一个节点while (closable.forwards[i] != null) {if (key == closable.forwards[i].key) {closable.forwards[i].value = value;return;} else if (key > closable.forwards[i].key) {closable = closable.forwards[i];} else {break;}}if (randomLevel > i) {if (closable.forwards[i] == null) {closable.forwards[i] = node;} else {final SkipListNode<E> next = closable.forwards[i];closable.forwards[i] = node;node.forwards[i] = next;}}}if (randomLevel > level) { //如果随机出来的层数比当前的层数还大,那么超过currentLevel的head 直接指向newNodefor (int i = level; i < randomLevel; i++) {header.forwards[i] = node;}this.level = randomLevel;}}public E get(int key) {SkipListNode<E> closable = header;for (int i = level - 1; i >= 0; i--) {//找到这一层的下一个节点while (closable.forwards[i] != null) {if (key == closable.forwards[i].key) {return closable.forwards[i].value;} else if (key > closable.forwards[i].key) {closable = closable.forwards[i];} else {break;}}if (closable.forwards[i] != null && closable.forwards[i].key == key) {return closable.forwards[i].value;}}return null;}public void remove(int key) {SkipListNode<E> closable = header;for (int i = level - 1; i >= 0; i--) {//找到这一层的下一个节点while (closable.forwards[i] != null) {if (key > closable.forwards[i].key) {closable = closable.forwards[i];} else {break;}}if (closable.forwards[i] != null && closable.forwards[i].key == key) {final SkipListNode<E> current = closable.forwards[i];final SkipListNode<E> next = current.forwards[i];closable.forwards[i] = next;}}}public void printList() {for (int i = level - 1; i >= 0; i--) {SkipListNode<E> curNode = this.header.forwards[i];System.out.print("HEAD->");while (curNode != null) {String line = String.format("(%s,%s)->", curNode.key, curNode.value);System.out.print(line);curNode = curNode.forwards[i];}System.out.println("NIL");}}private int getRandomLevel() {int lvl = 1;//Math.random() 返回一个介于 [0,1) 之间的数字while (lvl < MAX_LEVEL && Math.random() < p) {lvl++;}return lvl;}private static class SkipListNode<E> {/*** key 信息* <p>* 这个是什么?index 吗?*/int key;/*** 存放的元素*/E value;/*** 向前的指针* <p>* 跳表是多层的,这个向前的指针,最多和层数一样。** @since 0.0.4*/SkipListNode<E>[] forwards;@SuppressWarnings("all")public SkipListNode(int key, E value, int level) {this.key = key;this.value = value;this.forwards = new SkipListNode[level];}@Overridepublic String toString() {return "SkipListNode{" +"key=" + key +", value=" + value +", forwards=" + Arrays.toString(forwards) +'}';}}}
