Skip to content

Commit

Permalink
Bổ xung slist
Browse files Browse the repository at this point in the history
  • Loading branch information
bangoc committed Dec 13, 2024
1 parent d2a3924 commit afb3625
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 30 deletions.
3 changes: 2 additions & 1 deletion v3/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ add_test(NAME q2insort_ut COMMAND q2insort_ut)
add_test(NAME binsearch_ut COMMAND binsearch_ut)
add_test(NAME hmap_demo_ut COMMAND hmap_demo_ut)
add_test(NAME ivec_sort_ut COMMAND ivec_sort_ut)
add_test(NAME ivec_put_rem_demo_ut COMMAND ivec_put_rem_demo_ut)
add_test(NAME ivec_put_rem_demo_ut COMMAND ivec_put_rem_demo_ut)
add_test(NAME slist_demo_ut COMMAND slist_demo_ut)
4 changes: 2 additions & 2 deletions v3/algo.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ static void heapsort(void *a, int n, int sz,
}
}

#define VHEAPSORT(v, order) heapsort(v->elems, v->sz, sizeof(v->elems[0]), order)
#define VQ2INSORT(v, order) q2insort(v->elems, v->sz, sizeof(v->elems[0]), order)
#define VHEAPSORT(v, order) heapsort(v->elems, v->size, sizeof(v->elems[0]), order)
#define VQ2INSORT(v, order) q2insort(v->elems, v->size, sizeof(v->elems[0]), order)

