From 758edf9d3049c61aa0036c8239f9fa922905a387 Mon Sep 17 00:00:00 2001 From: Squibid Date: Mon, 17 Nov 2025 17:51:57 -0500 Subject: [PATCH] feat(queue): introduce a queue ds, internally this is just a stack... the only actual difference is a oneline change which makes pushing append instead of prepend the new data. --- README.md | 5 ++++- ds.c | 33 +++++++++++++++++++++++++++++++++ ds.h | 35 +++++++++++++++++++++++++++++++++++ test.c | 21 +++++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1affa24..462f4d9 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ ds_hmp_free(&hmp, NULL); free(b); ``` -## Stack +## Stack / Queue ```c char *a = "a"; char *b = "b"; @@ -58,6 +58,9 @@ ds_stack_pop(stack); // "b" ds_stack_pop(stack); // "a" free(stack); ``` +If you need a queue just use the equivalent `ds_queue` functions and datatypes. +Internally a queue is just a stack which pushes to the end instead of the +beginning. # TODO - [ ] more data structures diff --git a/ds.c b/ds.c index 73ab51a..ca5879a 100644 --- a/ds.c +++ b/ds.c @@ -420,3 +420,36 @@ void return NULL; } + +ds_queue_t +*ds_queue_init(void) +{ + return ds_stack_init(); +} + +int +ds_queue_push(ds_queue_t *queue, void *data) +{ + if (queue->n == 0) { + queue->items = ds_sll_new_node(data); + queue->n++; + return 0; + } + int r = ds_sll_append(queue->items, data); + if (!r) { + queue->n++; + } + return r; +} + +void +*ds_queue_pop(ds_queue_t *queue) +{ + return ds_stack_pop((ds_stack_t *)queue); +} + +void +*ds_queue_peek(ds_queue_t *queue, unsigned x) +{ + return ds_stack_peek((ds_stack_t *)queue, x); +} diff --git a/ds.h b/ds.h index 7db0049..e1b1613 100644 --- a/ds.h +++ b/ds.h @@ -27,6 +27,8 @@ typedef struct { ds_sll_t *items; } ds_stack_t; +typedef ds_stack_t ds_queue_t; + #define ds_ll_foreach(t, ll) for (t *cur = ll; cur; cur = cur->next) /** @@ -206,4 +208,37 @@ void *ds_stack_pop(ds_stack_t *stack); */ void *ds_stack_peek(ds_stack_t *stack, unsigned x); +/** + * @brief initialize a new queue + * + * @return the queue + */ +ds_queue_t *ds_queue_init(void); + +/** + * @brief push new data onto the queue + * + * @param queue the queue + * @param data the data + * @return 0 on success + */ +int ds_queue_push(ds_queue_t *queue, void *data); + +/** + * @brief pop the data off the top of the queue + * + * @param queue the queue + * @return the data + */ +void *ds_queue_pop(ds_queue_t *queue); + +/** + * @brief peek forward x items + * + * @param queue the queue + * @param x how many items to look ahead + * @return the data or NULL if out of range + */ +void *ds_queue_peek(ds_queue_t *queue, unsigned x); + #endif diff --git a/test.c b/test.c index 32942a6..6e9c967 100644 --- a/test.c +++ b/test.c @@ -99,4 +99,25 @@ main(int argc, char *argv[]) free(stack); ); + + test("queue", + char *a = "a"; + char *b = "b"; + char *c = "c"; + + ds_queue_t *queue = ds_queue_init(); + it("pushes an item", ds_queue_push(queue, a) == 0); + it("pops an item", ds_queue_pop(queue) == a); + + ds_queue_push(queue, b); + ds_queue_push(queue, c); + + it("peeks ahead", ds_queue_peek(queue, 0) == b); + it("peeks past the queue", ds_queue_peek(queue, INT_MAX) == NULL); + + ds_queue_pop(queue); + ds_queue_pop(queue); + + free(queue); + ); }