[알고리즘] 깊이 우선 탐색(DFS) / 너비 우선 탐색(BFS)

2022. 5. 7. 20:54· Algorithm
목차
  1. [깊이 우선 탐색(DFS)] 
  2.  
  3.  
  4.  
  5.  
  6.  
  7. [너비 우선 탐색(BFS)]
그래프를 탐색하는 알고리즘

 

[깊이 우선 탐색(DFS)] 

이름처럼 한길만 깊이 파고드는 알고리즘이다 (depth)

 

<특징>

1. 하나의 정점에서 다른 하나의 정점만 탐색한다(한 사람에게만 연락한다)

2. 스택을 이용하여 경로를 되돌아간다★

3. 처음 탐색을 시작한 정점의 위치에서 탐색은 끝이 난다

 

 

▶ DFS의 구현

 

<주요 장치>

 

  • 스택 : 경로 정보의 추적을 목적 (내가 이미 탐색을 완료해서 탐색할 기회를 다른 정점에게 넘긴 애들만 들어옴)
  • 배열 : 방문 정보의 기록을 목적

 

그래프 구현한 내용에서 DFS 탐색 기능(스택+연결리스트)만 추가

<실제 구현>

 

  • 정점의 이름
// 정점의 이름들을 상수화
enum {A, B, C, D, E, F, G, H, I, J};

 

 

  • 그래프를 표현한 구조체 (탐색이 완료된 정점의 정보 추가 by 배열)
typedef struct _ual
{
	int numV;   // 정점의 수
	int numE;   // 간선의 수
	List * adjList;   // 간선의 정보
	int * visitInfo; //탐색이 완료된 정점의 정보(배열로 할당됨)
} ALGraph;

 

 

  • 정점의 방문을 진행하는 함수 (이미 방문 했는지(FALSE) 안했는지(TRUE) 구분함)
int VisitVertex(ALGraph * pg, int visitV)
{
	if(pg->visitInfo[visitV] == 0)
	{
		pg->visitInfo[visitV] = 1;
		printf("%c ", visitV + 65);     // 방문 정점 출력
		return TRUE; //방문 안했으면 TRUE 반환
	}
	
	return FALSE; //방문 했으면 FALSE 반환
}

 

 

 

  • 실제 DFS의 구현 !!
void DFShowGraphVertex(ALGraph * pg, int startV)
{
	Stack stack;
	int visitV = startV;
	int nextV;

	// DFS를 위한 스택의 초기화
	StackInit(&stack);

	VisitVertex(pg, visitV);    // 시작 정점 방문
	SPush(&stack, visitV);

	while(LFirst(&(pg->adjList[visitV]), &nextV) == TRUE)
	{
		int visitFlag = FALSE;

		if(VisitVertex(pg, nextV) == TRUE)//첫번째 노드가 탐색이 이뤄질수 있음
		{
			SPush(&stack, visitV);
			visitV = nextV;
			visitFlag = TRUE;
		}
		else //첫번째 노드가 탐색이 안돼서 다음 탐색 안한 노드를 찾아야 함
		{
			while(LNext(&(pg->adjList[visitV]), &nextV) == TRUE)
			{
				if(VisitVertex(pg, nextV) == TRUE)
				{
					SPush(&stack, visitV);
					visitV = nextV;
					visitFlag = TRUE;
					break;
				}
			}
		}
		
		if(visitFlag == FALSE) //지금 있는 노드 주변은 다 탐색을 함
		{
			if(SIsEmpty(&stack) == TRUE)    // 스택이 비면 DFS종료
				break;
			else	// 스택이 안비어 있으면 이전으로 돌아감
				visitV = SPop(&stack);	
		}
	}

	// 탐색 정보 초기화
	memset(pg->visitInfo, 0, sizeof(int) * pg->numV);
}

 

이 모형을 떠올리면서 위 구현을 이해

 

더보기

562~563P에 야무지게 정리해 놓음

 

 

 

 

[너비 우선 탐색(BFS)]

 자신에게 연결된 모든 정점을 탐색하는 방식 (breadth)

 

<특징>

1. 자신과 연결된 모든 정점을 탐색한다 (폭을 우선시하는 방식)

2. 큐를 이용하여 폭 넓히는 탐색을 진행할 정점의 순서를 정한다★

3. 큐가 비고 정점을 더 탐색할수 없으면 탐색은 끝이 난다

 

 

 

 

▶ BFS의 구현

 

<주요 장치>

 

  • 큐 : 방문 차례의 기록 목적
  • 배열 : 방문 정보의 기록을 목적

 

 

