跳表程序

#include <string.h>
#include <time.h>
#include <iostream>
#include <map>
#include <stdexcept>
template <typename KeyType, typename ValueType>
struct skip_list_node {
    KeyType key;
    ValueType value;
    skip_list_node *forwards[1] = {nullptr};
};
template <typename KeyType, typename ValueType>
struct skip_list {
    int level = 0;
    skip_list_node<KeyType, ValueType>*header = nullptr;
};
using KeyType = int;
using ValueType = int;
using NodeType = struct skip_list_node<KeyType, ValueType>;
using ListType = struct skip_list<KeyType, ValueType>;
using Node = NodeType *;
using List = ListType *;
#define NEW_LEVEL_NODE(level) (Node)malloc(sizeof(NodeType) + (level) * sizeof(Node))
#define NEW_LIST (List)malloc(sizeof(ListType))
class CSkipList {
public:
    CSkipList() {
        srand(time(NULL));
        skip_list_ = NEW_LIST;
        if (nullptr == skip_list_) {
            throw std::bad_alloc();
        }
        skip_list_->header = NEW_LEVEL_NODE(MAX_LEVEL);
        if (nullptr == skip_list_->header) {
            throw std::bad_alloc();
        }
        for (int i = 0;i < MAX_LEVEL;i++) {
            skip_list_->header->forwards[i] = nullptr;
        }
    }
    CSkipList(const CSkipList &) = delete;
    CSkipList & operator = (const CSkipList &) = delete;
    ~CSkipList() {
        free_list();
    }
public:
    static inline int get_random_level() {
        int level = rand() % (MAX_LEVEL +1);
        return level;
    }
public:
    bool insert(const KeyType &key, const ValueType &value) {
        Node update[MAX_LEVEL] = {0};
        if (false == locate_insert_location(key, update)) {
            return false;
        }
        int level = expand_level(update);
        insert_node(key, value, level, update);
        return true;
    }
    bool search(const KeyType &key, ValueType &value) {
        Node node = skip_list_->header;
        Node index_node = nullptr;
        for (int i = skip_list_->level - 1;i >= 0;i--) {
            while ((index_node = node->forwards[i]) && (index_node->key <= key)) {
                if (key == index_node->key) {
                    value = index_node->value;
                    return true;
                }
                node = index_node;
            }
        }
        return false;
    }
private:
    bool locate_insert_location(const KeyType &key, Node *update) {
        Node node = skip_list_->header;
        Node index_node = nullptr;
        for (int i = skip_list_->level - 1;i >= 0;i--) {
            while ((index_node = node->forwards[i]) && (index_node->key < key)) {
                node = index_node;
            }
            update[i] = node;
        }
        node = node->forwards[0];
        if (node != nullptr && key == node->key) {
            std::cerr << key << " has already existed." << std::endl;
            return false;
        }
        return true;
    }
    int expand_level(Node *update) {
        int level = get_random_level();
        int &cur_level = skip_list_->level;
        if (level > cur_level) {
            for (int i = cur_level;i < level;i++) {
                update[i] = skip_list_->header;
            }
            cur_level = level;
        }
        return level;
    }
    void insert_node(const KeyType &key, const ValueType &value, int level, Node *update) {
        int &cur_level = skip_list_->level;
        Node new_node = NEW_LEVEL_NODE(level);
        if (nullptr == new_node) {
             throw std::bad_alloc();
        }
        new_node->key = key;
        new_node->value = value;
        for (int i = level - 1;i >= 0;i--) {
            new_node->forwards[i] = update[i]->forwards[i];
            update[i]->forwards[i] = new_node;    // cost time
        }
        ++size_;
    }
    void free_list() {
        if (nullptr == skip_list_) {
            return;
        }
        Node p = skip_list_->header;
        Node q = nullptr;
        while (p != nullptr) {
            q = p->forwards[0];
            free(p);
            p = q;
        }
        free(skip_list_);
        skip_list_ = nullptr;
        size_ = 0;
    }
private:
    static const int MAX_LEVEL = 10;
private:
    List skip_list_ = nullptr;
    int size_ = 0;
};
const int N = 100;
void test_map() {
    std::map<int, int>mm;
    for (int i = 0;i < N;i++) {
        mm[i] = i;
    }
    for (int i = 0;i < N;i++) {
        if (mm.find(i) != end(mm)) {
        }
    }
}
void test_skip_list() {
    CSkipList skipList;
    for (int i = 0;i < N;i++) {
        skipList.insert(i, i);
    }
    int value = 0;
    for (int i = 0;i < N;i++) {
        if (true == skipList.search(i, value)) {
            // std::cout << "value = " << value << std::endl;
        }
    }
}
int main() {
    // test_map();     // 9.559s
    test_skip_list();   // > 4m50.766s

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值