美文网首页
跳表skiplist实现

跳表skiplist实现

作者: RiceCake1122 | 来源:发表于2020-03-19 20:13 被阅读0次

    实现要点:每个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实现

          本文链接:https://www.haomeiwen.com/subject/vtcryhtx.html