Cleaned single linked list up.
This commit is contained in:
parent
8ae807fb89
commit
87cd5c3f45
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue