Skip List基本操作

public class SkipList {

    public int height;
    public int size;
    public Random random = new Random();
    public Node head = new Node(0, null, true);

    public static class Node {
        public int key;
        public String value;
        public boolean isHeadNode = false;

        public Node left;
        public Node right;
        public Node up;
        public Node down;

        public Node(int key, String value) {
            this.key = key;
            this.value = value;
        }

        public Node(int key, String value, boolean isHeadNode) {
            this.key = key;
            this.value = value;
            this.isHeadNode = isHeadNode;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "key=" + key +
                    ", value='" + value + '\'' +
                    ", isHeadNode=" + isHeadNode +
                    '}';
        }
    }

    public Node findEntry(int key) {
        Node curr = head;

        while (true) {
            while (curr.right != null && key >= curr.right.key) {
                curr = curr.right;
            }

            if (curr.down != null) {
                curr = curr.down;
            } else {
                break;
            }
        }

        return curr;
    }

    public String get(int key) {
        Node target = findEntry(key);
        return !target.isHeadNode && target.key == key ? target.value : null;
    }

    public String put(int key, String value) {
        Node target = findEntry(key);

        //update exist node value
        if (!target.isHeadNode && target.key == key) {
            String oldValue = target.value;
            target.value = value;
            return oldValue;
        }

        //create new node at bottom list
        Node newNode = new Node(key, value);
        newNode.left = target;
        newNode.right = target.right;

        if (target.right != null) {
            target.right.left = newNode;
        }
        target.right = newNode;

        Node preBaseNode = newNode;

        int currLevel = 0;
        while (random.nextDouble() > 0.5) {

            //create new level
            if (currLevel >= this.height) {
                Node newHead = new Node(0, null, true);
                newHead.down = head;
                head.up = newHead;
                head = newHead;

                Node newLevelNode = new Node(key, value);
                newLevelNode.left = newHead;
                newHead.right = newLevelNode;

                newLevelNode.down = preBaseNode;
                preBaseNode.up = newLevelNode;

                preBaseNode = newLevelNode;

                this.height++;
            } else {

                //insert node in up level
                while (target.up == null) {
                    target = target.left;
                }
                target = target.up;

                //left right pointer
                Node newLevelNode = new Node(key, value);
                newLevelNode.left = target;
                newLevelNode.right = target.right;

                if (target.right != null) {
                    target.right.left = newLevelNode;
                }
                target.right = newLevelNode;

                //up down pointer
                newLevelNode.down = preBaseNode;
                preBaseNode.up = newLevelNode;

                preBaseNode = newLevelNode;
            }

            currLevel++;
        }

        this.size++;

        return null;
    }

    public String remove(int key) {
        Node target = findEntry(key);
        if (target.isHeadNode || target.key != key) {
            return null;
        }

        String value = target.value;

        while (target != null) {
            target.left.right = target.right;
            if (target.right != null) {
                target.right.left = target.left;
            }

            target = target.up;
        }

        return value;
    }

    public void print() {
        Node p = head;

        while (p != null) {
            System.out.print(p.key);

            Node curr = p;
            while (curr.right != null) {
                if (curr.right.down != null && curr.right.down.key != curr.right.key) {
                    throw new IllegalStateException(curr.right.key + " != " + curr.right.down.key);
                }

                System.out.print(" -> " + curr.right.key);
                curr = curr.right;
            }
            System.out.println();
            p = p.down;
        }
    }

    public static void main(String[] args) {
        SkipList skipList = new SkipList();

        //put
        skipList.put(3, "(3)");
        skipList.put(10, "(10)");
        skipList.put(1, "(1)");
        skipList.put(2, "(2)");
        skipList.put(5, "(5)");
        skipList.put(8, "(8)");
        skipList.put(9, "(9)");
        skipList.put(6, "(6)");

        skipList.print();

        //get
        System.out.println("skip list size:" + skipList.size);
        System.out.println("skip list height:" + skipList.height);
        System.out.println("search 5:" + skipList.get(5));
        System.out.println("search 4:" + skipList.get(4));

        //remove
        System.out.println("remove 5:" + skipList.remove(5));
        System.out.println("search 5:" + skipList.get(5));
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章