如何实现跳表?

跳表是一种基于链表的数据结构,它通过在链表中建立多级索引,从而实现快速的查找、插入和删除操作。

跳表的时间复杂度为$O(logn)$,其中$n$为元素的数量。

下面是跳表的Java实现:

import java.util.Random;

public class SkipList<K extends Comparable<K>, V> {
    private static final int MAX_LEVEL = 32;
    private Node<K, V> head;
    private int level;
    private int size;
    private Random random;

    public SkipList() {
        this.head = new Node<>(null, null, MAX_LEVEL);
        this.level = 1;
        this.size = 0;
        this.random = new Random();
    }

    public boolean contains(K key) {
        Node<K, V> node = findNode(key);
        return node != null && node.key.compareTo(key) == 0;
    }

    public V get(K key) {
        Node<K, V> node = findNode(key);
        return node != null ? node.value : null;
    }

    public void put(K key, V value) {
        Node<K, V>[] update = new Node[MAX_LEVEL];
        Node<K, V> node = head;
        for (int i = level - 1; i >= 0; i--) {
            while (node.next[i] != null && node.next[i].key.compareTo(key) < 0) {
                node = node.next[i];
            }
            update[i] = node;
        }
        node = node.next[0];
        if (node != null && node.key.compareTo(key) == 0) {
            node.value = value;
        } else {
            int newLevel = randomLevel();
            if (newLevel > level) {
                for (int i = level; i < newLevel; i++) {
                    update[i] = head;
                }
                level = newLevel;
            }
            node = new Node<>(key, value, newLevel);
            for (int i = 0; i < newLevel; i++) {
                node.next[i] = update[i].next[i];
                update[i].next[i] = node;
            }
            size++;
        }
    }

    public void remove(K key) {
        Node<K, V>[] update = new Node[MAX_LEVEL];
        Node<K, V> node = head;
        for (int i = level - 1; i >= 0; i--) {
            while (node.next[i] != null && node.next[i].key.compareTo(key) < 0) {
                node = node.next[i];
            }
            update[i] = node;
        }
        node = node.next[0];
        if (node != null && node.key.compareTo(key) == 0) {
            for (int i = 0; i < level; i++) {
                if (update[i].next[i] != node) {
                    break;
                }
                update[i].next[i] = node.next[i];
            }
            while (level > 1 && head.next[level - 1] == null) {
                level--;
            }
            size--;
        }
    }

    public int size() {
        return size;
    }

    private Node<K, V> findNode(K key) {
        Node<K, V> node = head;
        for (int i = level - 1; i >= 0; i--) {
            while (node.next[i] != null && node.next[i].key.compareTo(key) < 0) {
                node = node.next[i];
            }
        }
        return node.next[0];
    }

    private int randomLevel() {
        int level = 1;
        while (random.nextInt(2) == 1 && level < MAX_LEVEL) {
            level++;
        }
        return level;
 }

}