• 跳表C语言


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

    leetcode原题,代码如下

    1. #define MAX(a, b) ((a) > (b) ? (a) : (b))
    2. const int MAX_LEVEL = 32;
    3. const int P_FACTOR = RAND_MAX >> 2;
    4. typedef struct SkiplistNode {
    5. int val;
    6. int maxLevel;
    7. struct SkiplistNode **forward;
    8. } SkiplistNode;
    9. typedef struct {
    10. SkiplistNode *head;
    11. int level;
    12. } Skiplist;
    13. SkiplistNode *skiplistNodeCreat(int val, int maxLevel) {
    14. SkiplistNode *obj = (SkiplistNode *)malloc(sizeof(SkiplistNode));
    15. obj->val = val;
    16. obj->maxLevel = maxLevel;
    17. obj->forward = (SkiplistNode **)malloc(sizeof(SkiplistNode *) * maxLevel);
    18. for (int i = 0; i < maxLevel; i++) {
    19. obj->forward[i] = NULL;
    20. }
    21. return obj;
    22. }
    23. void skiplistNodeFree(SkiplistNode* obj) {
    24. if (obj->forward) {
    25. free(obj->forward);
    26. obj->forward = NULL;
    27. obj->maxLevel = 0;
    28. }
    29. free(obj);
    30. }
    31. Skiplist* skiplistCreate() {
    32. Skiplist *obj = (Skiplist *)malloc(sizeof(Skiplist));
    33. obj->head = skiplistNodeCreat(-1, MAX_LEVEL);
    34. obj->level = 0;
    35. srand(time(NULL));
    36. return obj;
    37. }
    38. static inline int randomLevel() {
    39. int lv = 1;
    40. /* 随机生成 lv */
    41. while (rand() < P_FACTOR && lv < MAX_LEVEL) {
    42. lv++;
    43. }
    44. return lv;
    45. }
    46. bool skiplistSearch(Skiplist* obj, int target) {
    47. SkiplistNode *curr = obj->head;
    48. for (int i = obj->level - 1; i >= 0; i--) {
    49. /* 找到第 i 层小于且最接近 target 的元素*/
    50. while (curr->forward[i] && curr->forward[i]->val < target) {
    51. curr = curr->forward[i];
    52. }
    53. }
    54. curr = curr->forward[0];
    55. /* 检测当前元素的值是否等于 target */
    56. if (curr && curr->val == target) {
    57. return true;
    58. }
    59. return false;
    60. }
    61. void skiplistAdd(Skiplist* obj, int num) {
    62. SkiplistNode *update[MAX_LEVEL];
    63. SkiplistNode *curr = obj->head;
    64. for (int i = obj->level - 1; i >= 0; i--) {
    65. /* 找到第 i 层小于且最接近 num 的元素*/
    66. while (curr->forward[i] && curr->forward[i]->val < num) {
    67. curr = curr->forward[i];
    68. }
    69. update[i] = curr;
    70. }
    71. int lv = randomLevel();
    72. if (lv > obj->level) {
    73. for (int i = obj->level; i < lv; i++) {
    74. update[i] = obj->head;
    75. }
    76. obj->level = lv;
    77. }
    78. SkiplistNode *newNode = skiplistNodeCreat(num, lv);
    79. for (int i = 0; i < lv; i++) {
    80. /* 对第 i 层的状态进行更新,将当前元素的 forward 指向新的节点 */
    81. newNode->forward[i] = update[i]->forward[i];
    82. update[i]->forward[i] = newNode;
    83. }
    84. }
    85. bool skiplistErase(Skiplist* obj, int num) {
    86. SkiplistNode *update[MAX_LEVEL];
    87. SkiplistNode *curr = obj->head;
    88. for (int i = obj->level - 1; i >= 0; i--) {
    89. /* 找到第 i 层小于且最接近 num 的元素*/
    90. while (curr->forward[i] && curr->forward[i]->val < num) {
    91. curr = curr->forward[i];
    92. }
    93. update[i] = curr;
    94. }
    95. curr = curr->forward[0];
    96. /* 如果值不存在则返回 false */
    97. if (!curr || curr->val != num) {
    98. return false;
    99. }
    100. for (int i = 0; i < obj->level; i++) {
    101. if (update[i]->forward[i] != curr) {
    102. break;
    103. }
    104. /* 对第 i 层的状态进行更新,将 forward 指向被删除节点的下一跳 */
    105. update[i]->forward[i] = curr->forward[i];
    106. }
    107. skiplistNodeFree(curr);
    108. /* 更新当前的 level */
    109. while (obj->level > 1 && obj->head->forward[obj->level - 1] == NULL) {
    110. obj->level--;
    111. }
    112. return true;
    113. }
    114. void skiplistFree(Skiplist* obj) {
    115. for (SkiplistNode * curr = obj->head; curr; ) {
    116. SkiplistNode *prev = curr;
    117. curr = curr->forward[0];
    118. skiplistNodeFree(prev);
    119. }
    120. free(obj);
    121. }
    122. /**
    123. * Your Skiplist struct will be instantiated and called as such:
    124. * Skiplist* obj = skiplistCreate();
    125. * bool param_1 = skiplistSearch(obj, target);
    126. * skiplistAdd(obj, num);
    127. * bool param_3 = skiplistErase(obj, num);
    128. * skiplistFree(obj);
    129. */

  • 相关阅读:
    NodeMCU ESP8266 GPIO使用详解(图文并茂)
    [4G/5G/6G专题基础-160]: 5G双链接与MCG/SCG/PCell/PSCell/SCell
    Shell根据文本内容批量修改文件名(附完整代码)
    SQL note2:DIsks and Files
    Python(乱学)
    c# 泛型
    http和https的区别,以及https涉及到的加密过程
    系统升级丨酷雷曼4大功能优化,轻松完成VR全景制作
    做了Java5年crud了四年,靠着这份学习笔记,终从12K涨成了35K
    Win11如何更改默认下载路径?Win11更改默认下载路径的方法
  • 原文地址:https://blog.csdn.net/qq_41790844/article/details/133781197