Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 자료구조와함께배우는알고리즘입문
- 스프링부트핵심가이드
- 코드로배우는스프링부트웹프로젝트
- 목록처리
- 티스토리 쿠키 삭제
- 구멍가게코딩단
- 네트워크 설정
- /etc/network/interfaces
- 처음 만나는 AI 수학 with Python
- 데비안
- 이터레이터
- 리눅스
- 코드로배우는스프링웹프로젝트
- 스프링 시큐리티
- resttemplate
- iterator
- baeldung
- 자료구조와 함께 배우는 알고리즘 입문
- 서버설정
- ㅒ
- GIT
- 자바편
- network configuration
- 페이징
- 알파회계
- 친절한SQL튜닝
- d
- 처음 만나는 AI수학 with Python
- Kernighan의 C언어 프로그래밍
- 선형대수
Archives
- Today
- Total
bright jazz music
너비우선탐색(Breadth-First Search, BFS) 본문
Algorithm&Data structure/JS alg.
너비우선탐색(Breadth-First Search, BFS)
bright jazz music 2024. 11. 4. 15:10BFS는 그래프나 트리 구조에서 노드를 탐색하는 알고리즘으로, 루트 노드(혹은 시작 노드)에서 시작하여 인접한 노드들을 먼저 탐색하는 방식이다.
주요 특징:
- 큐(Queue) 자료구조를 사용
- 같은 레벨(depth)에 있는 노드들을 먼저 탐색
- 최단 경로를 찾는 문제에서 많이 사용됨
BFS의 실제 활용 사례:
- 최단 경로 찾기 (예: 네비게이션)
- 웹 크롤링
- SNS에서 친구 추천 시스템
- 네트워크 탐색
아래 코드는 A 노드에서 출발하여 BFS를 하는 과정을 출력한다.
// 그래프를 인접 리스트로 표현
const graph = {
A: ['B', 'C'],
B: ['A', 'D', 'E'],
C: ['A', 'F'],
D: ['B'],
E: ['B', 'F'],
F: ['C', 'E']
};
function bfs(graph, startNode) {
const visited = new Set(); // 방문한 노드를 저장하는 Set. 빈 객체로 선언하기도 함.
const queue = [startNode]; // 탐색할 노드를 저장하는 큐. 빈 배열로 선언하고 .push(startNode)하여 따로 넣어주기도 함.
visited.add(startNode);
while (queue.length > 0) {
const currentNode = queue.shift(); // 큐에서 노드를 꺼냄
console.log(currentNode); // 현재 노드 출력
// 인접한 노드들을 확인
for (const neighbor of graph[currentNode]) {
if (!visited.has(neighbor)) { // 방문하지 않은 노드라면
visited.add(neighbor); // 방문 처리
queue.push(neighbor); // 큐에 추가
}
}
}
}
// 사용 예시
bfs(graph, 'A');
/*
A (시작 노드)
B, C (A의 이웃 노드들)
D, E, F (B와 C의 이웃 노드들)
: 위 순서대로 방문함
*/
이를 응용하여 아래와 같이 최단거리를 구할 수도 있다.
const graph = {
A: ['B', 'C'],
B: ['A', 'D'],
C: ['A', 'E', 'F'],
D: ['B'],
E: ['C'],
F: ['C', 'E'],
G: ['E', 'H'],
H: ['G']
};
const bfs = (graph, startNode, targetNode) => {
const visited = {}; // 방문할 노드를 저장할 객체
const queue = []; // 탐색 예정인 노드들의 대기열인 큐
const distances = {}; // 시작 노드부터의 거리를 저장할 객체
visited[startNode] = true; // 시작 노드를 방문처리
queue.push(startNode); // 시작 노드를 큐에 추가.
distances[startNode] = 0; // 시작노드에서 시작노드까지의 거리를 0으로 지정
while(queue.length > 0) {
const node = queue.shift(); // 큐의 맨 앞에 존재하는 원소를 제거하면서 할당
if(node === targetNode) {
return distances[targetNode]; // 목표 정점에 도달한 경우 거리 반환
}
const adjacentNodes = graph[node]; // 인접 노드들을 가져옴
for( let i = 0; i < adjacentNodes.length; i++) {
const adjacentNode = adjacentNodes[i];
if(!visited[adjacentNode]) { // 미방문 노드인 경우
visited[adjacentNode] = true; // 방문처리
queue.push(adjacentNode) // 큐에 추가
distances[adjacentNode] = distances[node] + 1 // 거리 업데이트
}
}
}
return -1; // 탐색 실패 시 -1 반환
}
// 최단거리 계산 호출 예시
const shortestDistances = bfs(graph, 'A', 'E')
console.log(`A에서 E까지의 최단거리: ${shortestDistances}`) // 2 (A -> C -> E)
/*
가장 좋아하는 연예인 소개 받기
한국인 배열에서, 이소영이 최인기를 찾는 방법
*/
const korean = [
{
이름: "이소영",
주민등록번호: "990825-2305941",
친구: ["990412-1450372", "970501-2295043"]
},
{
이름: "김민수",
주민등록번호: "990412-1450372",
친구: ["990825-2305941", "850410-1234567", "970501-2295043"]
},
/*... */
{
이름: "박지은",
주민등록번호: "970501-2295043",
친구: ["990825-2305941", "850410-1234567"]
},
{
이름: "최인기",
주민등록번호: "850410-1234567", // 찾고자 하는 생일을 가진 사람
친구: ["990412-1450372", "970501-2295043"]
}
];
function findFriendOfFriendBFS(name, targetBirthdate) {
const visited = new Set();
const queue = [];
// 이소영을 큐에 추가
queue.push(
{ // 파라미터 name과 같은 이름을 가진 객체 반환. 따라서 person 속성엔 객체가 값으로 저장된다.
person: korean.find(person => person.이름 === name),
depth: 0
}
)
while(queue.length !== 0) {
const {person, depth} = queue.shift();
if (person) {
// 현재 사용자의 친구 목록을 확인
for (const friendId of person.친구) {
const friend = korean.find(p => p.주민등록번호 === friendId);
if (friend && !visited.has(friendId)) {
visited.add(friendId);
// 생일을 기준으로 최인기 찾기
if(friend.주민등록번호.startsWith(targetBirthdate)) {
return {
찾은사람: friend,
거리: depth + 1
};
}
// 친구의 친구를 큐에 추가
queue.push(
{
person: friend,
depth: depth + 1
}
)
}
}
}
}
return null // 찾지 못한 경우
}
// 이소영의 친구의 친구 중 생일이 1985년 4월 10일인 사용자 찾기
const resultBFS = findFriendOfFriendBFS("이소영", "850410");
console.log(resultBFS);
/*
{
'찾은사람': {
'이름': '최인기',
'주민등록번호': '850410-1234567',
'친구': [ '990412-1450372', '970501-2295043' ]
},
'거리': 2 // 김민수 -> 최인기
}
*/
그러나 단순 최단경로를 구하는 것이 아니고 모든 경우의 수를 고려해야 한다면 외판원 문제(Traveling Salesman Problem, TPS)를 적용해야 할 수도 있다. 최단경로라고 해서 BFS만을 떠올리면 안되는 이유이다.
'Algorithm&Data structure > JS alg.' 카테고리의 다른 글
동적 프로그래밍(Dynamic Programming) (0) | 2024.11.08 |
---|---|
최소신장트리(Minimum Spanning Tree, MST) + (프림, 크루스칼 알고리즘) (0) | 2024.11.05 |
깊이우선탐색(DFS, Depth-First Search) (0) | 2024.11.03 |
이진탐색(Binary Search) (0) | 2024.11.01 |
선형탐색(Linear Search)과 Array.prototype.find() (0) | 2024.10.31 |
Comments