|
| 1 | +#include <stdio.h> |
| 2 | +#include <stdlib.h> |
| 3 | + |
| 4 | +#define MAX_LEVEL 32 /* Should be enough for 2^32 elements */ |
| 5 | + |
| 6 | +#define list_entry(ptr, type, member) \ |
| 7 | + ((type *)((char *)(ptr) - (size_t)(&((type *)0)->member))) |
| 8 | + |
| 9 | +#define skiplist_foreach(pos, end) \ |
| 10 | + for (; pos != end; pos = pos->next) |
| 11 | + |
| 12 | +#define skiplist_foreach_safe(pos, n, end) \ |
| 13 | + for (n = pos->next; pos != end; pos = n, n = pos->next) |
| 14 | + |
| 15 | +struct sk_link { |
| 16 | + struct sk_link *prev, *next; |
| 17 | +}; |
| 18 | + |
| 19 | +static inline void list_init(struct sk_link *link) |
| 20 | +{ |
| 21 | + link->prev = link; |
| 22 | + link->next = link; |
| 23 | +} |
| 24 | + |
| 25 | +static inline void |
| 26 | +__list_add(struct sk_link *link, struct sk_link *prev, struct sk_link *next) |
| 27 | +{ |
| 28 | + link->next = next; |
| 29 | + link->prev = prev; |
| 30 | + next->prev = link; |
| 31 | + prev->next = link; |
| 32 | +} |
| 33 | + |
| 34 | +static inline void __list_del(struct sk_link *prev, struct sk_link *next) |
| 35 | +{ |
| 36 | + prev->next = next; |
| 37 | + next->prev = prev; |
| 38 | +} |
| 39 | + |
| 40 | +static inline void list_add(struct sk_link *link, struct sk_link *prev) |
| 41 | +{ |
| 42 | + __list_add(link, prev, prev->next); |
| 43 | +} |
| 44 | + |
| 45 | +static inline void list_del(struct sk_link *link) |
| 46 | +{ |
| 47 | + __list_del(link->prev, link->next); |
| 48 | + list_init(link); |
| 49 | +} |
| 50 | + |
| 51 | +static inline int list_empty(struct sk_link *link) |
| 52 | +{ |
| 53 | + return link->next == link; |
| 54 | +} |
| 55 | + |
| 56 | +struct skiplist { |
| 57 | + int level; |
| 58 | + int count; |
| 59 | + struct sk_link head[MAX_LEVEL]; |
| 60 | +}; |
| 61 | + |
| 62 | +struct skipnode { |
| 63 | + int key; |
| 64 | + int value; |
| 65 | + struct sk_link link[0]; |
| 66 | +}; |
| 67 | + |
| 68 | +typedef struct { |
| 69 | + int size; |
| 70 | + int num; |
| 71 | + int *stack; |
| 72 | + struct skiplist *sklist; |
| 73 | +} MinStack; |
| 74 | + |
| 75 | +static struct skipnode *skipnode_new(int level, int key, int value) |
| 76 | +{ |
| 77 | + struct skipnode *node; |
| 78 | + node = malloc(sizeof(*node) + level * sizeof(struct sk_link)); |
| 79 | + if (node != NULL) { |
| 80 | + node->key = key; |
| 81 | + node->value = value; |
| 82 | + } |
| 83 | + return node; |
| 84 | +} |
| 85 | + |
| 86 | +static void skipnode_delete(struct skipnode *node) |
| 87 | +{ |
| 88 | + free(node); |
| 89 | +} |
| 90 | + |
| 91 | +static struct skiplist *skiplist_new(void) |
| 92 | +{ |
| 93 | + int i; |
| 94 | + struct skiplist *list = malloc(sizeof(*list)); |
| 95 | + if (list != NULL) { |
| 96 | + list->level = 1; |
| 97 | + list->count = 0; |
| 98 | + for (i = 0; i < sizeof(list->head) / sizeof(list->head[0]); i++) { |
| 99 | + list_init(&list->head[i]); |
| 100 | + } |
| 101 | + } |
| 102 | + return list; |
| 103 | +} |
| 104 | + |
| 105 | +static void skiplist_delete(struct skiplist *list) |
| 106 | +{ |
| 107 | + struct sk_link *n; |
| 108 | + struct sk_link *pos = list->head[0].next; |
| 109 | + skiplist_foreach_safe(pos, n, &list->head[0]) { |
| 110 | + struct skipnode *node = list_entry(pos, struct skipnode, link[0]); |
| 111 | + skipnode_delete(node); |
| 112 | + } |
| 113 | + free(list); |
| 114 | +} |
| 115 | + |
| 116 | +static int random_level(void) |
| 117 | +{ |
| 118 | + int level = 1; |
| 119 | + const double p = 0.25; |
| 120 | + while ((random() & 0xffff) < 0xffff * p) { |
| 121 | + level++; |
| 122 | + } |
| 123 | + return level > MAX_LEVEL ? MAX_LEVEL : level; |
| 124 | +} |
| 125 | + |
| 126 | +static struct skipnode *skiplist_search(struct skiplist *list, int key) |
| 127 | +{ |
| 128 | + struct skipnode *node; |
| 129 | + int i = list->level - 1; |
| 130 | + struct sk_link *pos = &list->head[i]; |
| 131 | + struct sk_link *end = &list->head[i]; |
| 132 | + |
| 133 | + for (; i >= 0; i--) { |
| 134 | + pos = pos->next; |
| 135 | + skiplist_foreach(pos, end) { |
| 136 | + node = list_entry(pos, struct skipnode, link[i]); |
| 137 | + if (node->key >= key) { |
| 138 | + end = &node->link[i]; |
| 139 | + break; |
| 140 | + } |
| 141 | + } |
| 142 | + if (node->key == key) { |
| 143 | + return node; |
| 144 | + } |
| 145 | + pos = end->prev; |
| 146 | + pos--; |
| 147 | + end--; |
| 148 | + } |
| 149 | + |
| 150 | + return NULL; |
| 151 | +} |
| 152 | + |
| 153 | +static struct skipnode *skiplist_insert(struct skiplist *list, int key, int value) |
| 154 | +{ |
| 155 | + int level = random_level(); |
| 156 | + if (level > list->level) { |
| 157 | + list->level = level; |
| 158 | + } |
| 159 | + |
| 160 | + struct skipnode *node = skipnode_new(level, key, value); |
| 161 | + if (node != NULL) { |
| 162 | + int i = list->level - 1; |
| 163 | + struct sk_link *pos = &list->head[i]; |
| 164 | + struct sk_link *end = &list->head[i]; |
| 165 | + |
| 166 | + for (; i >= 0; i--) { |
| 167 | + pos = pos->next; |
| 168 | + skiplist_foreach(pos, end) { |
| 169 | + struct skipnode *nd = list_entry(pos, struct skipnode, link[i]); |
| 170 | + if (nd->key >= key) { |
| 171 | + end = &nd->link[i]; |
| 172 | + break; |
| 173 | + } |
| 174 | + } |
| 175 | + pos = end->prev; |
| 176 | + if (i < level) { |
| 177 | + __list_add(&node->link[i], pos, end); |
| 178 | + } |
| 179 | + pos--; |
| 180 | + end--; |
| 181 | + } |
| 182 | + |
| 183 | + list->count++; |
| 184 | + } |
| 185 | + return node; |
| 186 | +} |
| 187 | + |
| 188 | +static void __remove(struct skiplist *list, struct skipnode *node, int level) |
| 189 | +{ |
| 190 | + int i; |
| 191 | + for (i = 0; i < level; i++) { |
| 192 | + list_del(&node->link[i]); |
| 193 | + if (list_empty(&list->head[i])) { |
| 194 | + list->level--; |
| 195 | + } |
| 196 | + } |
| 197 | + skipnode_delete(node); |
| 198 | + list->count--; |
| 199 | +} |
| 200 | + |
| 201 | +static void skiplist_remove(struct skiplist *list, int key) |
| 202 | +{ |
| 203 | + struct sk_link *n; |
| 204 | + struct skipnode *node; |
| 205 | + int i = list->level - 1; |
| 206 | + struct sk_link *pos = &list->head[i]; |
| 207 | + struct sk_link *end = &list->head[i]; |
| 208 | + |
| 209 | + for (; i >= 0; i--) { |
| 210 | + pos = pos->next; |
| 211 | + skiplist_foreach_safe(pos, n, end) { |
| 212 | + node = list_entry(pos, struct skipnode, link[i]); |
| 213 | + if (node->key > key) { |
| 214 | + end = &node->link[i]; |
| 215 | + break; |
| 216 | + } else if (node->key == key) { |
| 217 | + __remove(list, node, i + 1); |
| 218 | + return; |
| 219 | + } |
| 220 | + } |
| 221 | + pos = end->prev; |
| 222 | + pos--; |
| 223 | + end--; |
| 224 | + } |
| 225 | +} |
| 226 | + |
| 227 | +/** initialize your data structure here. */ |
| 228 | +static MinStack* minStackCreate(int maxSize) |
| 229 | +{ |
| 230 | + MinStack *obj = malloc(sizeof(*obj)); |
| 231 | + obj->size = maxSize; |
| 232 | + obj->num = 0; |
| 233 | + obj->stack = malloc(maxSize * sizeof(int)); |
| 234 | + obj->sklist = skiplist_new(); |
| 235 | + return obj; |
| 236 | +} |
| 237 | + |
| 238 | +static void minStackPush(MinStack* obj, int x) |
| 239 | +{ |
| 240 | + if (obj->num < obj->size) { |
| 241 | + obj->stack[obj->num++] = x; |
| 242 | + skiplist_insert(obj->sklist, x, x); |
| 243 | + } |
| 244 | +} |
| 245 | + |
| 246 | +static void minStackPop(MinStack* obj) |
| 247 | +{ |
| 248 | + if (obj->num > 0) { |
| 249 | + int key = obj->stack[--obj->num]; |
| 250 | + skiplist_remove(obj->sklist, key); |
| 251 | + } |
| 252 | +} |
| 253 | + |
| 254 | +static int minStackTop(MinStack* obj) |
| 255 | +{ |
| 256 | + return obj->num > 0 ? obj->stack[obj->num - 1] : 0; |
| 257 | +} |
| 258 | + |
| 259 | +static int minStackGetMin(MinStack* obj) |
| 260 | +{ |
| 261 | + if (obj->num > 0) { |
| 262 | + struct sk_link *pos = obj->sklist->head[0].next; |
| 263 | + struct skipnode *node = list_entry(pos, struct skipnode, link[0]); |
| 264 | + return node->key; |
| 265 | + } else { |
| 266 | + return 0; |
| 267 | + } |
| 268 | +} |
| 269 | + |
| 270 | +static void minStackFree(MinStack* obj) |
| 271 | +{ |
| 272 | + free(obj->stack); |
| 273 | + skiplist_delete(obj->sklist); |
| 274 | + free(obj); |
| 275 | +} |
| 276 | + |
| 277 | +int main(void) |
| 278 | +{ |
| 279 | + MinStack *obj = minStackCreate(5); |
| 280 | + minStackPush(obj, 2); |
| 281 | + minStackPush(obj, 0); |
| 282 | + minStackPush(obj, 3); |
| 283 | + minStackPush(obj, 0); |
| 284 | + printf("Min:%d\n", minStackGetMin(obj)); |
| 285 | + minStackPop(obj); |
| 286 | + //printf("Top:%d\n", minStackTop(obj)); |
| 287 | + printf("Min:%d\n", minStackGetMin(obj)); |
| 288 | + minStackPop(obj); |
| 289 | + printf("Min:%d\n", minStackGetMin(obj)); |
| 290 | + minStackPop(obj); |
| 291 | + printf("Min:%d\n", minStackGetMin(obj)); |
| 292 | + minStackFree(obj); |
| 293 | + return 0; |
| 294 | +} |
0 commit comments