일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 코테
- 컴퓨터구조
- 트리셋
- 운영체제
- 백준
- Spring JPA
- JPA
- 구현
- 해시
- 트리맵
- 프로젝트
- findById
- 산업은행it
- DB replication
- CPU스케줄링
- 파이널프로젝트
- fatch
- 임베디드타입
- flyway
- BFS
- 그래프탐색
- 외래키제약조건위반
- 프로그래머스
- 2178
- springboot
- 스케일아웃
- 폰켓몬
- SpringBatch
- 산업은행청년인턴
- CS
- Today
- Total
나 JAVA 봐라
DFS / 백트래킹 본문
DFS / 백트래킹 이 두가지가 항상 함께 등장하는데, 어떤 차이가 있는지 몰라 정리해보았다.
쉽게 이야기 하자면 끝까지 가는지(DFS)/ 돌아오는지(백트래킹) 의 차이이다.
그래서, DFS 탐색하며 조건을 확인하며 해당 노드가 유망하지 않으면 탐색하지 않는 것 = 백트래킹 이다.
백트래킹도 일반적으로 재귀 형태로 작성되며 크게 3개의 내용을 작성한다.
- 재귀를 진행하는 동안 사용될 깊이(depth)를 매개변수로 넣기
- 재귀가 종료될 때 수행할 내용
- 재귀 종료조건 = 보통 정해진 depth에 도달했을 때
- dfs 함수의 제일 앞에서 종료 조건에 포함되었는지 먼저 검사한다.
- 재귀가 진행 중이면 가지치기(백트래킹)할 내용
백트래킹으로 조합하는 함수를 구현하면 아래와 같다.
public static void combination(int[] arr, int[] result, int start, int depth) {
if (depth == result.length) {
// 조합 출력
for (int i = 0; i < result.length; i++) {
System.out.print(result[i] + " ");
}
System.out.println();
return;
}
for (int i = start; i < arr.length; i++) {
result[depth] = arr[i];
combination(arr, result, i + 1, depth + 1);
}
}
// 아래와 같이 사용할 수 있다.
int[] arr = {1, 2, 3, 4};
int[] result = new int[2];
combination(arr, result, 0, 0);
// 출력 결과
1 2
1 3
1 4
2 3
2 4
3 4
사용되는 변수
- arr: 원본 배열
- result: 조합을 저장하는 배열, 배열의 크기가 nCr 중 r이 된다.
- start: 조합을 만들 때 시작할 인덱스
- depth: 현재 조합의 깊이
재귀 함수의 작동 방식
1. depth가 result.length과 같으면 (모든 숫자가 선택된 경우):
- 조합 출력
- 재귀 함수 종료
2. depth가 result.length보다 작으면:
- start 인덱스부터 arr.length까지 각 숫자를 순회
- 숫자를 선택하고 result 배열에 저장
- depth를 1 증가시키고 재귀 함수 호출
그렇다면 위 코드에서 백트래킹이 적용되는 부분이 무엇인가?
- combination 함수는 재귀 함수를 사용하여 모든 경우의 수를 탐색
- depth가 result.length보다 작을 때, start 인덱스부터 arr.length까지 각 숫자를 순회하며 모든 경우의 수를 탐색
- 조건에 맞지 않는 경우 (예: depth가 result.length보다 크거나, 이미 선택된 숫자를 선택하려는 경우) 다시 돌아가 다른 선택을 시도
=> 즉, dfs 탐색할 때 조건을 확인하여 유효하지 않으면 탐색하지 않음 = 백트래킹 이 적용됨. 으로 볼 수 있다.
만약, DFS 탐색 시에 백트래킹을 적용하지 않았다면, start 인덱스 필요없이 for(int i =0; i< size; i++) 같은 형식을 모든 값들을 탐색하기에 값이 중복되어서 나올 것이다. => {1,2} , {2,1} 둘 다 탐색
좀 더 자세히, 함수가 어떻게 재귀적으로 호출하는지 그림을 그려보았다.
즉, 인덱스 순서대로 DFS 탐색하며 조건이 되지 않으면 탐색하지 않는다. (=백트래킹)
- 또, 보니까 BFS와 비슷하다는 생각을 했는데 (당연히 탐색이니까,,, ) 일단 차이점으로 생각되는 것은
1. BFS는 큐로 구현해서 q.isEmpty == true가 되었을 때 탐색이 끝난다.
2. DFS는 재귀함수로 구현해서 정해진 depth에 도달했을 때 탐색이 끝난다.
참고
문과생이 적어보는 백트래킹 (재귀와 DFS 를 곁들인)
들어가기에 앞서서, 해당 글은 기본적인 문법 (for, while, print, 입력받기, 배열)에 대해서 알고 있음을 전제로 합니다.만약 기본적인 문법을 모르는 상태라면 반복문과 출력, 배열, 입력받기에 대
velog.io
'CS > 자료구조' 카테고리의 다른 글
BFS 너비 우선 탐색 (1) | 2024.01.21 |
---|---|
힙과 우선순위 큐 (0) | 2023.12.31 |