首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >SkipList 动手实现

SkipList 动手实现

作者头像
木鸟杂记
发布2021-09-26 16:50:53
发布2021-09-26 16:50:53
4370
举报
文章被收录于专栏:木鸟杂记木鸟杂记

在写完漫谈 LevelDB 数据结构(一):跳表(Skip List)后,想去动手实现一番,于是就想看看 LeetCode 有没有,结果翻了翻还真有。省去了搭架子和测试用例,美滋滋。

链接在此:https://leetcode.com/problems/design-skiplist/, 点击原文也可跳转。

我的实现:

代码语言:javascript
复制
class Skiplist {
private:
    const int kMaxHeight = 8;
    
    struct Node {
        int val, height;
        Node** next;
        
        Node(int v, int h) {
            val = v;
            height = h;
            next = new Node*[h];
            while (--h >= 0) next[h] = nullptr;
        }
        
        ~Node() {
           delete [] next;
        }
    };
    
    int getRandomHeight() {
        int h = 1;
        while (h < kMaxHeight && rand() % 4 == 1) ++h;
        
        return h;
    }
    
    
    Node* findGreaterOrEqual(int target, Node** prev) {
        Node* it = head;
        int level = kMaxHeight-1;
        while (true) {
            Node* next = it->next[level];
            if (next && next->val < target) {
                it = next;
            } else {
                if (prev)  prev[level] = it;
                
                if (level == 0) {
                    return next;
                } else {
                    --level;
                }
            }
        }
    }
    
    
    Node* head;
public:
    Skiplist() {
        head = new Node(0, kMaxHeight);
    }
    
    bool search(int target) {
        Node* node = findGreaterOrEqual(target, nullptr);
        return node != nullptr && node->val == target;
    }
    
    void add(int num) {
        Node* prev[kMaxHeight];
        findGreaterOrEqual(num, prev);
        
        Node* node = new Node(num, getRandomHeight());
        for (int i = 0; i < node->height; ++i) {
            node->next[i] = prev[i]->next[i];
            prev[i]->next[i] = node;
        }
    }
    
    bool erase(int num) {
        Node* prev[kMaxHeight];
        Node* to_del = findGreaterOrEqual(num, prev);
        if (to_del == nullptr || to_del->val != num) {
            return false;
        }
        
        for (int i = 0; i < to_del->height; ++i) {
            prev[i]->next[i] = to_del->next[i];
        }
        
        delete to_del;
        return true;
    }
};

/**
 * Your Skiplist object will be instantiated and called as such:
 * Skiplist* obj = new Skiplist();
 * bool param_1 = obj->search(target);
 * obj->add(num);
 * bool param_3 = obj->erase(num);
 */
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 木鸟杂记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档