跳表实现

参考redis以及http://www.cnblogs.com/liuhao/archive/2012/07/26/2610218.html

  • bskl.h

    
    #include <vector>
    
    using namespace std;
    class SkipListLevel;
    
    static const uint32_t MAX_LEVEL = 8;
    
    struct SkipListNode {
        double score; 
        SkipListNode* backward;
        std::vector<SkipListLevel> levels_vec;
    
        SkipListNode() : 
            score(0.0),
            backward(NULL) {
            levels_vec.reserve(MAX_LEVEL);
        }
    
        SkipListNode(int level, double score) {
            this->score = score;
            levels_vec.reserve(level);
        }
    
        ~SkipListNode() {}
    };
    
    struct SkipListLevel {
        int level;
        SkipListNode* forward;
    
        SkipListLevel() :
            level(-1),
            forward(NULL) {}
    
        ~SkipListLevel() {}
    };
    
    class SkipList {
    public:
        SkipList();
        ~SkipList();
        SkipListNode* insert_node(double score);
        bool delete_node(double score);
        bool search_node(double score);
        void print();
    
    private:
        int random_level();
        void delete_node_impl(SkipListNode* node, SkipListNode** update_nodes);
    
    private:
        SkipListNode* _header;
        SkipListNode* _tail;
        int _level;                             // 层数
        uint32_t _length;               // skiplist中元素个数
    };
  • bskl.cpp

    
    #include "bskl.h"
    
    
    #include <iostream>
    
    
    #include <stdlib.h>
    
    using namespace std;
    
    SkipList::SkipList() : _level(1), _length(0) {
        _header = new (std::nothrow)SkipListNode();
        for (uint32_t i = 0; i < MAX_LEVEL; ++i) {
            SkipListLevel sl_level;
            sl_level.level = i;
            sl_level.forward = NULL;
            _header->levels_vec.push_back(sl_level);
        }
        _header->backward = NULL;
    
        _tail = NULL;
    }
    
    SkipList::~SkipList() {
        SkipListNode *node = _header->levels_vec[0].forward;
        SkipListNode *next = NULL;
        if (_header != NULL) {
            delete _header;
            _header = NULL;
        }
    
        // delete node
        while (node) {
            next = node->levels_vec[0].forward;
            delete node;
            node = next;
        }
    }
    
    SkipListNode* SkipList::insert_node(double score) {
        SkipListNode* update_nodes[MAX_LEVEL]; 
        SkipListNode* node = _header;
        // 获取不同level要插入位置的前一个结点
        for (int i = _level - 1; i >=0; --i) {
            while ((node->levels_vec[i].forward != NULL) && 
                    (node->levels_vec[i].forward->score < score)) {
                node = node->levels_vec[i].forward;
            }
            update_nodes[i] = node;
        }
    
        // 获取随机层数
        int level = random_level();
        if (level > _level) {
            for (int i = _level; i < level; ++i) {
                // NOTICE
                update_nodes[i] = _header;
            }
            _level = level;
        }
    
        // 插入新节点 : 更新新结点的前向后向、新结点前一个结点的前向、新节点后一个结点的后向、tail结点
        // TODO 何时delete 
        node = new (std::nothrow) SkipListNode(level, score);
        for (int i = 0; i < level; ++i) {
            node->levels_vec[i].forward = update_nodes[i]->levels_vec[i].forward;
            update_nodes[i]->levels_vec[i].forward = node;
        }
        node->backward = (update_nodes[0] == _header ? NULL : update_nodes[0]);
    
        if (node->levels_vec[0].forward == NULL) {
            _tail = node;
        } else {
            node->levels_vec[0].forward->backward = node;
        }
    
        ++_length;
        return node;
    }
    
    bool SkipList::delete_node(double score) {
        SkipListNode* update_nodes[MAX_LEVEL]; 
        SkipListNode* node = _header;
        // 获取不同level要插入位置的前一个结点
        for (int i = _level - 1; i >=0; --i) {
            while ((node->levels_vec[i].forward != NULL) && 
                    (node->levels_vec[i].forward->score < score)) {
                node = node->levels_vec[i].forward;
            }
            update_nodes[i] = node;
        }
    
        node = node->levels_vec[0].forward;
        if ((node != NULL) && (node->score == score)) {
            delete_node_impl(node, update_nodes);
            return true;
        } 
    
        return false;
    }
    
    void SkipList::delete_node_impl(SkipListNode* node, SkipListNode** update_nodes) {
        // 更新forward
        for (int i = 0; i < _level; ++i) {
            if (update_nodes[i]->levels_vec[i].forward == node) {
                update_nodes[i]->levels_vec[i].forward = node->levels_vec[i].forward;
            }
        }
    
        // 更新backward
        if (node->levels_vec[0].forward != NULL) {
            node->levels_vec[0].forward->backward = node->backward; 
        } else {
            _tail = node->backward;
        }
    
        // 更新整体level
        while ((_level > 1) && (_header->levels_vec[_level - 1].forward == NULL)) {
            --_level;
        }
    
        // 更新结点数目
        --_length;
    
        delete node;
        node = NULL;
    }
    
    bool SkipList::search_node(double score) {
        SkipListNode* node = _header;
    
        int i = _level - 1;
        for (; i >= 0; --i) {
            while((node->levels_vec[i].forward != NULL)
                    && node->levels_vec[i].forward->score < score) {
                node = node->levels_vec[i].forward;
            }
        }
    
        node = node->levels_vec[0].forward;
        if ((node != NULL) && (node->score == score)) {
            cout << "Found [" << score << "]" << endl;
            return true;
        } else {
            cout << "Not Found [" << score << "]" << endl;
            return false;
        }
    }
    
    void SkipList::print() {
        SkipListNode* node = NULL;
        for (uint32_t i = 0; i < MAX_LEVEL; ++i) {
            cout << "LEVEL[" << i << "]" << endl;
            node = _header->levels_vec[i].forward;
            while (node != NULL) {
                cout << node->score << " -> ";
                node = node->levels_vec[i].forward;
            }
            cout << "NULL" << endl;
        }
    }
    
    int SkipList::random_level() {
        int level = 1;
        // 层数越高,概率越低
        while ((rand() & 0xFFFF) < (0xFFFF >> 2)) {
            ++level;
        }
        return level;
    }
  • main.cpp

    
    #include <iostream>
    
    
    #include "bskl.h"
    
    using namespace std;
    
    int main() {
        int num = 0;
        cout << "Input skiplist nodes num: ";
        cin >> num;
    
        cout << "=== Create Skip List ===" << endl;
        SkipList *sl = new (std::nothrow)SkipList();
        for (int i = 0; i < num; ++i) {
            sl->insert_node(i);
        }
    
        sl->print();
    
        cout << "=== Search Skip List ===" << endl;
        srand((unsigned)time(0));
        int limit = num + 10;
        for (int i = 0; i < num; ++i) {
            int value = rand() % limit;
            sl->search_node(value);
        }
    
        cout << "=== Delete Skip List ===" << endl;
        for (int i = 0; i < limit; i += 2) {
            if (sl->delete_node(i)) {
                cout << "delete [" << i << "] success" << endl; 
            } else {
                cout << "delete [" << i << "] not found" << endl;
            }
        }
    
        sl->print();
    
        return 0;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值