舍伍德算法 跳跃表增删查的实现

Posted 8023spz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了舍伍德算法 跳跃表增删查的实现相关的知识,希望对你有一定的参考价值。

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#define MAX_LEVEL 10
#define MAX_Key 20
#define MAX_Value 40
#define inf 0x3f3f3f3f
using namespace std;

struct Node {
    int Key,Value,Id;
    Node **Next;
    Node() {
        Next = new Node *[1];
        Next[0] = NULL;
        Id = Value = 0;
        Key = -inf;
    }
    Node(int Size) {
        Id = Value = 0;
        Key = -inf;
        Next = new Node *[Size];
        for(int i = 0;i < Size;i ++) {
            Next[i] = NULL;
        }
    }
    ~Node() {
        delete [] Next;
    }
};
Node *NewNode(int level,int key,int value);
struct SkipList {
    int Level;
    Node *Header;
    int RandomLevel() {
        return rand() % MAX_LEVEL + 1;
    }
    SkipList() {
        Level = 0;
        srand(time(0));///构造时产生随机数种子
        Header = NewNode(MAX_LEVEL - 1,0,0);
    }
    ~SkipList() {
        delete Header;
    }
};
void UpdateId(SkipList *skiplist);///由于是辅助用 为了方便 不计效率
SkipList *NewSkipList();
bool Insert(SkipList *skiplist,int key,int value);
int Search(SkipList *skiplist,int key);
bool Delete(SkipList *skiplist,int key);
void Print(SkipList *skiplist);
int main() {
    int n = 10;
    bool vis[10000];
    srand(time(0));
    int Key,Value;
    SkipList *skiplist = NewSkipList();
    for(int i = 0;i < n;i ++) {///随机插入测试
        Key = rand() % MAX_Key;
        while(vis[Key]) Key = rand() % MAX_Key;
        vis[Key] = 1;
        Value = rand() % MAX_Value;
        Insert(skiplist,Key,Value);
        UpdateId(skiplist);
    }
    Print(skiplist);
    Key = rand() % MAX_Key;
    while(!vis[Key]) Key = rand() % MAX_Key;///随机查找测试
    printf("查找key%d对应的value为%d
",Key,Search(skiplist,Key));
    Delete(skiplist,Key);
    UpdateId(skiplist);
    printf("现在删除这个结点,跳越表结构发生变化:
");
    Print(skiplist);
    return 0;
}
Node *NewNode(int level,int key,int value) {
    Node *node = new Node(level);
    node -> Key = key;
    node -> Value = value;
    return node;
}
SkipList *NewSkipList() {
    SkipList *skiplist = new SkipList();
    return skiplist;
}
bool Insert(SkipList *skiplist,int key,int value) {
    Node *temp[MAX_LEVEL];
    Node *p = skiplist -> Header;
    int k = skiplist -> Level;
    for(int i = k - 1;i >= 0;i --) {
        while(p -> Next[i] && p -> Next[i] -> Key < key) {///找到合适位置
            p = p -> Next[i];
        }
        temp[i] = p; ///记录需要指向新结点的结点
    }
    p = p -> Next[0];
    if(p && p -> Key == key) return false;

    int level = skiplist -> RandomLevel();

    if(level > skiplist -> Level) {///随机级别 比 跳表的级别大
        for(int i = skiplist -> Level;i < level;i ++){///高出来的级别都是头部指向心结点
            temp[i] = skiplist -> Header;
        }
        skiplist -> Level = level;///更新级别
    }

    Node *node = NewNode(level,key,value);///待插入

    for(int i = 0;i < level;i ++) {
        node -> Next[i] = temp[i] -> Next[i];
        temp[i] -> Next[i] = node;
    }
    return true;
}
int Search(SkipList *skiplist,int key) {///从上往下找
    Node *p;
    int level = skiplist -> Level;
    for(int i = level - 1;i >= 0;i --){
        p = skiplist -> Header;
        while(p && p -> Key < key) {
            p = p -> Next[i];
        }
        if(p && p -> Key == key) return p -> Value;
    }
    return -inf;
}
bool Delete(SkipList *skiplist,int key) {
    cout<<key<<endl;
    Node *temp[MAX_LEVEL];
    Node *p;
    int level = skiplist -> Level;
    for(int i = level - 1;i >= 0;i --) {
        p = skiplist -> Header;
        while(p -> Next[i] && p -> Next[i] -> Key < key) {
            p = p -> Next[i];
        }
        temp[i] = p;///p -> Next[i] -> Key >= key
    }
    p = p -> Next[0];
    for(int i = 0;i < level;i ++) {
        if(temp[i] -> Next[i] == NULL || temp[i] -> Next[i] -> Key > key) {
            if(i == 0) return false;
            break;
        }
        temp[i] -> Next[i] = temp[i] -> Next[i] -> Next[i];
    }
    delete p;
    p = skiplist -> Header;///下面去掉无用层
    for(int i = level - 1;i >= 0;i --) {
        if(p != skiplist -> Header || p -> Next[i]) break;
        skiplist -> Level --;
    }
    return true;
}
void Print(SkipList *skiplist) {
    for(int i = skiplist -> Level - 1;i >= 0;i --) {
        int d = 0;
        Node *p = skiplist -> Header;
        printf("Header ");
        while(p = p -> Next[i]) {
            d = p -> Id - d - 1;
            while(d --) {
                printf("-----------");
            }
            printf("-> (%02d,%02d) ",p -> Key,p -> Value);
            d = p -> Id;
        }
        puts("");
    }
}
void UpdateId(SkipList *skiplist) {
    int d = 0;
    Node *p = skiplist -> Header;
    while(p) {
        p -> Id = d ++;
        p = p -> Next[0];
    }
}

 

以上是关于舍伍德算法 跳跃表增删查的实现的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 【随机化算法】搜索有序表【7.3.2】舍伍德(舍伍德)算法

Redis跳跃表原理分析与基本代码实现(java)

Redis跳跃表原理分析与基本代码实现(java)

自己实现Linkedlist,实现其常用的增删查的方法

跳跃表数据结构与算法分析

自己实现Arraylsit,实现其常用的几种增删该查的方法