Skip to content

Commit 36422d1

Browse files
Min stack
Signed-off-by: Leo Ma <[email protected]>
1 parent a82223e commit 36422d1

File tree

1 file changed

+25
-246
lines changed

1 file changed

+25
-246
lines changed

155_min_stack/stack.c

Lines changed: 25 additions & 246 deletions
Original file line numberDiff line numberDiff line change
@@ -1,277 +1,56 @@
11
#include <stdio.h>
22
#include <stdlib.h>
33

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-
684
typedef struct {
69-
int size;
705
int num;
71-
int *stack;
72-
struct skiplist *sklist;
6+
int min_idx;
7+
int stack[];
738
} MinStack;
749

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-
22710
/** initialize your data structure here. */
228-
static MinStack* minStackCreate(int maxSize)
11+
static MinStack* minStackCreate(const int maxSize)
22912
{
230-
MinStack *obj = malloc(sizeof(*obj));
231-
obj->size = maxSize;
13+
MinStack* obj = malloc(sizeof(MinStack) + sizeof(int) * maxSize);
23214
obj->num = 0;
233-
obj->stack = malloc(maxSize * sizeof(int));
234-
obj->sklist = skiplist_new();
15+
obj->min_idx = 0;
23516
return obj;
23617
}
23718

238-
static void minStackPush(MinStack* obj, int x)
19+
static void minStackPush(MinStack* const obj, const int x)
23920
{
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;
24323
}
24+
obj->stack[obj->num++] = x;
24425
}
24526

246-
static void minStackPop(MinStack* obj)
27+
static void minStackPop(MinStack* const obj)
24728
{
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;
25138
}
25239
}
25340

254-
static int minStackTop(MinStack* obj)
41+
static int minStackTop(MinStack* const obj)
25542
{
256-
return obj->num > 0 ? obj->stack[obj->num - 1] : 0;
43+
return obj->stack[obj->num - 1];
25744
}
25845

259-
static int minStackGetMin(MinStack* obj)
46+
static int minStackGetMin(MinStack* const obj)
26047
{
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];
26849
}
26950

270-
static void minStackFree(MinStack* obj)
51+
static void minStackFree(MinStack* const obj)
27152
{
272-
free(obj->stack);
273-
skiplist_delete(obj->sklist);
274-
free(obj);
53+
free(obj);
27554
}
27655

27756
int main(void)

0 commit comments

Comments
 (0)