[algorithm] 너비 우선 대 깊이 우선

트리 / 그래프를 탐색 할 때 너비 우선과 깊이의 차이점은 무엇입니까? 모든 코딩 또는 의사 코드 예제가 좋습니다.



답변

이 두 용어는 나무를 걷는 두 가지 방법을 구별합니다.

차이를 나타내는 것이 가장 쉬운 방법 일 것입니다. 나무를 생각해보십시오.

    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 Stack를 사용 하여 막 다른 곳에 도달했을 때 어디로 가야하는지 기억합니다.

  • 따라야 할 규칙 : 첫 번째 정점 A를 Stack

    1. 가능하면 방문하지 않은 인접한 정점을 방문하여 방문한 것으로 표시 한 다음 스택에 밀어 넣습니다.
    2. 규칙 1을 따르지 않으면 가능하면 스택에서 꼭지점을 팝하십시오.
    3. 규칙 1 또는 규칙 2를 수행 할 수 없으면 완료된 것입니다.
  • 자바 코드 :

    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.
  • 준수해야 할 규칙 : 정점 A를 현재 정점으로 시작
    1. 현재 정점에 인접한 다음 방문하지 않은 정점 (있는 경우)을 방문하여 표시 한 다음 대기열에 삽입합니다.
    2. 더 이상 방문하지 않은 정점이 없기 때문에 규칙 1을 수행 할 수 없으면 대기열에서 정점을 제거하고 (가능한 경우) 정점으로 만드십시오.
    3. 대기열이 비어있어 규칙 2를 수행 할 수 없으면 완료된 것입니다.
  • 자바 코드 :

    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는 합리적인 시스템 (예 : 체스 게임을하거나 미로로 나가는 것을 결정하는 사람이나 컴퓨터)의 선택 딜레마와 더 관련이 있습니다.

그래서 저에게있어 자연의 현상이 실제 전파 모델 (이동)과 가장 일치하는 것의 차이점이 있습니다.


답변