jaewpark 2021. 9. 2. 10:47

FILO(Last-In-First-Out), 후입선출의 특성

 

구현해야 하는 필수 요소

  • 푸시 연산
    • ⚠️ 스택의 크기를 초과해 새로운 자료를 추가하지 못하는 현상을 오버플로
    • 스택에 새로운 자료를 추가
  • 팝 연산
    • ⚠️ 아무 자료가 없는 빈 스택에 연산을 하게 되면 언더플로 현상 발생
    • 스택에서 자료를 제거
  • 피크
    • 연산자료를 제거 🚫
    • 스택의 맨 위 자료를 반환

특정 정보 기억 후 재이용 할 때 주로 사용

  • 컴퓨터 알고리즘에서 자주 쓰이는 데이터구조
  • 수행 중의 프로그램 함수나 서브프로그램들의 복귀주소와 관련된 여러 정보들을 저장

 

🐬배열리스트를 이용한 구현 

더보기
#include "array_list.h"

int	ft_push(t_array_list *list, int *top, int new_data)
{
	t_array_node new_node;

	if (list->curr_element_cnt == list->max_element_cnt)
	{
    printf("Error! Overflow\n");
    return (-1);
  }
	new_node.data = new_data;
	list->p_element[(*top) + 1] = new_node;
	++(*top);
	++list->curr_element_cnt;
	return (0);
}

int	ft_pop(t_array_list *list, int *top)
{
	if (list->curr_element_cnt == 0)
  {
    printf("Error! Underflow\n");
		return (-1);
  }
	list->p_element[*top].data = 0;
	--list->curr_element_cnt;
	--(*top);
	return (0);
}

int ft_peek(t_array_list *list, int *top)
{
	if (list->curr_element_cnt == 0)
		return (-1);
	return (list->p_element[*top].data);
}
#include "array_list.h"

int ft_get_array_list_length(t_array_list *p_list)
{
	int cnt = 0;
	for(int i = 0; i < p_list->max_element_cnt; i++)
	{
		if (p_list->p_element[i].data != 0)
			++cnt;
	}
	return (cnt);
}

int ft_is_array_list_full(t_array_list *p_list)
{
	int i = -1;
	int cnt = -1;
	if (p_list->p_element == NULL)
		return (1);
	while (++i < p_list->max_element_cnt)
	{
		if (p_list->p_element[i].data == 0)
			++cnt;
	}
	return (cnt);
}

int ft_add_element_to_array_list(t_array_list *p_list, int position, t_array_node element)//뒤쪽이 빈 거라고 가정
{
	if (ft_is_array_list_full(p_list) < 0)
		return (-1);
	int i = p_list->max_element_cnt - 1;
	while (i > position)
	{
		p_list->p_element[i].data = p_list->p_element[i - 1].data;
		--i;
	}
	p_list->p_element[i].data = element.data;
	++p_list->curr_element_cnt;
	return (0);
}  

int ft_remove_element_from_array_list(t_array_list *p_list, int position)
{
	int i = position;
	while (i < p_list->max_element_cnt - 1)
	{	
		p_list->p_element[i].data = p_list->p_element[i + 1].data;
		++i;
	}
	p_list->p_element[i].data = 0;
	--p_list->curr_element_cnt;
	return (0);
}

void ft_delete_array_list(t_array_list *p_list)
{
	for(int i = 0; i < p_list->max_element_cnt; i++) //배열 원소 삭제
		p_list->p_element[i].data = 0; //이게 다일까?
	free(p_list->p_element);
	p_list->p_element = NULL;
	p_list->max_element_cnt = 0;
	p_list->curr_element_cnt = 0;
	return ;
}

void ft_display_array_list(t_array_list *p_list)
{
	if (p_list->p_element == NULL)
		return ;
	for (int i = 0; i < p_list->max_element_cnt; i++)
		printf("array[%d]: %d\n", i, p_list->p_element[i].data);
	return ;
}

void ft_clear_array_list(t_array_list *p_list)
{
	for(int i = 0; i < p_list->max_element_cnt; i++) //배열 원소 삭제
		p_list->p_element[i].data = 0; //이게 다일까?
	p_list->curr_element_cnt = 0;
	return ;
}

t_array_node *ft_get_element_from_array_list(t_array_list *p_list, int position)
{
	return (&(p_list->p_element[position]));
}

