Skip to content

Commit a82223e

Browse files
Min stack
Signed-off-by: Leo Ma <begeekmyfriend@gmail.com>
1 parent 06db8d3 commit a82223e

File tree

2 files changed

+296
-0
lines changed

2 files changed

+296
-0
lines changed

155_min_stack/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
all:
2+
gcc -O2 -o test stack.c

155_min_stack/stack.c

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
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

Comments
 (0)