跳表skiplist实现

实现要点:每个node持有上下左右四个指针。插入节点时随机生成层数,方法是不断的生成随机数,如果小于0.5则level加一,直到随机数大于0.5为止。根据层数在各层插入相应的节点。

public class SkipList {
    private final double POSSIBILITY = 0.5;
    private final int MAX_LEVEL = 32;
    Random rand = new Random();
    private SkipListNode head;
    private SkipListNode tail;
    private int level;

    public SkipList() {
        head = new SkipListNode(SkipListNode.MIN);
        tail = new SkipListNode(SkipListNode.MAX);
        head.right = tail;
        tail.left = head;
        level = 1;
    }

    public boolean contains(int key) {
        SkipListNode p = findNode(key);
        return p.key == key;
    }

    public void add(int key) {
        SkipListNode p = findNode(key);
        if (p.key == key) return;
        int lev = getLevel();
        SkipListNode downNode = null;
        for (int i=1; i<=lev; i++) {
            if (p == null) {
                SkipListNode newHead = new SkipListNode(SkipListNode.MIN);
                SkipListNode newTail = new SkipListNode(SkipListNode.MAX);
                linkRight(newHead, newTail);
                linkUp(head, newHead);
                head = newHead;
                linkUp(tail, newTail);
                tail = newTail;
                p = head;
                level++;
            }
            SkipListNode node = new SkipListNode(key);
            SkipListNode next = p.right;
            linkRight(p, node);
            linkRight(node, next);
            if (downNode != null) linkUp(downNode, node);
            while (!isHead(p) && p.up == null) p = p.left;
            p = p.up;
            downNode = node;
        }
    }

    public void print() {
        SkipListNode p = head;
        while (p != null) {
            String line = "h->";
            SkipListNode cur = p.right;
            while (!isTail(cur)) {
                line += cur.key + "->";
                cur = cur.right;
            }
            p = p.down;
            System.out.println(line);
        }
    }

    private SkipListNode findNode(int key) {
        SkipListNode p = head;
        while (true) {
            while (!isTail(p.right) && p.right.key <= key) p = p.right;
            if (p.down == null)
                break;
            else p = p.down;
        }
        return p;
    }

    private boolean isHead(SkipListNode p) {
        return p.key == SkipListNode.MIN;
    }

    private boolean isTail(SkipListNode p) {
        return p.key == SkipListNode.MAX;
    }

    private void linkUp(SkipListNode pre, SkipListNode node) {
        pre.up = node;
        node.down = pre;
    }

    private void linkRight(SkipListNode pre, SkipListNode node) {
        pre.right = node;
        node.left = pre;
    }

    private int getLevel() {
        int ans = 1;
        while (rand.nextDouble() < POSSIBILITY && ans < MAX_LEVEL) ans++;
        return ans;
    }

    static class SkipListNode {
        static final int MIN = Integer.MIN_VALUE;
        static final int MAX = Integer.MAX_VALUE;
        int key;
        SkipListNode up;
        SkipListNode right;
        SkipListNode down;
        SkipListNode left;
        public SkipListNode(int k) {
            this.key = k;
        }
    }
}

你可能感兴趣的:(跳表skiplist实现)