]> www.ljiriste.work Git - Libft.git/commitdiff
Implement linked list structure
authorLukáš Jiřiště <redacted>
Tue, 30 Dec 2025 09:41:00 +0000 (10:41 +0100)
committerLukáš Jiřiště <redacted>
Tue, 30 Dec 2025 13:58:06 +0000 (14:58 +0100)
Makefile
ft_struct/ft_linked_list.c [new file with mode: 0644]
ft_struct/ft_linked_list_helpers.c [new file with mode: 0644]
inc/ft_struct.h

index d70aada2a3d4acf32f34a4b7ca94553ad46f45f2..91f244cc7e4f32c6ced6878101d90f817072bed1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -47,6 +47,8 @@ SRCstruct:=   ft_stack_free.c                                                                                 \
                        ft_dict_init.c                                                                                  \
                        ft_dict_insert.c                                                                                \
                        ft_dict_traversal.c                                                                             \
+                       ft_linked_list.c                                                                                \
+                       ft_linked_list_helpers.c                                                                \
 
 SRCparse:=     ft_parse.c                                                                                              \
                        ft_parsing_table_init.c                                                                 \
diff --git a/ft_struct/ft_linked_list.c b/ft_struct/ft_linked_list.c
new file mode 100644 (file)
index 0000000..472794b
--- /dev/null
@@ -0,0 +1,81 @@
+#include "ft_struct.h"
+#include "libft.h"
+#include <stdlib.h>
+
+t_ft_stat      ft_linked_list_init(t_linked_list *list, size_t el_size)
+{
+       if (!list)
+               return (invalid_input);
+       list->el_size = el_size;
+       list->head = NULL;
+       return (success);
+}
+
+t_linked_list_node             *ft_linked_list_insert(t_linked_list *list, void *element)
+{
+       t_linked_list_node      *node;
+       t_linked_list_node      *new_node;
+
+       if (!list || !element)
+               return (NULL);
+       new_node = malloc(sizeof(*new_node) + list->el_size);
+       if (!new_node)
+               return (NULL);
+       ft_memcpy(&new_node->data, element, list->el_size);
+       new_node->next = NULL;
+       node = list->head;
+       if (!node)
+       {
+               list->head = new_node;
+               return (new_node);
+       }
+       while (node->next)
+               node = node->next;
+       node->next = new_node;
+       return (new_node);
+}
+
+void   *ft_linked_list_access(t_linked_list_node *node)
+{
+       return (&node->data);
+}
+
+void   ft_linked_list_delete(t_linked_list *list,
+                       t_linked_list_node *node, t_free_fun free_el)
+{
+       t_linked_list_node      *parent;
+
+       if (!list || !list->head || !node)
+               return ;
+       if (node == list->head)
+       {
+               list->head = node->next;
+               if (free_el)
+                       free_el(ft_linked_list_access(node));
+               free(node);
+               return ;
+       }
+       parent = list->head;
+       while (parent->next && parent->next != node)
+               parent = parent->next;
+       ft_linked_list_delete_next(parent, free_el);
+       return ;
+}
+
+void   ft_linked_list_free(t_linked_list *list, t_free_fun free_el)
+{
+       t_linked_list_node      *node;
+       t_linked_list_node      *next;
+
+       node = list->head;
+       while (node)
+       {
+               next = node->next;
+               if (free_el)
+                       free_el(ft_linked_list_access(node));
+               free(node);
+               node = next;
+       }
+       list->head = NULL;
+       return ;
+}
diff --git a/ft_struct/ft_linked_list_helpers.c b/ft_struct/ft_linked_list_helpers.c
new file mode 100644 (file)
index 0000000..ce87472
--- /dev/null
@@ -0,0 +1,17 @@
+#include "ft_struct.h"
+#include <stdlib.h>
+
+void   ft_linked_list_delete_next(t_linked_list_node *node, t_free_fun free_el)
+{
+       t_linked_list_node      *child;
+
+       if (!node || !node->next)
+               return ;
+       child = node->next->next;
+       if (free_el)
+               free_el(ft_linked_list_access(node->next));
+       free(node->next);
+       node->next = child;
+       return ;
+}
+
index 3f072d8f71036f5d66a3574bb378332a763631d2..debad500b156fed0c642629d3a19c292b359cc78 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/20 16:59:43 by ljiriste          #+#    #+#             */
-/*   Updated: 2025/09/17 08:36:29 by ljiriste         ###   ########.fr       */
+/*   Updated: 2025/12/30 09:43:24 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -148,6 +148,32 @@ t_dict_entry       ft_dict_traverse_full(t_dict_traversal *traversal);
 void                   *ft_dict_traverse(t_dict_traversal *traversal);
 void                   ft_dict_traversal_free(t_dict_traversal *traversal);
 
+typedef struct s_linked_list_node t_linked_list_node;
+
+struct s_linked_list_node
+{
+       t_linked_list_node      *next;
+       char                            data[];
+};
+
+typedef struct s_linked_list
+{
+       size_t                          el_size;
+       t_linked_list_node      *head;
+}                                              t_linked_list;
+
+t_ft_stat                              ft_linked_list_init(t_linked_list *list, size_t el_size);
+// Because of notoriously slow access, the insert function returns a pointer to
+// the inserted node instead of t_ft_stat (so the user needs not traverse).
+// NULL signifies an error (probably failed allocation of memory).
+t_linked_list_node             *ft_linked_list_insert(t_linked_list *list, void *element);
+void                                   *ft_linked_list_access(t_linked_list_node *node);
+void                                   ft_linked_list_delete(t_linked_list *list,
+                                                       t_linked_list_node *node, t_free_fun free_el);
+void                                   ft_linked_list_delete_next(
+                                                       t_linked_list_node *node, t_free_fun free_el);
+void                                   ft_linked_list_free(t_linked_list *list, t_free_fun free_el);
+
 # ifdef __cplusplus
 }
 # endif // __cplusplus