#endif // ALGO_H_
14 changes: 7 additions & 7 deletions v3/hmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct pre##hmap { \
struct pre##hmap_node *end; \
int mod; \
unsigned mask; \
int sz; \
int size; \
int cap; \
int used; \
unsigned (*ha)(key_t); \
Expand Down Expand Up @@ -145,7 +145,7 @@ static void relocate_map(struct pre##hmap *hm, unsigned ocap, \
} \
static void pre##hmap_realloc(struct pre##hmap *hm) { \
int ocap = hm->cap; \
pre##hmap_set_shift_from_cap(hm, hm->sz * 1.333); \
pre##hmap_set_shift_from_cap(hm, hm->size * 1.333); \
if (hm->cap > ocap) { \
pre##hmap_realloc_arrays(hm); \
memset(hm->nodes + ocap, 0, (hm->cap - ocap) * sizeof(struct pre##hmap_node)); \
Expand All @@ -156,11 +156,11 @@ static void pre##hmap_realloc(struct pre##hmap *hm) { \
if (hm->cap < ocap) { \
pre##hmap_realloc_arrays(hm); \
} \
hm->used = hm->sz; \
hm->used = hm->size; \
} \
static inline int pre##hmap_maybe_realloc(struct pre##hmap *hm) { \
unsigned used = hm->used, cap = hm->cap; \
if ((cap > hm->sz * 4 && cap > 1 << HASH_MIN_SHIFT) || \
if ((cap > hm->size * 4 && cap > 1 << HASH_MIN_SHIFT) || \
(cap <= used + (used/16))) { \
pre##hmap_realloc(hm); \
return 1; \
Expand All @@ -170,7 +170,7 @@ static inline int pre##hmap_maybe_realloc(struct pre##hmap *hm) { \
static struct pre##hmap_node *pre##hmap_rem_node(struct pre##hmap *hm, int idx) { \
struct pre##hmap_node *n = hm->nodes + idx; \
n->state = DELETED; \
hm->sz--; \
hm->size--; \
return n; \
} \
static inline int pre##hmap_lookup(struct pre##hmap *hm, key_t key, \
Expand Down Expand Up @@ -203,7 +203,7 @@ static inline int pre##hmap_lookup(struct pre##hmap *hm, key_t key, \
} \
struct pre##hmap *pre##hmap(int shift, unsigned (*ha)(), int (*eq)()) { \
struct pre##hmap *hm = malloc(sizeof(struct pre##hmap)); \
hm->sz = 0; \
hm->size = 0; \
hm->used = 0; \
hm->ha = ha; \
hm->eq = eq; \
Expand All @@ -220,7 +220,7 @@ struct pre##hmap_node *pre##hmap_put(struct pre##hmap *hm, key_t k, value_t v) {
n->hash = key_hash; \
n->key = k; \
n->value = v; \
++hm->sz; \
++hm->size; \
int new_usage = n->state == UNUSED; \
n->state = USING; \
if (new_usage) { \
Expand Down
119 changes: 119 additions & 0 deletions v3/slist.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#ifndef SLIST_H_
#define SLIST_H_

#include <stdlib.h>

#define SDECL(sname, elem_t) \
struct sname##_node; \
struct sname; \
struct sname##_node *sname##_node(elem_t value); \
struct sname *sname(); \
void sname##_del(struct sname *list); \
struct sname *sname##_append(struct sname *list, elem_t value); \
struct sname *sname##_prepend(struct sname *list, elem_t value); \
struct sname *sname##_dfirst(struct sname *list); \
struct sname *sname##_push(struct sname *list, elem_t elem); \
elem_t *sname##_top(struct sname *list); \
struct sname *sname##_pop(struct sname *list); \
struct sname *sname##_enque(struct sname *list, elem_t elem); \
elem_t *sname##_peek(struct sname *list); \
struct sname *sname##_deque(struct sname *list); \
int sname##_empty(struct sname *list);

#define SIMPL(sname, elem_t) \
struct sname##_node { \
elem_t value; \
struct sname##_node *next; \
}; \
struct sname { \
struct sname##_node *first; \
struct sname##_node *last; \
int size; \
}; \
\
struct sname##_node *sname##_node(elem_t value) { \
struct sname##_node *tmp = malloc(sizeof(struct sname##_node)); \
tmp->value = value; \
tmp->next = NULL; \
return tmp; \
} \
struct sname *sname() { \
struct sname *tmp = malloc(sizeof(struct sname)); \
tmp->first = tmp->last = NULL; \
tmp->size = 0; \
return tmp; \
} \
void sname##_del(struct sname *list) { \
while (!sname##_empty(list)) { \
sname##_dfirst(list); \
} \
free(list); \
} \
struct sname *sname##_append(struct sname *list, elem_t value) {\
struct sname##_node *node = sname##_node(value); \
if (!node) { \
return NULL; \
} \
if (list->first == NULL) { \
list->first = list->last = node; \
} else { \
list->last->next = node; \
list->last = node; \
} \
++list->size; \
return list; \
} \
struct sname *sname##_prepend(struct sname *list, elem_t value) {\
struct sname##_node *node = sname##_node(value); \
if (!node) { \
return NULL; \
} \
if (list->first == NULL) { \
list->first = list->last = node; \
} else { \
node->next = list->first; \
list->first = node; \
} \
++list->size; \
return list; \
} \
struct sname *sname##_dfirst(struct sname *list) {\
if (!list || sname##_empty(list)) { \
return NULL; \
} \
if (list->first == list->last) { \
list->last = NULL; \
} \
struct sname##_node *tmp = list->first; \
list->first = tmp->next; \
free(tmp); \
--list->size; \
return list; \
} \
struct sname *sname##_push(struct sname *list, elem_t elem) { \
return sname##_prepend(list, elem); \
} \
elem_t *sname##_top(struct sname *list) { \
return &list->first->value; \
} \
struct sname *sname##_pop(struct sname *list) {\
return sname##_dfirst(list); \
} \
struct sname *sname##_enque(struct sname *list, elem_t elem) { \
return sname##_append(list, elem); \
} \
elem_t *sname##_peek(struct sname *list) {\
return &list->first->value; \
} \
struct sname *sname##_deque(struct sname *list) { \
return sname##_dfirst(list); \
} \
int sname##_empty(struct sname *list) { \
return list->first == NULL || list->last == NULL; \
}

#define SDECL_IMPL(sname, elem_t) \
SDECL(sname, elem_t) \
SIMPL(sname, elem_t)

#endif // SLIST_H_
3 changes: 2 additions & 1 deletion v3/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ add_executable(q2insort_ut q2insort_ut.c)
add_executable(binsearch_ut binsearch_ut.c)
add_executable(hmap_demo_ut hmap_demo_ut.c)
add_executable(ivec_sort_ut ivec_sort_ut.c)
add_executable(ivec_put_rem_demo_ut ivec_put_rem_demo_ut.c)
add_executable(ivec_put_rem_demo_ut ivec_put_rem_demo_ut.c)
add_executable(slist_demo_ut slist_demo_ut.c)
4 changes: 2 additions & 2 deletions v3/tests/ivec_put_rem_demo_ut.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
VEC_DECL_IMPL(i, int)

