typedef struct s_list
{
void *content;
struct s_list *next;
} t_list;
이와같이 구조체 선언하여 사용한다.
t_list *ft_lstnew(void *content) { t_list *new; new = (t_list *)malloc(sizeof(t_list)); if (new == NULL) return (NULL); new->content = content; new->next = NULL; return (new); }
*new라는 새로운 리스트를 만들어 malloc의 사이즈를 t_list로 하여 만들어 준다.new->content = content로 new의 content에는 입력받은 content를 넣는다.new->next = NULL에서 왜 new의 next에 NULL을 넣냐면 새로 생성한 리스트여서 다음 노드가 없기 때문에 NULL을 넣는다.void ft_lstadd_front(t_list **lst, t_list *new) { if (new == NULL || lst == NULL) return ; if (*lst == NULL) { *lst = new; return ; } new->next = *lst; *lst = new; }
new리스트를 lst앞쪽에 이어 붙이는 함수를 구현했다.lst가 NULL이면 빈 리스트이므로 new리스트를 넣어주기만 하면 된다.new->next = *lst로 new의 next에 *lst의 값을 넣어주고 *lst에는 new를 넣어 앞쪽으로 연결되게 만든다.int ft_lstsize(t_list *lst) { int i; i = 0; if (lst == NULL) return (0); while (lst != NULL) { lst = lst->next; i++; } return (i); }
lst = lst->next를 하여 i++을 한다.i는 리스트의 길이가 된다. 이 i를 리턴한다.t_list *ft_lstlast(t_list *lst) { if (lst == NULL) return (NULL); while (lst->next != NULL) lst = lst->next; return (lst); }
lst->next가 NULL인 리스트를 찾아 반환한다.void ft_lstadd_back(t_list **lst, t_list *new) { t_list *last; if (lst == NULL || new == NULL) return ; if (*lst == NULL) { *lst = new; return ; } last = *lst; while (last->next != NULL) last = last->next; last->next = new; return ; }
**lst의 마지막에 new를 연결하는 함수를 구현하였다.*lst가 NULL이면 빈 리스트이므로 *lst에 new를 넣고 리턴한다.last를 마지막 노드를 찾아 저장하고 last->next에 new를 넣어 연결하여 리턴한다.void ft_lstdelone(t_list *lst, void (*del)(void *)) { if (lst == NULL || del == NULL) return ; del(lst->content); free(lst); return ; }
del 포인터함수로 lst의 content 내용을 지우고 리스트를 free로 동적할당한 메모리르 해제해준다.void ft_lstclear(t_list **lst, void (*del)(void *)) { t_list *cpl; t_list *list; if (lst == NULL || del == NULL || *lst == NULL) return ; list = *lst; while (list != NULL) { cpl = list->next; del(list->content); free(list); list = cpl; } *lst = NULL; }
cpl에 list->next값을 저장했다. 이 값을 저장하지 않고 free를 하게 되면 다음 리스트를 찾을 수 없다.del포인터 함수를 이용하여 list->content값을 지우고 free를 하였다.list에는 앞에서 복사한 cpl의 값을 넣고 while문을 돌게 하였다.void ft_lstiter(t_list *lst, void (*f)(void *)) { if (lst == NULL || f == NULL) return ; while (lst != NULL) { f(lst->content); lst = lst->next; } }
f포인터함수 적용하는 함수를 구현하였다.lst가 마지막 노드인 NULL을 만나기 전까지 f(lst->content)를 거친다.lst = lst->next로 다음 노드를 불러온다.t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *)) { t_list *newlst; t_list *newnode; t_list *tail; if (lst == NULL || f == NULL || del == NULL) return (NULL); newlst = ft_lstnew(f(lst->content)); if (newlst == NULL) return (NULL); lst = lst->next; tail = newlst; while (lst != NULL) { newnode = ft_lstnew(f(lst->content)); if (newnode == NULL) { ft_lstclear(&newlst, del); return (NULL); } tail->next = newnode; tail = newnode; lst = lst->next; } return (newlst); }
lst에 f 포인터 함수를 적용하고 문제가 있을 경우 del함수로 모든 데이터를 지우는 함수를 구현했다.newlst는 함수가 적용된 리스트의 헤드를 저장한다.tail은 함수를 적용하면서 끝까지 가는 역할을 한다.newnode에 f함수를 적용한 content를 넣어 생성한다.newnode에서 malloc 실패같은 문제가 생겨 NULL을 뱉으면 ft_lstclear로 모든 내용을 지우고 free를해서 NULL을 반환한다.newnode가 적용이 잘 되었으면 tail->next에 newnode를 대입하고, tail에 newnode를 넣고 lst=lst->next로 다음 리스트로 넘어가서 진행한다.