그래프에서 DFS 구현한 내용에서 BFS 탐색 기능(큐+연결리스트)만 추가

 

<실제 구현> 

 

  • 정점의 이름
// 정점의 이름들을 상수화
enum {A, B, C, D, E, F, G, H, I, J};

 

 

  • 그래프를 표현한 구조체 (탐색이 완료된 정점의 정보 추가 by 배열)
typedef struct _ual
{
	int numV;   // 정점의 수
	int numE;   // 간선의 수
	List * adjList;   // 간선의 정보
	int * visitInfo; //탐색이 완료된 정점의 정보(배열로 할당됨)
} ALGraph;

 

 

  • 정점의 방문을 진행하는 함수 (이미 방문 했는지(FALSE) 안했는지(TRUE) 구분함)
int VisitVertex(ALGraph * pg, int visitV)
{
	if(pg->visitInfo[visitV] == 0)
	{
		pg->visitInfo[visitV] = 1;
		printf("%c ", visitV + 65);     // 방문 정점 출력
		return TRUE; //방문 안했으면 TRUE 반환
	}
	
	return FALSE; //방문 했으면 FALSE 반환
}

 

  • 실제 BFS의 구현 !!
void BFShowGraphVertex(ALGraph * pg, int startV)
{
	Queue queue;
	int visitV = startV;
	int nextV;

	// BFS를 위한 큐의 초기화
	QueueInit(&queue);

	// 시작 정점 탐색
	VisitVertex(pg, visitV);

	while(LFirst(&(pg->adjList[visitV]), &nextV) == TRUE)
	{
		if(VisitVertex(pg, nextV) == TRUE) //리스트의 첫번째 노드가 처음 방문이면 큐에 삽입 
			Enqueue(&queue, nextV);

		while(LNext(&(pg->adjList[visitV]), &nextV) == TRUE)
        //한 리스트의 모든 노드를 방문하고 처음 방문이면 큐에 삽입
		{
			if(VisitVertex(pg, nextV) == TRUE)
				Enqueue(&queue, nextV);
		}

		if(QIsEmpty(&queue) == TRUE)    // 큐가 비면 BFS 종료
			break;
		else 
        // 하나의 리스트를 다 탐색(=하나의 정점에서 모든 연결된 정점을 탐색)하면 
        //가장 먼저 큐에 들어간 리스트를 visitV로 설정
			visitV = Dequeue(&queue);	
	}

	// 탐색 정보 초기화
	memset(pg->visitInfo, 0, sizeof(int) * pg->numV);
}

 

 

이 모형을 떠올리면서 위 구현을 이해

 

'Algorithm' 카테고리의 다른 글

[알고리즘] 다이나믹 프로그래밍 (DP)  (0) 2022.06.01
[알고리즘] PS에 필요한 수학지식  (0) 2022.05.24
[알고리즘] 재귀 알고리즘  (0) 2022.04.29
  1. [깊이 우선 탐색(DFS)] 
  2.  
  3.  
  4.  
  5.  
  6.  
  7. [너비 우선 탐색(BFS)]
'Algorithm' 카테고리의 다른 글
  • [알고리즘] 다이나믹 프로그래밍 (DP)
  • [알고리즘] PS에 필요한 수학지식
  • [알고리즘] 재귀 알고리즘
생선묵김치찌개
생선묵김치찌개
생선묵김치찌개
준혁's 코딩 연구기록
생선묵김치찌개
전체
오늘
어제
  • 분류 전체보기 (96)
    • Java (5)
    • Spring Boot (3)
    • 자료구조 (8)
    • 네트워크 (4)
    • 데이터베이스 (4)
    • 기술적 고민 (17)
      • Side Match (13)
      • 자리나따 (4)
    • C++ (3)
    • Algorithm (4)
    • PS 연습 (38)
    • 잡동사니 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 배열 리스트
  • 백준 골드
  • 이진트리
  • DN
  • 완전탐색
  • 파일 업로드
  • 열혈 자료구조
  • 스택
  • 자료구조
  • 예외처리
  • 백준
  • open api
  • 수식트리
  • 트리
  • 재귀
  • 큐
  • 양방향 연결 리스트
  • dp
  • 원형 연결 리스트
  • 스프링
  • 브루트 포스
  • aws rds
  • CPP
  • Stream
  • ㄱ
  • sentry
  • 알고리즘
  • 단순 연결 리스트
  • backend
  • 해커톤

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
생선묵김치찌개
[알고리즘] 깊이 우선 탐색(DFS) / 너비 우선 탐색(BFS)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.