leetcode1206. 设计跳表(跳表)

个人学习跳表网站:https://blog.csdn.net/pcwl1206/article/details/83512600
跳表思想类似于二分查找,只不过用在链表上。但是又不能弄成平衡的二分查找(保持平衡耗费的性能很高),所以加入随机数,随机高度,保证效率不会太低。
跳表的查询复杂度是O(lgn),仅插入或删除的复杂度是O(1),但是插入、删除之前需要先查询位置,所以还是O(lgn)
图不会画,还是看链接的地址吧。

该题java代码:

class Skiplist {
    private static final int MAX_LEVEL = 16;    // 结点的个数

    private int levelCount = 1;   // 索引的层级数

    private Node head = new Node();    // 头结点

    private Random random = new Random();

    public Skiplist() {

    }

    public boolean search(int target) {
        Node p = head;
        for (int i = levelCount - 1; i >= 0; --i) {
            while (p.next[i] != null && p.next[i].data < target) {
                p = p.next[i];
            }
        }
        if (p.next[0] != null && p.next[0].data == target) {
            return true;    // 找到,则返回原始链表中的结点
        } else {
            return false;
        }
    }

    public void add(int num) {
        int level = randomLevel();
        Node newNode = new Node();
        newNode.data = num;
        newNode.maxLevel = level;   // 通过随机函数改变索引层的结点布置
        Node update[] = new Node[level];
        for (int i = 0; i < level; ++i) {
            update[i] = head;
        }

        Node p = head;
        for (int i = level - 1; i >= 0; --i) {
            while (p.next[i] != null && p.next[i].data < num) {
                p = p.next[i];
            }
            update[i] = p;
        }

        for (int i = 0; i < level; ++i) {
            newNode.next[i] = update[i].next[i];
            update[i].next[i] = newNode;
        }
        if (levelCount < level) {
            levelCount = level;
        }
    }

    public boolean erase(int num) {
        boolean deleted = false;
        Node[] update = new Node[levelCount];
        Node p = head;
        for (int i = levelCount - 1; i >= 0; --i) {
            while (p.next[i] != null && p.next[i].data < num) {
                p = p.next[i];
            }
            update[i] = p;
        }

        if (p.next[0] != null && p.next[0].data == num) {
            for (int i = levelCount - 1; i >= 0; --i) {
                if (update[i].next[i] != null && update[i].next[i].data == num) {
                    update[i].next[i] = update[i].next[i].next[i];
                    deleted = true;
                }
            }
        }
        return deleted;
    }

    // 随机函数
    private int randomLevel() {
        int level = 1;
        for (int i = 1; i < MAX_LEVEL; ++i) {
            if (random.nextInt() % 2 == 1) {
                level++;
            }
        }

        return level;
    }

    // Node内部类
    public class Node {
        private int data = -1;
        private Node next[] = new Node[MAX_LEVEL];
        private int maxLevel = 0;
    }
}
发布了127 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_33321609/article/details/102796197
今日推荐