zoukankan      html  css  js  c++  java
  • 舍伍德算法 跳跃表增删查的实现

    #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];
        }
    }
  • 相关阅读:
    SQL Server 查看物理页存储
    Sql Server 孤立用户解决办法
    大文件下载
    UITableViewCell
    xib文件的使用
    UIToolbar
    UIView常见的属性和方法
    iOS的三种多线程技术:
    网络处理文件上传、获取文件MIMEType、其他HTTP请求方式
    转场动画过渡效果
  • 原文地址:https://www.cnblogs.com/8023spz/p/10222144.html
Copyright © 2011-2022 走看看