void ivec_print(struct ivector *v) {
printf("sz: %d\ncap: %d\n", v->sz, v->cap);
for (int i = 0; i < v->sz; ++i) {
printf("sz: %d\ncap: %d\n", v->size, v->cap);
for (int i = 0; i < v->size; ++i) {
printf("%d\n", v->elems[i]);
}
}
Expand Down
6 changes: 3 additions & 3 deletions v3/tests/ivec_sort_ut.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ int main() {
ivec_append(v, rand());
}
VQ2INSORT(v, lte);
for (int i = 0; i < v->sz; ++i) {
for (int i = 0; i < v->size; ++i) {
if (i > 0 && !lte(v->elems + i - 1, v->elems + i)) {
return 1;
}
}
printf("sz: %d\ncap: %d\n", v->sz, v->cap);
for (int i = 0; i < v->sz; ++i) {
printf("sz: %d\ncap: %d\n", v->size, v->cap);
for (int i = 0; i < v->size; ++i) {
printf("%d\n", v->elems[i]);
}
ivec_del(v);
Expand Down
2 changes: 1 addition & 1 deletion v3/tests/ivec_ut.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ int main() {
for (int i = 0; i < 5; ++i) {
ivec_append(v, i);
}
printf("sz = %d\ncap = %d\n", v->sz, v->cap);
printf("sz = %d\ncap = %d\n", v->size, v->cap);
for (int i = 0; i < 5; ++i) {
printf("%d ", v->elems[i]);
}
Expand Down
27 changes: 27 additions & 0 deletions v3/tests/slist_demo_ut.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "slist.h"

#include <stdio.h>

SDECL_IMPL(slist, int)

void print_lst(struct slist *lst) {
printf("size = %d\n", lst->size);
for (struct slist_node *n = lst->first; n; n = n->next) {
printf("%d ", n->value);
}
printf("\n");
}

int main() {
struct slist *lst = slist();
slist_append(lst, 1);
slist_append(lst, 3);
slist_append(lst, 5);
slist_prepend(lst, 2);
slist_prepend(lst, 6);
print_lst(lst);
slist_dfirst(lst);
slist_dfirst(lst);
print_lst(lst);
slist_del(lst);
}
26 changes: 13 additions & 13 deletions v3/vec.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,37 @@ void pre##vec_del(struct pre##vector *v);

#define VEC_IMPL(pre, elem_t) \
struct pre##vector { \
int sz; \
int size; \
int cap; \
elem_t *elems; \
}; \
struct pre##vector *pre##vector(int n) { \
struct pre##vector *v = malloc(sizeof(struct pre##vector)); \
v->sz = n; \
v->cap = v->sz > 0? v->sz: 8; \
v->size = n; \
v->cap = v->size > 0? v->size: 8; \
v->elems = calloc(v->cap, sizeof(elem_t)); \
return v; \
} \
elem_t pre##vec_rem(struct pre##vector *v, int idx) { \
elem_t tmp = v->elems[idx]; \
for (int i = idx; i < v->sz - 1; ++i) { \
for (int i = idx; i < v->size - 1; ++i) { \
v->elems[i] = v->elems[i + 1]; \
} \
--v->sz; \
if (v->sz > 8 && v->cap > v->sz * 2) { \
pre##vec_reserve(v, v->sz * 1.33); \
--v->size; \
if (v->size > 8 && v->cap > v->size * 2) { \
pre##vec_reserve(v, v->size * 1.33); \
} \
return tmp; \
} \
void pre##vec_put(struct pre##vector *v, elem_t elem, int idx) { \
pre##vec_append(v, elem); \
for (int i = v->sz; i > idx; --i) { \
for (int i = v->size; i > idx; --i) { \
v->elems[i] = v->elems[i - 1]; \
} \
v->elems[idx] = elem; \
} \
int pre##vec_reserve(struct pre##vector *v, int newcap) { \
if (newcap <= v->sz) { \
if (newcap <= v->size) { \
return 1; \
} \
v->elems = realloc(v->elems, newcap * sizeof(elem_t)); \
Expand All @@ -61,17 +61,17 @@ int pre##vec_reserve(struct pre##vector *v, int newcap) { \
void pre##vec_append(struct pre##vector *v, elem_t value) { \
if (v->cap == 0) { \
pre##vec_reserve(v, 16); \
} else if (v->sz == v->cap) { \
} else if (v->size == v->cap) { \
pre##vec_reserve(v, 2 * v->cap); \
} \
v->elems[v->sz] = value; \
++v->sz; \
v->elems[v->size] = value; \
++v->size; \
} \
void pre##vec_resize(struct pre##vector *v, int newsize) { \
if (newsize > v->cap) { \
pre##vec_reserve(v, newsize); \
} \
v->sz = newsize; \
v->size = newsize; \
} \
void pre##vec_del(struct pre##vector *v) { \
if (!v) { \
Expand Down

0 comments on commit afb3625

Please sign in to comment.