[42Seoul] Libft Bonus

jiyseo·2022년 4월 15일
0

42 Seoul

목록 보기
4/9

ft_lstnew

t_list ft_lstnew(void content)

new 리스트의 next 변수(다음 노드의 포인터)는 NULL로 초기화.

생성하는 함수일 뿐, 추가하거나 삽입하는 함수는 아님 !! 그래서 아래와 같은 의문이 들었지만 쓸데없는 걱정이었다.

  • 원래 NULL을 가리키던 마지막 요소는 어떻게 되는 걸까?
  • 두 개의 리스트가 NULL을 가리키는 것 아닌가?

노드의 생성, 추가, 삽입은 개념이 다 다르다.

  • 추가는 새로 만든 노드를 연결리스트의 제일 마지막에 붙이는 작업
  • 삽입은 노드와 노드 사이에 새로운 노드를 삽입하는 작업
  • 참고 : https://junistudy.tistory.com/2
  • malloc으로 메모리를 할당해주는 이유 malloc없이 새로운 노드를 만들게 되면, ft_newlst 함수가 종료되면서 반환되는 new 노드는 stack에서 사라지게 된다. malloc을 하면 힙영역에 할당되고, 그래야 함수가 종료돼도 메모리 상에 남아 t_list *new 가 할당 받은 메모리를 가리킬 수 있게 된다. void ft_lstadd_front(t_list *lst, t_list new)
#include"libft.h"

t_list	*ft_lstnew(void	*content)
{
	t_list	*new;

	new = (t_list *)malloc(sizeof(t_list));
	if (!new)
		return (NULL);
	new->content = content;
	new->next = NULL;
	return (new);
}

ft_lstadd_front

리스트 제일 앞에 새 리스트 추가하는 함수

  1. 새 노드의 다음 주소를 head로 설정
  2. head를 새 노드로 설정

연결 리스트 구현시 이중 포인터를 사용하는 이유

  • 단일 연결리스트에서 삽입과 삭제를 통해 head 포인터의 값을 변화시킬 수 있다.
  • 이때, 호출 함수의 포인터변수가 참조하는 객체를 피호출 함수에서 바꾸고자 할 경우 이중 포인터를 사용하면 된다.
  • t_list **lst 는 t_list 포인터(lst)의 주소를 가리키는 포인터다.
    • t_list **lst 변수가 담고있는 값은 t_list *의 주소
    • t_list ** lst가 담고 있는 t_list * 의 주소는 어떤 리스트의 첫번째 주소
    • 즉, *lst는 head의 주소
#include"libft.h"

void	ft_lstadd_front(t_list	**lst, t_list	*new)
{
	if (!lst || !new)
		return ;
	new->next = *lst;
	*lst = new;
}

ft_lstsize

int ft_lstsize(t_list *lst)

리스트에 포함된 요소의 개수를 셉니다.

#include"libft.h"

int	ft_lstsize(t_list	*lst)
{
	int	size;

	size = 0;
	while (lst)
	{
		lst = lst->next;
		size++;
	}
	return (size);
}

ft_lstlast

t_list ft_lstlast(t_list lst)

리스트의 맨 마지막에 위치한 요소를 반환합니다.

#include"libft.h"

t_list	*ft_lstlast(t_list	*lst)
{
	if (!lst)
		return (NULL);
	while (lst->next)
		lst = lst->next;
	return (lst);
}

ft_lstadd_back

void ft_lstadd_back(t_list *lst, t_list new)

요소 'new'를 리스트의 맨 뒤에 추가합니다.

  1. new의 다음 주소는 원래 last의 다음 주소( = NULL) 로 설정
  2. last의 다음 주소가 new를 가리키도록 변경
  • ft_lstlast();` 함수의 인자로 lst를 보내야하는지 *lst를 보내야 하는지 헷갈렸다.
    • lstlast 함수는 파라미터로 t_list * 즉, 첫 번째 요소의 주소를 받는다.
    • 이렇게 생각하면 조금 쉬워진다. ft_lstadd_back 함수에서 우리가 받은 인자의 자료형은 t_list *이고, (t_list * ) = t_list 이기 때문에 *lst 를 인자로 보내면 된다. *lst == NULL 과 lst == NULL 의 차이
      • lst는 lst의 첫번째 주소, 즉 헤드의 주소를 의미한다. 헤드가 비었다는 건,
        • lst는 빈 리스트 라는 뜻!
      • lst == NULL은 리스트 자체가 존재하지 않는다 뜻!
#include"libft.h"

void	ft_lstadd_back(t_list	**lst, t_list	*new)
{
	t_list	*last;

	if (!lst || !new)
		return ;
	if (!(*lst))
	{
		*lst = new;
		return ;
	}
	last = ft_lstlast(*lst);
	new->next = last->next;
	last->next = new;
}

ft_lstdelone

void ft_lstdelone(t_list lst, void (del)(void *))

첫 번째 인자값으로 받은 요소의 content를 두 번째 인자로 받은 함수 포인터를 이용해 해제하고, 요소 자체의 메모리를 해제합니다. next 포인터는 해제하면 안 됩니다.

#include"libft.h"

void	ft_lstdelone(t_list	*lst, void	(*del)(void *))
{
	if (!lst)
		return ;
	del(lst->content);
	free(lst);
}

ft_lstclear

함수 'del' 과 free(3) 을 이용하여 인자값으로 받은 요소와 그 뒤에 따라오는 리스트의 모든 요소들을 삭제하고 해제합니다. 마지막으로, 리스트의 포인터는 NULL로 설정되어야 합니다.

#include"libft.h"

void	ft_lstclear(t_list	**lst, void	(*del)(void *))
{
	t_list	*next;
	t_list	*now;

	now = *lst;
	if (!lst || !del)
		return ;
	while (now)
	{
		next = now->next;
		ft_lstdelone(now, del);
		now = next;
	}
	*lst = NULL;
}

ft_lstiter

void ft_lstiter(t_list lst, void (f)(void *))

리스트 'lst' 를 순회하며, 리스트에 포함된 모든 요소들의 content에 함수 'f'를 반복적으로 적용시킵니다.

#include"libft.h"

void	ft_lstiter(t_list	*lst, void	(*f)(void *))
{
	if (!lst || !f)
		return ;
	while (lst)
	{
		f(lst->content);
		lst = lst->next;
	}
}

ft_lstmap

t_list ft_lstmap(t_list lst, void (f)(void ), void (del)(void *))

리스트 'lst'의 요소들을 순회하며 각 요소의 content에 함수 'f'를 연속적으로 적용시킵니다. 또한 함수 'f'를 적용시킨 결과물들을 content로 담은 새로운 리스트를 생성합니다. 'del' 함수들은 필요 시 각 요소의 content를 삭제하는 데 사용됩니다.

#include"libft.h"

t_list	*ft_lstmap(t_list	*lst, void	*(*f)(void *), void	(*del)(void *))
{
	t_list	*res;
	t_list	*tmp;

	if (!f || !lst)
		return (0);
	res = 0;
	while (lst)
	{
		tmp = ft_lstnew((f)(lst->content));
		if (!tmp)
		{
			ft_lstclear(&res, del);
			return (0);
		}
		ft_lstadd_back(&res, tmp);
		tmp = tmp->next;
		lst = lst->next;
	}
	return (res);
}
profile
코딩뿡뿡이

0개의 댓글