HOME/Articles/

ifndef SKIPLIST_H_

Article Outline
#ifndef SKIPLIST_H_
#define SKIPLIST_H_

#include <stdio.h>
#include <stdlib.h>

#define MAX_LEVEL 12

struct Skiplist {

    struct Node {
        Node(int k, int v, int l) : key(k), value(v) {
            forwards = new Node*[l];
            for (int i = 0; i < l; ++i)
                forwards[i] = nullptr;
        }
        ~Node() {
            delete[] forwards;
        }

        int key;
        int value;
        Node **forwards;
    };

    int level;
    Node *header;

    Skiplist() {
        level = 0;
        header = new Node(0, 0, MAX_LEVEL);
    }

    int RandomLevel() {
        int k = 1;
        while (::rand() % 2) {
            k++;
        }

        k = (k < MAX_LEVEL)? k : MAX_LEVEL;
        return k - 1;
    }

    bool Insert(int k, int v) {
        Node *update[MAX_LEVEL];
        Node *p, *q = nullptr;
        p = header;

        // find the position from top
        for (int l = level; l >= 0; --l) {
            while ((q = p->forwards[l]) && q->key < k) {
                p = q;
            }

            update[l] = p;
        }

        if (q && q->key == k) return false;

        int l = RandomLevel();
        // Update skiplist level
        if (l > level) {
            for (int i = level+1; i <= l; ++i) {
                update[i] = header;
            }
            level = l;
        }

        // insert node per level
        q = new Node(k, v, k + 1);
        for (int i = 0; i <= k; ++i) {
            q->forwards[i] = update[i]->forwards[i];
            update[i]->forwards[i] = q;
        }

        return true;
    }

    bool Find(int k, int* v) {
        Node *p, *q = nullptr;
        p = header;

        for (int i = level; i >= 0; --i) {
            while ((q = p->forwards[i]) && q->key <= k) {
                if (q->key == k) {
                    *v = q->value;
                    return true;
                }
                p = q;
            }
        }

        return false;
    }

    bool Delete(int k) {
        Node *update[MAX_LEVEL];
        Node *p, *q = nullptr;
        p = header;

        // find the position from top
        for (int l = level; l >= 0; --l) {
            while ((q = p->forwards[l]) && q->key < k) {
                p = q;
            }

            update[l] = p;
        }

        if (q == nullptr || q->key != k) {
            return false;
        }

        // delete
        for (int i = 0; i <= level; ++i) {
            if (update[i]->forwards[i] == q) {
                update[i]->forwards[i] = q->forwards[i];
            }
        }

        delete q;

        for (int i = level; i >= 0; --i) {
            if (header->forwards[i] == nullptr)
                level--;
        }
        return true;
    }

    void Print() const {
        Node *p, *q = nullptr;
        for (int i = level; i >= 0; --i) {
            p = header;
            printf("%d: ", i);
            while (p->forwards[i]) {
                printf("%d -> ", p->forwards[i]->key);
                p = p->forwards[i];
            }
            printf("NULL\n");
        }

        printf("\n");
    }
};

#endif // SKIPLIST_H_