|
1 | 1 | #include <stdio.h> |
2 | 2 | #include <stdlib.h> |
3 | 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 | 4 | typedef struct { |
69 | | - int size; |
70 | 5 | int num; |
71 | | - int *stack; |
72 | | - struct skiplist *sklist; |
| 6 | + int min_idx; |
| 7 | + int stack[]; |
73 | 8 | } MinStack; |
74 | 9 |
|
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 | 10 | /** initialize your data structure here. */ |
228 | | -static MinStack* minStackCreate(int maxSize) |
| 11 | +static MinStack* minStackCreate(const int maxSize) |
229 | 12 | { |
230 | | - MinStack *obj = malloc(sizeof(*obj)); |
231 | | - obj->size = maxSize; |
| 13 | + MinStack* obj = malloc(sizeof(MinStack) + sizeof(int) * maxSize); |
232 | 14 | obj->num = 0; |
233 | | - obj->stack = malloc(maxSize * sizeof(int)); |
234 | | - obj->sklist = skiplist_new(); |
| 15 | + obj->min_idx = 0; |
235 | 16 | return obj; |
236 | 17 | } |
237 | 18 |
|
238 | | -static void minStackPush(MinStack* obj, int x) |
| 19 | +static void minStackPush(MinStack* const obj, const int x) |
239 | 20 | { |
240 | | - if (obj->num < obj->size) { |
241 | | - obj->stack[obj->num++] = x; |
242 | | - skiplist_insert(obj->sklist, x, x); |
| 21 | + if (obj->num > 0 && x < obj->stack[obj->min_idx]) { |
| 22 | + obj->min_idx = obj->num; |
243 | 23 | } |
| 24 | + obj->stack[obj->num++] = x; |
244 | 25 | } |
245 | 26 |
|
246 | | -static void minStackPop(MinStack* obj) |
| 27 | +static void minStackPop(MinStack* const obj) |
247 | 28 | { |
248 | | - if (obj->num > 0) { |
249 | | - int key = obj->stack[--obj->num]; |
250 | | - skiplist_remove(obj->sklist, key); |
| 29 | + int i; |
| 30 | + if (--obj->num == obj->min_idx) { |
| 31 | + int min_idx = 0; |
| 32 | + for (i = 1; i < obj->num; i++) { |
| 33 | + if (obj->stack[i] < obj->stack[min_idx]) { |
| 34 | + min_idx = i; |
| 35 | + } |
| 36 | + } |
| 37 | + obj->min_idx = min_idx; |
251 | 38 | } |
252 | 39 | } |
253 | 40 |
|
254 | | -static int minStackTop(MinStack* obj) |
| 41 | +static int minStackTop(MinStack* const obj) |
255 | 42 | { |
256 | | - return obj->num > 0 ? obj->stack[obj->num - 1] : 0; |
| 43 | + return obj->stack[obj->num - 1]; |
257 | 44 | } |
258 | 45 |
|
259 | | -static int minStackGetMin(MinStack* obj) |
| 46 | +static int minStackGetMin(MinStack* const obj) |
260 | 47 | { |
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 | | - } |
| 48 | + return obj->stack[obj->min_idx]; |
268 | 49 | } |
269 | 50 |
|
270 | | -static void minStackFree(MinStack* obj) |
| 51 | +static void minStackFree(MinStack* const obj) |
271 | 52 | { |
272 | | - free(obj->stack); |
273 | | - skiplist_delete(obj->sklist); |
274 | | - free(obj); |
| 53 | + free(obj); |
275 | 54 | } |
276 | 55 |
|
277 | 56 | int main(void) |
|
0 commit comments