1
0
Fork 0

Cleaned single linked list up.

This commit is contained in:
wael 2022-01-05 16:43:18 +02:00
parent 8ae807fb89
commit 87cd5c3f45
No known key found for this signature in database
GPG Key ID: C0A5FBF4558963D4
2 changed files with 78 additions and 77 deletions

View File

@ -14,8 +14,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/* TODO: fixing serialization: change the code to take a user-supplied indexing function and array, and just send the current void pointer to it with the index in each iteration of the loop. */
/* This file contains the function implementations for single linked lists. */
/* Include guard + includes. */
#ifndef SINGLE_LINKED_LIST_C
@ -32,11 +30,11 @@ linked_list_t* initialize_single_linked_list() {
result = (linked_list_t*) malloc(sizeof(linked_list_t));
/* Check if the allocation worked. */
if (result == NULL)
if (!result)
return NULL;
/* Initialize the internal fields. */
result->length = 0;
result->length = 0L;
result->head = NULL;
/* Return the result. */
@ -46,19 +44,19 @@ linked_list_t* initialize_single_linked_list() {
/* This function appends a node to the given linked list, returns 1 on success and 0 on failure. */
int append_node_single_linked_list(linked_list_t *list, node_t *node) {
/* Input sanity check. */
if (list == NULL || node == NULL)
if (!list || !node)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Set the next to NULL. */
node->next = NULL;
/* Check if we can append at the start. */
if (list->head == NULL) {
if (!(list->head)) {
list->head = node;
(list->length)++;
return SUCCESS_CODE_SIGNLE_LINKED_LIST_C;
}
/* Loop till we get to the end. */
node_t *current = list->head;
while (current->next != NULL) {
while (current->next) {
current = current->next;
}
/* Got to the end, append and add. */
@ -70,12 +68,11 @@ int append_node_single_linked_list(linked_list_t *list, node_t *node) {
/* This function prepends a node to the given linked list, returns 1 on success and 0 on failure. */
int prepend_node_single_linked_list(linked_list_t *list, node_t *node) {
/* Input sanity check. */
if (list == NULL || node == NULL)
if (!list || !node)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Set the next to NULL. */
node->next = NULL;
/* Check if we can prepend at the start. */
if (list->head == NULL) {
if (!(list->head)) {
list->head = node;
(list->length)++;
return SUCCESS_CODE_SIGNLE_LINKED_LIST_C;
@ -90,11 +87,11 @@ int prepend_node_single_linked_list(linked_list_t *list, node_t *node) {
/* This function creates and appends a node to the given linked list, returns 1 on success and 0 on failure. */
int append_node_data_single_linked_list(linked_list_t *list, void *data) {
/* Input sanity check. */
if (list == NULL || data == NULL)
if (!list || !data)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Attempt to create a node. */
node_t *node = (node_t*) malloc(sizeof(node_t));
if (node == NULL)
if (!node)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Insert the data. */
node->data = data;
@ -105,11 +102,11 @@ int append_node_data_single_linked_list(linked_list_t *list, void *data) {
/* This function creates and prepends a node to the given linked list, returns 1 on success and 0 on failure. */
int prepend_node_data_single_linked_list(linked_list_t *list, void *data) {
/* Input sanity check. */
if (list == NULL || data == NULL)
if (!list || !data)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Attempt to create a node. */
node_t *node = (node_t*) malloc(sizeof(node_t));
if (node == NULL)
if (!node)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Insert the data. */
node->data = data;
@ -118,14 +115,14 @@ int prepend_node_data_single_linked_list(linked_list_t *list, void *data) {
}
/* This function inserts a node at the ith place, returns 1 on success and 0 on failure. */
int add_node_i_single_linked_list(linked_list_t *list, node_t *node, int i) {
int add_node_i_single_linked_list(linked_list_t *list, node_t *node, size_t i) {
/* Input sanity check. */
if (list == NULL || node == NULL || list->length <= i)
if (!list || !node || list->length <= i)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Set the next to NULL. */
node->next = NULL;
/* Deal with special case of head. */
if (i == 0) {
if (!i) {
node->next = list->head;
list->head = node;
(list->length)++;
@ -133,7 +130,7 @@ int add_node_i_single_linked_list(linked_list_t *list, node_t *node, int i) {
}
/* Loop till we get to the right place. */
node_t *current = list->head;
for (; i > 1; i--)
for (; i > 0; i--)
current = current->next;
/* Insert the node. */
node->next = current->next;
@ -143,13 +140,13 @@ int add_node_i_single_linked_list(linked_list_t *list, node_t *node, int i) {
}
/* This function creates and inserts a node at the ith place, returns 1 in success and 0 on failure. */
int add_node_data_i_single_linked_list(linked_list_t *list, void *data, int i) {
int add_node_data_i_single_linked_list(linked_list_t *list, void *data, size_t i) {
/* Input sanity check. */
if (list == NULL || list->length <= i)
if (!list || list->length <= i)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Attempt to create a node. */
node_t *node = (node_t*) malloc(sizeof(node_t));
if (node == NULL)
if (!node)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Insert the data. */
node->data = data;
@ -159,15 +156,19 @@ int add_node_data_i_single_linked_list(linked_list_t *list, void *data, int i) {
/* This function reads the data at the ith node, returns NULL on failure or NULL data! */
/* Sets the error code in error (instead of returning it). */
void* read_node_i_single_linked_list(linked_list_t *list, int i, int *error) {
void* read_node_i_single_linked_list(linked_list_t *list, size_t i, int *error) {
/* Input sanity check. */
if (error == NULL)
if (!error)
return NULL;
if (list == NULL || list->length <= i) {
if (!list || list->length <= i) {
*error = FAILURE_CODE_SIGNLE_LINKED_LIST_C;
return NULL;
}
/* Check if dealing with the head. */
if (!i)
return list->head->data;
/* Loop and read. */
node_t *current = list->head;
for (; i > 0; i--)
@ -182,15 +183,19 @@ void* read_node_i_single_linked_list(linked_list_t *list, int i, int *error) {
/* This function retrieves a pointer to the ith node, returns NULL on failure. */
/* Sets the error code in error (instead of returning it). */
node_t* get_node_i_single_linked_list(linked_list_t *list, int i, int *error) {
node_t* get_node_i_single_linked_list(linked_list_t *list, size_t i, int *error) {
/* Input sanity check */
if (error == NULL)
if (!error)
return NULL;
if (list == NULL || list->length <= i) {
if (!list || list->length <= i) {
*error = FAILURE_CODE_SIGNLE_LINKED_LIST_C;
return NULL;
}
/* Check if dealing with the head. */
if (!i)
return list->head;
/* Loop. */
node_t *current = list->head;
for (; i > 0; i--)
@ -205,19 +210,19 @@ node_t* get_node_i_single_linked_list(linked_list_t *list, int i, int *error) {
/* This function attempts to find the index of a given node, by pointer. */
/* Returns -2 on invalid input, and -1 when not found. */
int get_node_index_pointer_single_linked_list(linked_list_t *list, node_t *node){
size_t get_node_index_pointer_single_linked_list(linked_list_t *list, node_t *node){
/* Sanity check. */
if (list == NULL || node == NULL)
if (!list || !node)
return INVALID_INPUT_CODE_SINGLE_LINKED_LIST_C;
/* Local variables. */
node_t *current;
int i = 0;
size_t i = 0L;
/* Attempt to search. */
if (list->head == NULL)
if (!(list->head))
return INDEX_NOT_FOUND_CODE_SINGLE_LINKED_LIST_C;
current = list->head;
while (current != NULL && current != node) {
while (current && current != node) {
current = current->next;
i++;
}
@ -227,22 +232,22 @@ int get_node_index_pointer_single_linked_list(linked_list_t *list, node_t *node)
/* This function attempts to find the index of a given node, by data. */
/* Returns -2 on invalid input, and -1 when not found. */
int get_node_index_data_single_linked_list(linked_list_t *list, void *data, int (*comparison_function)(const void*, const void*)) {
size_t get_node_index_data_single_linked_list(linked_list_t *list, void *data, int (*comparison_function)(const void*, const void*)) {
/* Sanity check. */
if (list == NULL || comparison_function == NULL)
return INVALID_INPUT_CODE_SINGLE_LINKED_LIST_C;
/* Local variables. */
node_t *current;
int i = 0;
size_t i = 0L;
/* Check if there is anything to search in the first place. */
if (list->head == NULL)
if (!(list->head))
return INDEX_NOT_FOUND_CODE_SINGLE_LINKED_LIST_C;
/* Set the start. */
current = list->head;
/* Attempt to search. */
while (current != NULL && comparison_function(data, current->data) != 0) {
while (current && !comparison_function(data, current->data)) {
current = current->next;
i++;
}
@ -251,13 +256,13 @@ int get_node_index_data_single_linked_list(linked_list_t *list, void *data, int
}
/* This function deletes the ith node, returns 1 on success and 0 on failure. */
int remove_node_i_single_linked_list(linked_list_t *list, int i) {
int remove_node_i_single_linked_list(linked_list_t *list, size_t i) {
/* Input sanity check */
if (list == NULL || list->length <= i)
if (!list || list->length <= i)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Deal with the special case of the head node. */
if (i == 0) {
if (list->head == NULL)
if (!i) {
if (!(list->head))
return SUCCESS_CODE_SIGNLE_LINKED_LIST_C;
node_t *tmp = list->head;
list->head = tmp->next;
@ -268,7 +273,7 @@ int remove_node_i_single_linked_list(linked_list_t *list, int i) {
}
/* Loop. */
node_t *current = list->head;
for (; i > 1; i--)
for (; i > 0; i--)
current = current->next;
/* Got to the requested node, delete it. */
node_t *tmp = current->next;
@ -281,18 +286,18 @@ int remove_node_i_single_linked_list(linked_list_t *list, int i) {
/* This function deletes the ith node with the data stored within it, returns 1 on success and 0 on failure. */
/* A free function pointer of NULL value causes the use of the internal stdlib free(). */
int remove_node_i_data_single_linked_list(linked_list_t *list, int i, void (*free_function)(void*)) {
int remove_node_i_data_single_linked_list(linked_list_t *list, size_t i, void (*free_function)(void*)) {
/* Input sanity check */
if (list == NULL || list->length <= i)
if (!list || list->length <= i)
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Deal with the special case of the head node. */
if (i == 0) {
if (list->head == NULL)
if (!i) {
if (!(list->head))
return SUCCESS_CODE_SIGNLE_LINKED_LIST_C;
node_t *tmp = list->head;
list->head = tmp->next;
tmp->next = NULL;
if (free_function == NULL)
if (!free_function)
free(tmp->data);
else
free_function(tmp->data);
@ -302,13 +307,13 @@ int remove_node_i_data_single_linked_list(linked_list_t *list, int i, void (*fre
}
/* Loop. */
node_t *current = list->head;
for (; i > 1; i--)
for (; i > 0; i--)
current = current->next;
/* Got to the requested node, delete it. */
node_t *tmp = current->next;
current->next = tmp->next;
tmp->next = NULL;
if (free_function == NULL)
if (!free_function)
free(tmp->data);
else
free_function(tmp->data);
@ -348,9 +353,9 @@ int remove_node_head_data_single_linked_list(linked_list_t *list, void (*free_fu
/* Sets the error code in error (instead of returning it). */
void* read_node_tail_single_linked_list(linked_list_t *list, int *error) {
/* Sanity check. */
if (error == NULL)
if (!error)
return NULL;
if (list == NULL || list->head == NULL)
if (!list || !(list->head))
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Delegate. */
return read_node_i_single_linked_list(list, list->length - 1, error);
@ -360,9 +365,9 @@ void* read_node_tail_single_linked_list(linked_list_t *list, int *error) {
/* Sets the error code in error (instead of returning it). */
node_t* get_node_tail_single_linked_list(linked_list_t *list, int *error) {
/* Sanity check. */
if (error == NULL)
if (!error)
return NULL;
if (list == NULL || list->head == NULL)
if (!list || !(list->head))
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Delegate. */
return get_node_i_single_linked_list(list, list->length - 1, error);
@ -371,7 +376,7 @@ node_t* get_node_tail_single_linked_list(linked_list_t *list, int *error) {
/* This function deletes the last node, returns 1 on success and 0 on failure. */
int remove_node_tail_single_linked_list(linked_list_t *list) {
/* Sanity check. */
if (list == NULL || list->head == NULL)
if (!list || !(list->head))
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Delegate. */
return remove_node_i_single_linked_list(list, list->length - 1);
@ -381,7 +386,7 @@ int remove_node_tail_single_linked_list(linked_list_t *list) {
/* If the free_function is NULL, will use stdlib's free() instead. */
int remove_node_tail_data_single_linked_list(linked_list_t *list, void (*free_function)(void*)) {
/* Sanity check. */
if (list == NULL || list->head == NULL)
if (!list || !(list->head))
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Delegate. */
return remove_node_i_data_single_linked_list(list, list->length - 1, free_function);
@ -392,15 +397,13 @@ int remove_node_tail_data_single_linked_list(linked_list_t *list, void (*free_fu
/* Will return -1 when the list was freed successfully but it was initially malformed. */
int clear_list_single_linked_list(linked_list_t **list) {
/* Sanity check. */
if (list == NULL || *list == NULL)
if (!list || !(*list))
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Local variables. */
node_t *current = (*list)->head;
node_t *tmp;
int length;
int count = 0;
node_t *current = (*list)->head, *tmp;
size_t length, count = 0;
/* Loop and free. */
while(current != NULL) {
while(current) {
count++;
tmp = current->next;
free(current);
@ -423,10 +426,8 @@ int clear_list_data_single_linked_list(linked_list_t **list, void (*free_functio
if (!list || !(*list))
return FAILURE_CODE_SIGNLE_LINKED_LIST_C;
/* Local variables. */
node_t *current = (*list)->head;
node_t *tmp;
int length;
int count = 0;
node_t *current = (*list)->head, *tmp;
size_t length, count = 0;
/* Loop and free. */
while(current) {
count++;
@ -451,7 +452,7 @@ int clear_list_data_single_linked_list(linked_list_t **list, void (*free_functio
/* This function attetmps to serialize a linked list into an array. */
/* Note that the array has to be allocated by the caller. */
/* The array setting function is used to set the values at an index, takes the pointer to the array, index, and value to put. */
extern inline void *serialize_linked_list(linked_list_t *list, void (*array_setting_function)(void*, size_t, void*), void *array) {
void *serialize_linked_list(linked_list_t *list, void (*array_setting_function)(void*, size_t, void*), void *array) {
/* Local variables. */
node_t *current;
size_t i = 0L;

View File

@ -38,7 +38,7 @@
/* The linked list's struct. */
typedef struct linked_list {
/* Stores the list's length. */
int length;
size_t length;
/* Stores the head node pointer. */
node_t *head;
} linked_list_t;
@ -54,23 +54,23 @@ int append_node_data_single_linked_list(linked_list_t *list, void *data);
/* This function creates and prepends a node to the given linked list. */
int prepend_node_data_single_linked_list(linked_list_t *list, void *data);
/* This function inserts a node at the ith place. */
int add_node_i_single_linked_list(linked_list_t *list, node_t *node, int i);
int add_node_i_single_linked_list(linked_list_t *list, node_t *node, size_t i);
/* This function creates and inserts a node at the ith place. */
int add_node_data_i_single_linked_list(linked_list_t *list, void *data, int i);
int add_node_data_i_single_linked_list(linked_list_t *list, void *data, size_t i);
/* This function reads the data at the ith node. */
void* read_node_i_single_linked_list(linked_list_t *list, int i, int *error);
void* read_node_i_single_linked_list(linked_list_t *list, size_t i, int *error);
/* This function retrieves a pointer to the ith node. */
node_t* get_node_i_single_linked_list(linked_list_t *list, int i, int *error);
node_t* get_node_i_single_linked_list(linked_list_t *list, size_t i, int *error);
/* This function attempts to find the index of a given node, by pointer. */
int get_node_index_pointer_single_linked_list(linked_list_t *list, node_t *node);
size_t get_node_index_pointer_single_linked_list(linked_list_t *list, node_t *node);
/* This function attempts to find the index of a given node, by data. */
int get_node_index_data_single_linked_list(linked_list_t *list, void *data, int (*comparison_function)(const void*, const void*));
size_t get_node_index_data_single_linked_list(linked_list_t *list, void *data, int (*comparison_function)(const void*, const void*));
/* This function deletes the ith node. */
int remove_node_i_single_linked_list(linked_list_t *list, int i);
int remove_node_i_single_linked_list(linked_list_t *list, size_t i);
/* This function deletes the ith node and the data stored within. */
int remove_node_i_data_single_linked_list(linked_list_t *list, int i, void (*free_function)(void*));
int remove_node_i_data_single_linked_list(linked_list_t *list, size_t i, void (*free_function)(void*));
/* This function reads the data at the first node. */
void* read_node_head_single_linked_list(linked_list_t *list, int* error);
void* read_node_head_single_linked_list(linked_list_t *list, int *error);
/* This function retrieves the first node. */
node_t* get_node_head_single_linked_list(linked_list_t *list, int *error);
/* This function deletes the first node. */
@ -90,5 +90,5 @@ int clear_list_single_linked_list(linked_list_t **list);
/* This function deletes all the nodes and data stored within of the given list and the list itself. */
int clear_list_data_single_linked_list(linked_list_t **list, void (*free_function)(void*));
/* This function attempts to serialize a linked list into an array, it relies on an array setting function and an allocated buffer. */
extern inline void *serialize_linked_list(linked_list_t *list, void (*array_setting_function)(void*, size_t, void*), void *array);
void *serialize_linked_list(linked_list_t *list, void (*array_setting_function)(void*, size_t, void*), void *array);
#endif /* SINGLE_LINKED_LIST_H */