t_array_list *ft_create_array_list(int max_element_cnt)
{
	t_array_list *array_list;

	array_list = (t_array_list *)malloc(sizeof(t_array_list));
	array_list->max_element_cnt = max_element_cnt;
	array_list->curr_element_cnt = 0;
	array_list->p_element = (t_array_node *)malloc(sizeof(t_array_node) * max_element_cnt);
	for(int i = 0; i < max_element_cnt; i++) //배열 초기화
		array_list->p_element[i].data = 0;
	return (array_list);
}

🐬링크드 리스트를 이용한 구현

더보기
#include "linked_list.h"

void ft_push(t_linked_list *pList, int data){
  t_linked_list_node *new_node = NULL;
  new_node = ft_create_element(data);
  if (!new_node)
  {
    printf("Error! Wrong malloc\n");
    return ;
  }
  if (pList->header_node->next == NULL)
    pList->header_node->next = new_node;
  else
  {
    new_node->next = pList->header_node->next;
    pList->header_node->next = new_node;
  }
}

void ft_pop(t_linked_list *pList){
  t_linked_list_node *tmp_node = NULL;
  if (pList->header_node->next == NULL)
  {
    printf("Error! Underflow\n");
    return ;
  }
  tmp_node = pList->header_node->next;
  pList->header_node->next = pList->header_node->next->next;
  tmp_node->next = NULL;
  free(tmp_node);
}

int ft_peek(t_linked_list *pList){
  return (pList->header_node->next->data);
}
#include "linked_list.h"

void	ft_reverse_linked_list(t_linked_list *p_list)
{
	t_linked_list_node 		*origin;
	t_linked_list_node		*curr;

	if (p_list->num_of_current_element <= 1)
		return ;
	curr = p_list->header_node->next; 
	origin = curr->next;
	curr->next = NULL; 
	while (origin != NULL)
	{
		curr = origin;
		origin = origin->next;
		curr->next = p_list->header_node->next;
		p_list->header_node->next = curr;
	}
	return ;
}

t_linked_list	*ft_create_linked_list()
{
	t_linked_list	*list;

	list = (t_linked_list *)malloc(sizeof(t_linked_list));
	if (list == NULL)
		return (NULL);
	list->header_node = ft_create_element(0);
	list->num_of_current_element = 0;
	return (list);
}

int	ft_add_element_to_linked_list(t_linked_list *p_list, int position, t_linked_list_node *element)
{
	t_linked_list_node *curr;

	curr = p_list->header_node;
	int cnt = 0;
	while (curr)
	{
		if (cnt == position)
		{
			element->next = curr->next;
			curr->next = element;
			++p_list->num_of_current_element;
			return (0);
		}
		++cnt;
		curr = curr->next;
	}
	return (0);
}

int	ft_add_last_element_to_linked_list(t_linked_list *p_list, t_linked_list_node *element)
{
	t_linked_list_node *curr;

  	if (p_list->header_node->next == NULL)
  	{  
   		p_list->header_node->next = element;
   		++p_list->num_of_current_element;
    return (0);
  	}
  	curr = p_list->header_node->next;
	while (curr->next != NULL)
	{
		curr = curr->next;
	}
  	++p_list->num_of_current_element;
	curr->next = element;
	return (0);
}

void	ft_print_linked_list(t_linked_list *p_list)
{
	t_linked_list_node *curr;
	
	curr = p_list->header_node->next;
	int i = 0;
	while (curr)
	{
		printf("node[%d] -> data: %d\n", i, curr->data);
		++i;
		curr = curr->next;
	}
	return ;
}

t_linked_list_node	*ft_create_element(int data)
{
	t_linked_list_node *new_element;
	
	new_element = (t_linked_list_node *)malloc(sizeof(t_linked_list_node));
	if (new_element == NULL)
		return (NULL);
	new_element->data = data;
	new_element->next = NULL;
	return (new_element);
}

int	ft_remove_element_from_linked_list(t_linked_list *p_list, int position)
{
	int					idx;
	t_linked_list_node	*curr;
	t_linked_list_node	*tmp;

	if (position >= p_list->num_of_current_element)
		return (-1);
	idx = 0;
	curr = p_list->header_node;
	while (curr)
	{
		if (idx == position)
		{
			tmp = curr->next;
			curr->next = curr->next->next;
			free(tmp);
			--p_list->num_of_current_element;
			return (0);
		}
		++idx;
		curr = curr->next;
	}
	return (0);
}

