[42] libft - bonus part

younoah·2021년 1월 8일
0

42Seoul

목록 보기
3/3

0. 구현 목록

  • ft_lstnew
  • ft_lstadd_front
  • ft_lstsize
  • ft_lstlast
  • ft_lstadd_back
  • ft_lstdelone
  • ft_lstclear
  • ft_lstiter
  • ft_lstmap

1. ft_lstnew

프로토타입

t_list *ft_lstnew(void *content);

설명

새로운 노드를 생성하는 함수. (반환 자체는 연결 리스트가 아닌 1개의 노드이다.)

이 노드의 next에 계속해서 다음 노드를 연결하면 연결 리스트로 사용할 수 있다.

malloc(3)을 할당하고 새로운 요소(노드)를 반환. 변수 'content'는 매개변수 'content'의 값에 따라 초기화된다. 변수 'next'는 NULL로 초기화된다.

파라미터

  • content : 새로운 요소(노드)를 만들 content

리턴값

  • 새로운 요소

구현

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

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

2. ft_lstadd_front

프로토타입

void ft_lstadd_front(t_list **lst, t_list *new);

설명

리스트의 시작부분에 요소 new를 추가.

기존에 있는 리스트에서 맨앞에 새로운 노드를 추가한다.

파라미터

  • **lst : 첫 번째 링크 리스트의 포인터 주소
  • *new : 새로운 노드의 포인터 조수

리턴값

  • None

구현

void	ft_lstadd_front(t_list **lst, t_list *new)
{
	if (!lst || !new)
		return ;
	new->next = *lst;
	*lst = new;
}
  • *lst == NULL 도 예외처리 안해도 된다.
  • 현재 노드가 존재하지 않아도 새로운 노드(new)의 next에 현재노드, 즉, null을 할당해도 문제가 없기 때문이다.

3. ft_lstsize

프로토타입

int ft_lstsize(t_list *lst);

설명

리스트의 노드를 순회하면서 노드의 갯수를 세는 함수이다.

파라미터

  • *lst : 리스트의 시작

리턴값

  • 리스트의 길이

구현

int		ft_lstsize(t_list *lst)
{
	size_t	size;

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

4. ft_lstlast

프로토타입

t_list *ft_lstlast(t_list *lst);

설명

리스트의 마지막 노드를 반환.

파라미터

  • *lst : 리스트의 시작

리턴값

  • 리스트의 마지막 노드

구현

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

5. ft_lstadd_back

프로토타입

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

설명

리스트의 끝에 new 노드를 추가.

파라미터

  • 첫 번째 연결리스트의 포인터 주소
  • 새로 추가할 노드의 포인터 주소

리턴값

  • None

구현

void	ft_lstadd_back(t_list **lst, t_list *new)
{
	if (!lst || !new)
		return ;
	if (*lst == 0)
		*lst = new;
	else
		(ft_lstlast(*lst))->next = new;
}

인자로 t_list **lst 를 사용했을 때

lst 는 리스트의 노드를 가리키는 리스트 그 자체이다. (보통은 리스트의 첫번째가 head이기 때문에 head를 가리킨다.)

*lst 는 해당 리스트의 현재 노드를 가리킨다. (보통 처음에는 lst가 head를 가리키기 때문에 *lst 는 처음에 head 노드 자체를 가리킨다.)

  • lst == 0 은 리스트 자체가 없다는 뜻이다.
  • *lst == 0 은 현재 노드가 없다는 뜻이다.

6. ft_lstdelone

프로토타입

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

설명

한 개의 노드를 삭제하는 함수이다.

먼저 노드의 content 를 삭제(del)하고 해당 노드를 free(메모리해제)함으로써 삭제한다.

파라미터

  • free할 노드
  • content를 삭제하는데 사용되는 함수 포인터

리턴값

  • None

구현

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

노드의 content 는 포인터이므로 content가 가리키는 곳을 del 을 이용해 삭제한다.

content에 접근하려면lst->content 로 접근해야한다. 이때 free(lst) 를 먼저 하게되면 이후에 content 에 접근할 수 없게 되므로 content 를 꼭 먼저 삭제하고 free(lst) 를 해야한다.

7. ft_lstclear

프로토타입

void ft_lstclear(t_list **lst, void (*del)(void *));

설명

연결 리스트의 전체 노드 데이터를 삭제하는 함수이다.

주어진 노드와 해당 노드의 모든 후속 노드를 삭제하고 free한다.

파라미터

  • 노드의 포인터 주소
  • 노드의 content를 삭제하는데 사용되는 함수 포인터

리턴값

  • None

구현

void	ft_lstclear(t_list **lst, void (*del)(void *))
{
	t_list	*tmp;

	if (!lst || !del)
		return ;
	while (*lst)
	{
		tmp = (*lst)->next;
		ft_lstdelone(*lst, del);
		*lst = tmp;
	}
}
  • 다음 노드를 우선 임시로 보관한다.
  • 현재 리스트의 해당 노드를 삭제한다.
  • 현재 리스트를 다음 노드로 가리킨다.
  • 반복한다.

8. ft_lstiter

프로토타입

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

설명

노드를 순회하며 각 노드의 content에 함수 f 함수를 적용시킨다.

파라미터

  • 노드의 포인터
  • 리스트에 반복적으로 사용되는 함수 포인터

리턴값

  • None

구현

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

9. ft_lstmap

프로토타입

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

설명

노드를 순회하며 각 노드의 content에 함수 f 를 적용시키고 새로운 리스트를 만든다.

만약 f 함수로 새로운 리스트를 만들다가 노드 생성에 실패시 함수 del을 이용하여 만들던 리스트를 삭제하고 NULL을 리턴한다.

파라미터

  • 노드의 포인터주소
  • 리스트에 반복적으로 사용되는 함수 포인터
  • 필요한 경우 노드의 content를 삭제하기 위해 사용되는 함수 포인터

리턴값

  • 새로운 리스트
  • 할당 실패시 NULL

구현

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

	if (!lst || !f)
		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
console.log(noah(🍕 , 🍺)); // true

0개의 댓글