Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions data_structures/list/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
CC = gcc
CFLAGS = -g -c -Wall
CFLAGS = -g -Wall -c

all: main

main: main.o list.o
$(CC) -g main.o list.o -o main
$(CC) main.o list.o -o main

main.o: main.c list.h
$(CC) $(CFLAGS) main.c

list.o: list.c
list.o: list.c list.h
$(CC) $(CFLAGS) list.c

clean:
rm *o main
rm -f *.o main

140 changes: 92 additions & 48 deletions data_structures/list/list.c
Original file line number Diff line number Diff line change
@@ -1,80 +1,124 @@
#include "list.h"
#include <assert.h>

#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define L List_T
/** Initial capacity for new lists */
#define LIST_INITIAL_CAPACITY 8

/* Initial list */
L List_init(void)
/**
* @brief Resize the internal array to a new capacity.
* @param list Pointer to the List.
* @param new_capacity New capacity.
* @return 0 on success, -1 on failure.
*/
static int list_resize(List* list, size_t new_capacity)
{
L list;
list = (L)malloc(sizeof(L));
list->next = NULL;
return list;
void** new_items = realloc(list->items, new_capacity * sizeof(void*));
if (!new_items)
return -1;
list->items = new_items;
list->capacity = new_capacity;
return 0;
}

/* Push an element into top of the list */
L List_push(L list, void *val)
List* list_init(void)
{
L new_elem = (L)malloc(sizeof(L));
new_elem->val = val;
new_elem->next = list;
return new_elem;
List* list = malloc(sizeof(List));
if (!list)
return NULL;

list->items = malloc(LIST_INITIAL_CAPACITY * sizeof(void*));
if (!list->items)
{
free(list);
return NULL;
}

list->size = 0;
list->capacity = LIST_INITIAL_CAPACITY;
return list;
}

/* Length of list */
int List_length(L list)
int list_append(List* list, void* val)
{
int n;
for (n = 0; list; list = list->next) n++;
return n - 1;
if (list->size >= list->capacity)
{
if (list_resize(list, list->capacity * 2) != 0)
return -1;
}
list->items[list->size++] = val;
return 0;
}

/* Convert list to array */
void **List_toArray(L list)
int list_insert(List* list, size_t index, void* val)
{
int i, n = List_length(list) + 1;
void **array = (void **)malloc((n + 1) * sizeof(*array));
if (index > list->size)
return -1;

for (i = 0; i < n; i++)
if (list->size >= list->capacity)
{
array[i] = list->val;
list = list->next;
if (list_resize(list, list->capacity * 2) != 0)
return -1;
}
array[i] = NULL;

memmove(&list->items[index + 1], &list->items[index],
(list->size - index) * sizeof(void*));
list->items[index] = val;
list->size++;
return 0;
}

void* list_pop(List* list)
{
if (list->size == 0)
return NULL;

return list->items[--list->size];
}

size_t list_length(const List* list) { return list->size; }

void** list_to_array(const List* list)
{
void** array = malloc((list->size + 1) * sizeof(void*));
if (!array)
return NULL;

memcpy(array, list->items, list->size * sizeof(void*));
array[list->size] = NULL;
return array;
}

/* Create and return a list */
L List_list(L list, void *val, ...)
List* list_from_args(void* first, ...)
{
va_list ap;
L *p = &list;
List* list = list_init();
if (!list)
return NULL;

va_start(ap, val);
for (; val; val = va_arg(ap, void *))
va_start(ap, first);
void* val = first;
while (val != NULL)
{
*p = malloc(sizeof(L));
(*p)->val = val;
p = &(*p)->next;
if (list_append(list, val) != 0)
{
list_free(list);
va_end(ap);
return NULL;
}
val = va_arg(ap, void*);
}
*p = NULL;
va_end(ap);

return list;
}

/* Append 2 lists together */
L List_append(L list, L tail)
void list_free(List* list)
{
L *p = &list;
while ((*p)->next)
{
p = &(*p)->next;
}

*p = tail;
return list;
if (!list)
return;
free(list->items);
free(list);
}
92 changes: 74 additions & 18 deletions data_structures/list/list.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,80 @@
#ifndef __LIST__
#define __LIST__

#define L List_T
typedef struct L *L;
#include <stddef.h>

struct L
/**
* @file list.h
* @brief Dynamic array of generic pointers, similar to Python lists.
*/

/**
* @struct List
* @brief Represents a dynamic array of void pointers.
*/
typedef struct
{
void *val;
L next;
};

extern L List_init(void);
extern L List_push(L list, void *val);
extern int List_length(L list);
extern void **List_toArray(L list);
extern L List_append(L list, L tail);
extern L List_list(L list, void *val, ...);
/* TODO */
extern L List_copy(L list);
extern int List_pop(L *list);

#undef L
void **items; /**< Pointer to array of elements */
size_t size; /**< Current number of elements */
size_t capacity; /**< Allocated capacity */
} List;

/**
* @brief Initialize a new empty list.
* @return Pointer to the newly created List.
*/
List *list_init(void);

/**
* @brief Append an element to the end of the list.
* @param list Pointer to the List.
* @param val Pointer to the value to append.
* @return 0 on success, -1 on allocation failure.
*/
int list_append(List *list, void *val);

/**
* @brief Insert an element at a given index.
* @param list Pointer to the List.
* @param index Position to insert.
* @param val Pointer to the value to insert.
* @return 0 on success, -1 on error.
*/
int list_insert(List *list, size_t index, void *val);

/**
* @brief Remove and return the last element from the list.
* @param list Pointer to the List.
* @return Pointer to the removed element, NULL if list is empty.
*/
void *list_pop(List *list);

/**
* @brief Get the number of elements in the list.
* @param list Pointer to the List.
* @return Number of elements.
*/
size_t list_length(const List *list);

/**
* @brief Convert the list to a NULL-terminated array.
* @param list Pointer to the List.
* @return Pointer to a newly allocated array. Caller must free it.
*/
void **list_to_array(const List *list);

/**
* @brief Create a list from variable arguments, ending with NULL.
* @param first Pointer to the first element.
* @param ... Subsequent elements ending with NULL.
* @return Pointer to the newly created List.
*/
List *list_from_args(void *first, ...);

/**
* @brief Free the list structure (does not free individual elements).
* @param list Pointer to the List.
*/
void list_free(List *list);

#endif
Loading