t_linked_list_node	*ft_get_element_from__linked_list(t_linked_list *p_list, int position)
{
	int					idx;
	t_linked_list_node	*curr;

	idx = 0;
	curr = p_list->header_node->next;
	while (curr)
	{
		if (idx == position)
		{
			return (curr);
		}
		++idx;
		curr = curr->next;
	}
	return (NULL);
}

void	ft_clear_linked_list(t_linked_list *p_list)
{
	t_linked_list_node	*curr;
	
	curr = p_list->header_node->next;
	while (curr)
	{
		curr->data = 0;
		curr = curr->next;
	}
	p_list->num_of_current_element = 0;
	return ;
}

void	ft_delete_linked_list(t_linked_list *p_list)
{
	t_linked_list_node *curr;
	t_linked_list_node *tmp;

	curr = p_list->header_node;
	tmp = curr;
	while (curr)
	{
		curr = curr->next;
		free(tmp);
		tmp = curr;
	}
	p_list->header_node->next = NULL;
	p_list->num_of_current_element = 0;
	return ;
}

 

미로찾기 구현

💨 data를 담는 것을 구조체에 만들어서 저장

#ifndef PROJECT_H
# define PROJECT_H

# define  UP    0
# define  RIGHT 1
# define  DOWN  2
# define  LEFT  3

# define  MAPSIZE 7

int DIRECTION_OFFSETS[4][2] = {
    {0, -1}, // 위쪽으로이동.
    {1, 0}, // 오른쪽으로이동.
    {0, 1}, // 아래쪽으로이동.
    {-1, 0} // 왼쪽으로이동.
  };

void  move(t_coordinate *point, int direction);
int   isMovable(int map[][MAPSIZE], int x, int y);
void  findRoute(int map[][MAPSIZE]);

#endif
#include "linked_list.h"
#include "project.h"

int main () {
  
  int myMaze[MAPSIZE][MAPSIZE] = {
    {0, 0, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 0, 0},
    {1, 1, 1, 0, 1, 1, 1},
    {1, 1, 1, 0, 1, 1, 1},
    {1, 1, 0, 0, 0, 0, 0},
    {1, 1, 1, 0, 1, 1, 1},
    {1, 0, 0, 0, 0, 0, 0},
  };

  findRoute(myMaze);

  return (0);
}

void move(t_coordinate *point, int direction)
{
  point->x += DIRECTION_OFFSETS[direction][0];
  point->y += DIRECTION_OFFSETS[direction][1];
}

/*
  인자로 넘겨진 위치가 이동가능한지? -> 맵크기비교 + 그 자리가 0인지?
*/
int isMovable(int map[][MAPSIZE], int x, int y)
{
  if (x < 0 || x > MAPSIZE - 1 || y < 0 || y > MAPSIZE - 1)
    return (0);
  if (map[y][x] == 1)
    return (0);
  return (1);
}

void  findRoute(int map[][MAPSIZE])
{
  t_coordinate  point;
  t_linked_list *list;

  list = ft_create_linked_list();
  point.x = 0;
  point.y = 0;

  while (!(point.x == MAPSIZE - 1 && point.y == MAPSIZE - 1)) {  
    map[point.y][point.x] = 1;
    //printf("[%d, %d]\n", point.x, point.y);
    if (isMovable(map, point.x, point.y - 1)) {
      ft_push(list, point);
      move(&point, UP);
      //printf("u");
    }
    else if (isMovable(map, point.x + 1, point.y)) {
      ft_push(list, point);
      move(&point, RIGHT);
      //printf("r");
    }
    else if (isMovable(map, point.x, point.y + 1)) {
      ft_push(list, point);
      move(&point, DOWN);
      //printf("d");
    }
    else if (isMovable(map, point.x - 1, point.y)) {
      ft_push(list, point);
      move(&point, LEFT);
      //printf("l");
    }
    else {  // 전부 못간다면
      if (point.x == 0 && point.y == 0) // 출구 없음!
      {
        printf("Error! No EXIT");
        exit(1);
      }
      point = ft_peek(list)->point; // 이전 위치로 이동
      ft_pop(list);
      //printf("what?\n");
    }
  }
  if (point.x == MAPSIZE - 1 && point.y == MAPSIZE - 1)
    ft_push(list, point);
  ft_reverse_linked_list(list); // 역순
  ft_print_linked_list(list); //출력
}