当前位置: 首页 > news >正文

跳表C语言

【C语言】算法学习·跳表_c语言跳表-CSDN博客

leetcode原题,代码如下

#define MAX(a, b) ((a) > (b) ? (a) : (b))
const int MAX_LEVEL = 32;
const int P_FACTOR = RAND_MAX >> 2;

typedef struct SkiplistNode {
    int val;
    int maxLevel;
    struct SkiplistNode **forward;
} SkiplistNode;

typedef struct {
    SkiplistNode *head;
    int level;
} Skiplist;

SkiplistNode *skiplistNodeCreat(int val, int maxLevel) {
    SkiplistNode *obj = (SkiplistNode *)malloc(sizeof(SkiplistNode));
    obj->val = val;
    obj->maxLevel = maxLevel;
    obj->forward = (SkiplistNode **)malloc(sizeof(SkiplistNode *) * maxLevel);
    for (int i = 0; i < maxLevel; i++) {
        obj->forward[i] = NULL;
    }
    return obj;
}

void skiplistNodeFree(SkiplistNode* obj) {
    if (obj->forward) {
        free(obj->forward);
        obj->forward = NULL;
        obj->maxLevel = 0;
    }
    free(obj);
}

Skiplist* skiplistCreate() {
    Skiplist *obj = (Skiplist *)malloc(sizeof(Skiplist));
    obj->head = skiplistNodeCreat(-1, MAX_LEVEL);
    obj->level = 0;
    srand(time(NULL));
    return obj;
}

static inline int randomLevel() {
    int lv = 1;
    /* 随机生成 lv */
    while (rand() < P_FACTOR && lv < MAX_LEVEL) {
        lv++;
    }
    return lv;
}

bool skiplistSearch(Skiplist* obj, int target) {
    SkiplistNode *curr = obj->head;
    for (int i = obj->level - 1; i >= 0; i--) {
        /* 找到第 i 层小于且最接近 target 的元素*/
        while (curr->forward[i] && curr->forward[i]->val < target) {
            curr = curr->forward[i];
        }
    }
    curr = curr->forward[0];
    /* 检测当前元素的值是否等于 target */
    if (curr && curr->val == target) {
        return true;
    } 
    return false;
}

void skiplistAdd(Skiplist* obj, int num) {
    SkiplistNode *update[MAX_LEVEL];
    SkiplistNode *curr = obj->head;
    for (int i = obj->level - 1; i >= 0; i--) {
        /* 找到第 i 层小于且最接近 num 的元素*/
        while (curr->forward[i] && curr->forward[i]->val < num) {
            curr = curr->forward[i];
        }
        update[i] = curr;
    }
    int lv = randomLevel();
    if (lv > obj->level) {
        for (int i = obj->level; i < lv; i++) {
            update[i] = obj->head;
        }
        obj->level = lv;
    }
    SkiplistNode *newNode = skiplistNodeCreat(num, lv);
    for (int i = 0; i < lv; i++) {
        /* 对第 i 层的状态进行更新,将当前元素的 forward 指向新的节点 */
        newNode->forward[i] = update[i]->forward[i];
        update[i]->forward[i] = newNode;
    }
}

bool skiplistErase(Skiplist* obj, int num) {
    SkiplistNode *update[MAX_LEVEL];
    SkiplistNode *curr = obj->head;
    for (int i = obj->level - 1; i >= 0; i--) {
        /* 找到第 i 层小于且最接近 num 的元素*/
        while (curr->forward[i] && curr->forward[i]->val < num) {
            curr = curr->forward[i];
        }
        update[i] = curr;
    }
    curr = curr->forward[0];
    /* 如果值不存在则返回 false */
    if (!curr || curr->val != num) {
        return false;
    }
    for (int i = 0; i < obj->level; i++) {
        if (update[i]->forward[i] != curr) {
            break;
        } 
        /* 对第 i 层的状态进行更新,将 forward 指向被删除节点的下一跳 */
        update[i]->forward[i] = curr->forward[i];
    }
    skiplistNodeFree(curr);
    /* 更新当前的 level */
    while (obj->level > 1 && obj->head->forward[obj->level - 1] == NULL) {
        obj->level--;
    }
    return true;
}

void skiplistFree(Skiplist* obj) {
    for (SkiplistNode * curr = obj->head; curr; ) {
        SkiplistNode *prev = curr;
        curr = curr->forward[0];
        skiplistNodeFree(prev);
    }
    free(obj);
}

/**
 * Your Skiplist struct will be instantiated and called as such:
 * Skiplist* obj = skiplistCreate();
 * bool param_1 = skiplistSearch(obj, target);
 
 * skiplistAdd(obj, num);
 
 * bool param_3 = skiplistErase(obj, num);
 
 * skiplistFree(obj);
*/

相关文章:

  • “华为杯”研究生数学建模竞赛2019年-【华为杯】F题:智能飞行器航迹规划模型(下)(附优秀论文及Pyhton代码实现)
  • 几种预训练模型微调方法和peft包的使用介绍
  • 奥威BI系统:做数据可视化大屏,又快又简单
  • SpringCloud小项目——订单积分商城 使用Nacos、Open Feign、Gateway、Sentinel技术栈
  • 一般香港服务器带宽选多大够用?(带宽计算方法)
  • 两数之和[中等]
  • cesium 地图蒙版遮罩效果
  • 短视频视频号矩阵系统源码独立部署开发对接
  • vue3使用腾讯地图选择地点
  • 【被误用的feof与文件操作读取结束的正确判定】
  • Adobe Premiere Pro:掌控视频剪辑的魔法之手,让你的创作腾飞!
  • 【算法|动态规划No.17】leetcode64. 最小路径和
  • jar 命令启动java 指定配置文件路径 jar如何启动
  • 「才得吹嘘身渐稳」,也来谈谈大模型
  • 95740-26-4|用于体内DNA合成的探针F-ara-EdU
  • MATLAB算法实战应用案例精讲-【图像处理】SLAM技术详解
  • CTF Misc(3)流量分析基础以及原理
  • Springboot 集成 Redis集群配置公网IP连接报私网IP连接失败问题
  • 数据挖掘与统计分析——T检验,正态性检验和一致性检验——代码复现
  • idea 插件推荐(持续更新)
  • 印度军方否认S-400防空系统被摧毁
  • 拿出压箱底作品,北京交响乐团让上海观众享受音乐盛宴
  • 方正证券总裁何亚刚到龄退休,54岁副总裁姜志军接棒
  • 教育部答澎湃:2025世界数字教育大会将发布系列重磅成果
  • 国家出口管制工作协调机制办公室部署开展打击战略矿产走私出口专项行动
  • 奥利弗·斯通回顾越战50周年:我们不善于总结历史教训