Skip to content

Commit 36422d1

Browse files
Min stack
Signed-off-by: Leo Ma <begeekmyfriend@gmail.com>
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy