트리 / 그래프를 탐색 할 때 너비 우선과 깊이의 차이점은 무엇입니까? 모든 코딩 또는 의사 코드 예제가 좋습니다.
트리 / 그래프를 탐색 할 때 너비 우선과 깊이의 차이점은 무엇입니까? 모든 코딩 또는 의사 코드 예제가 좋습니다.
답변:
이 두 용어는 나무를 걷는 두 가지 방법을 구별합니다.
차이를 나타내는 것이 가장 쉬운 방법 일 것입니다. 나무를 생각해보십시오.
A
/ \
B C
/ / \
D E F
깊이 우선 탐색은 다음 순서로 노드를 방문합니다
A, B, D, C, E, F
계속 진행 하기 전에 한쪽 다리를 완전히 내려가십시오 .
폭 우선 탐색은 다음 순서로 노드를 방문합니다
A, B, C, D, E, F
여기에서 우리는 모든 방법을 일 에 걸쳐 내려 가기 전에 각 수준.
(순서 순서에는 약간의 모호함이 있으며 트리의 각 레벨에서 "읽기"순서를 유지하는 것을 부정했습니다. 두 경우 모두 C 전후에 B에 도달 할 수 있으며 마찬가지로 F 전후에 E. 이것은 귀하의 신청에 따라 달라질 수 있습니다 ...)
의사 코드를 사용하여 두 종류의 순회를 모두 수행 할 수 있습니다.
Store the root node in Container
While (there are nodes in Container)
N = Get the "next" node from Container
Store all the children of N in Container
Do some work on N
두 순회 순서의 차이점은의 선택에 Container
있습니다.
재귀 구현은 다음과 같습니다
ProcessNode(Node)
Work on the payload Node
Foreach child of Node
ProcessNode(child)
/* Alternate time to work on the payload Node (see below) */
자식이없는 노드에 도달하면 재귀가 종료되므로 유한 한 비 주기적 그래프에서 종료됩니다.
이 시점에서 나는 여전히 약간의 속임수를 썼다. 약간의 영리함을 통해 다음 순서로 노드에서 작업 할 수도 있습니다 .
D, B, E, F, C, A
이것은 깊이 우선의 변형으로, 나무 위로 올라갈 때까지 각 노드에서 작업을 수행하지 않습니다. 그러나 나는 아이들을 찾기 위해 아래로 더 높은 노드를 방문 했습니다.
이 순회는 재귀 구현에서 매우 자연스럽고 (첫 번째 "작업"줄 대신 "교체 시간"줄 사용) 명시 적 스택을 사용하는 경우 에는 너무 어렵지 않지만 연습으로 남겨 두겠습니다.
A, B, D, C, E, F
-첫 번째로 제시된), 접두사 ( - D, B, A, E, C, F
정렬에 사용-AVL 트리로 추가 한 다음 접두사 를 읽음) 또는 접미사 ( D, B, E, F, C, A
대체 제시) 순회 를 얻도록 깊이 우선 버전을 수정할 수 있습니다 . 이름은 루트를 처리하는 위치에 따라 지정됩니다. infix는 이진 트리에만 실제로 의미가 있습니다. @ batbrat 그 이름은 ... 당신이 물어 본 이후 시간이 주어지면 아마 이미 알고있을 것입니다.
이 그림은 너비 와 깊이 라는 단어 가 사용되는 상황에 대한 아이디어를 제공합니다 .
깊이 우선 검색 알고리즘은 가능한 한 빨리 시작점에서 멀어 지길 원하는 것처럼 작동합니다.
일반적으로 a Stack
를 사용 하여 막 다른 곳에 도달했을 때 어디로 가야하는지 기억합니다.
따라야 할 규칙 : 첫 번째 정점 A를 Stack
자바 코드 :
public void searchDepthFirst() {
// Begin at vertex 0 (A)
vertexList[0].wasVisited = true;
displayVertex(0);
stack.push(0);
while (!stack.isEmpty()) {
int adjacentVertex = getAdjacentUnvisitedVertex(stack.peek());
// If no such vertex
if (adjacentVertex == -1) {
stack.pop();
} else {
vertexList[adjacentVertex].wasVisited = true;
// Do something
stack.push(adjacentVertex);
}
}
// Stack is empty, so we're done, reset flags
for (int j = 0; j < nVerts; j++)
vertexList[j].wasVisited = false;
}
응용 분야 : 깊이 우선 검색은 종종 게임 시뮬레이션 (실제 게임과 같은 상황)에 사용됩니다. 일반적인 게임에서는 몇 가지 가능한 동작 중 하나를 선택할 수 있습니다. 각 선택은 추가 선택으로 이어지고, 각 선택은 추가 선택으로 이어지고, 계속 확장되는 나무 모양의 가능성 그래프로 이어집니다.
Queue
.자바 코드 :
public void searchBreadthFirst() {
vertexList[0].wasVisited = true;
displayVertex(0);
queue.insert(0);
int v2;
while (!queue.isEmpty()) {
int v1 = queue.remove();
// Until it has no unvisited neighbors, get one
while ((v2 = getAdjUnvisitedVertex(v1)) != -1) {
vertexList[v2].wasVisited = true;
// Do something
queue.insert(v2);
}
}
// Queue is empty, so we're done, reset flags
for (int j = 0; j < nVerts; j++)
vertexList[j].wasVisited = false;
}
응용 프로그램 : 너비 우선 검색은 먼저 시작점에서 한 모서리 떨어진 정점을 찾은 다음 두 모서리 떨어진 정점 등을 찾습니다. 시작 정점에서 주어진 정점까지의 최단 경로를 찾으려고 할 때 유용합니다.
너비 우선 검색 및 깊이 우선 검색을 이해하기에 충분해야합니다. 자세한 내용은 Robert Lafore의 훌륭한 데이터 구조 책에서 Graphs 장을 참조하십시오.
이 이진 트리가 주어지면 :
폭 우선 순회 :
왼쪽에서 오른쪽으로 각 레벨을 가로 질러 이동합니다.
"저는 G입니다. 제 아이들은 D입니다. 제 손자는 B, E, H, K입니다. 손자는 A, C, F입니다."
- Level 1: G
- Level 2: D, I
- Level 3: B, E, H, K
- Level 4: A, C, F
Order Searched: G, D, I, B, E, H, K, A, C, F
깊이 우선 탐색 :
순회는 한 번에 전체 레벨을 가로 질러 수행되지 않습니다. 대신 순회는 먼저 나무의 깊이 (뿌리에서 잎으로)로 다이빙합니다. 그러나 단순히 위아래로하는 것보다 조금 더 복잡합니다.
세 가지 방법이 있습니다.
1) PREORDER: ROOT, LEFT, RIGHT.
You need to think of this as a recursive process:
Grab the Root. (G)
Then Check the Left. (It's a tree)
Grab the Root of the Left. (D)
Then Check the Left of D. (It's a tree)
Grab the Root of the Left (B)
Then Check the Left of B. (A)
Check the Right of B. (C, and it's a leaf node. Finish B tree. Continue D tree)
Check the Right of D. (It's a tree)
Grab the Root. (E)
Check the Left of E. (Nothing)
Check the Right of E. (F, Finish D Tree. Move back to G Tree)
Check the Right of G. (It's a tree)
Grab the Root of I Tree. (I)
Check the Left. (H, it's a leaf.)
Check the Right. (K, it's a leaf. Finish G tree)
DONE: G, D, B, A, C, E, F, I, H, K
2) INORDER: LEFT, ROOT, RIGHT
Where the root is "in" or between the left and right child node.
Check the Left of the G Tree. (It's a D Tree)
Check the Left of the D Tree. (It's a B Tree)
Check the Left of the B Tree. (A)
Check the Root of the B Tree (B)
Check the Right of the B Tree (C, finished B Tree!)
Check the Right of the D Tree (It's a E Tree)
Check the Left of the E Tree. (Nothing)
Check the Right of the E Tree. (F, it's a leaf. Finish E Tree. Finish D Tree)...
Onwards until...
DONE: A, B, C, D, E, F, G, H, I, K
3) POSTORDER:
LEFT, RIGHT, ROOT
DONE: A, C, B, F, E, D, H, K, I, G
사용법 (일명, 우리가 관심
을 갖는 이유) : 깊이 우선 탐색 방법에 대한 간단한 Quora 설명과 그 방법이 일반적으로 사용되는 방법을 정말 즐겼습니다
. "
"주문 순회는 [이진 검색 트리]의 사본을 만드는 데 사용됩니다. "
"사후 순회는 [이진 검색 트리]를 삭제하는 데 사용됩니다."
https://www.quora.com/What-is-the-use-of-pre-order-and-post-order-traversal-of-binary-trees-in-computing
코드를 바꾸는 것만으로 하나의 알고리즘 또는 다른 알고리즘을 얻을 수있는 방식으로 두 가지를 작성하는 것이 흥미로울 것이라고 생각합니다. .
저는 개인적으로 풍경을 범람하는 것으로 BFS를 해석하는 것을 좋아합니다. 저고도 지역은 먼저 침수 될 것이고, 그 후에 만 고고도 지역은 따라 올 것입니다. 지리 책에서 볼 수 있듯이 가로 고도를 등각 선으로 생각하면 BFS가 물리학에서와 마찬가지로 동일한 등선 아래의 모든 영역을 동시에 채울 수 있습니다. 따라서 고도를 거리 또는 스케일 비용으로 해석하면 알고리즘에 대한 직관적 인 아이디어를 얻을 수 있습니다.
이를 염두에두고 광범위한 첫 번째 검색 뒤에있는 아이디어를 쉽게 적용하여 최소 스패닝 트리를 쉽게 찾고, 최단 경로 및 기타 여러 최소화 알고리즘을 찾을 수 있습니다.
나는 DFS에 대한 직관적 인 해석을 아직 보지 못했지만 (미로에 대한 표준 만 있지만 BFS만큼 강력하지 않고 범람하지는 않습니다), BFS는 위에서 설명한 것처럼 물리적 현상과 더 나은 상관 관계가있는 것처럼 보입니다. DFS는 합리적인 시스템 (예 : 체스 게임을하거나 미로로 나가는 것을 결정하는 사람이나 컴퓨터)의 선택 딜레마와 더 관련이 있습니다.
그래서 저에게있어 자연의 현상이 실제 전파 모델 (이동)과 가장 일치하는 것의 차이점이 있습니다.