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.
This commit is contained in:
Squibid 2025-11-17 17:51:57 -05:00
parent 9daffd4ed1
commit 758edf9d30
Signed by: squibid
GPG key ID: BECE5684D3C4005D
4 changed files with 93 additions and 1 deletions

View file

@ -45,7 +45,7 @@ ds_hmp_free(&hmp, NULL);
free(b); free(b);
``` ```
## Stack ## Stack / Queue
```c ```c
char *a = "a"; char *a = "a";
char *b = "b"; char *b = "b";
@ -58,6 +58,9 @@ ds_stack_pop(stack); // "b"
ds_stack_pop(stack); // "a" ds_stack_pop(stack); // "a"
free(stack); 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 # TODO
- [ ] more data structures - [ ] more data structures

33
ds.c
View file

@ -420,3 +420,36 @@ void
return NULL; 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);
}

35
ds.h
View file

@ -27,6 +27,8 @@ typedef struct {
ds_sll_t *items; ds_sll_t *items;
} ds_stack_t; } ds_stack_t;
typedef ds_stack_t ds_queue_t;
#define ds_ll_foreach(t, ll) for (t *cur = ll; cur; cur = cur->next) #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); 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 #endif

21
test.c
View file

@ -99,4 +99,25 @@ main(int argc, char *argv[])
free(stack); 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);
);
} }