데이터 구조|이진 트리의 세 가지 순회 방법, 몇 가지를 마스터하셨습니까?

목차

1. 순회 방법

2. 선주문 순회

3. 중위 순회

1. 순회 방법

이진 트리의 구조를 배우는 가장 쉬운 방법은 이진 트리를 순회하는 것입니다. 이진 트리를 순회하는 것은 특정 라인을 통해 이진 트리의 각 노드를 방문하는 것 입니다. 액세스 방법에는 사전 순회, 순차 순회 및 후속 순회가 있습니다. 계층 순회의 순회 순서는 다음과 같습니다.

  • 선주문 순회: 루트 노드 = "루트 노드의 왼쪽 하위 트리 = "루트 노드의 오른쪽 하위 트리
  • 순서 순회: 루트 노드의 왼쪽 노드 = " 루트 노드 =" 루트 노드의 오른쪽 하위 트리
  • 후속 순회: 루트 노드의 왼쪽 노드 = "루트 노드의 오른쪽 노드 = " 루트 노드

이진 트리의 순회에서 순회의 시작은 헤드 노드에서 시작하고 순회의 끝도 헤드 노드에서 끝납니다.


값이 123456인 6개의 노드 ABCDEF가 있는 이진 트리가 있습니다. 해당 구조는 다음과 같습니다.

  • A가 루트 노드일 때 A의 왼쪽 하위 트리는 D이고 A의 오른쪽 하위 트리는 E이며 A의 값은 1입니다.
  • B가 루트 노드일 때 B의 왼쪽 하위 트리는 D이고 B의 오른쪽 하위 트리는 E이며 B의 값은 2입니다.
  • C가 루트 노드일 때 C의 왼쪽 하위 트리는 null이고 C의 오른쪽 하위 트리는 F이며 C의 값은 3입니다.
  • D가 루트 노드일 때 D의 왼쪽 하위 트리는 null이고 F의 오른쪽 하위 트리는 null이며 값은 4입니다.
  • E가 루트 노드일 때 E의 왼쪽 하위 트리는 null이고 F의 오른쪽 하위 트리는 null이며 그 값은 5입니다.
  • F가 루트 노드일 때 F의 왼쪽 하위 트리는 null이고 F의 오른쪽 하위 트리는 null이며 값은 6입니다.

이 블로그 게시물에서 실행되는 순회 방법은 모두 위 그림의 이진 트리에 표시됩니다.


2. 선주문 순회

선주문 순회, 순회 순서는 루트 노드 = "루트 노드의 왼쪽 하위 트리 = "루트 노드의 오른쪽 하위 트리 입니다 . 따라서 위에서 정의한 이진 트리를 선순위로 순회하는 순서는 다음과 같아야 합니다. ABDECF에서 얻은 값도 124536이어야 합니다. 특정 구현 방법에 대한 다음 설명을 참조하십시오.

첫 번째 단계는 루트 노드 A를 가져오는 것입니다. 노드에 왼쪽 하위 트리가 있는지 확인합니다. 그렇다면 다음 왼쪽 하위 트리로 이동합니다. 오른쪽 하위 트리가 없으면 오른쪽 하위 트리를 순회하고, 오른쪽 하위 트리가 없으면 부모 노드를 반환합니다. 부모 노드가 없으면 프로그램이 종료됩니다!

이 단계는 A의 왼쪽 하위 트리를 순회합니다. 먼저 A 노드를 얻고 A에 왼쪽 하위 트리가 있는지 찾은 다음 A의 왼쪽 하위 트리 노드를 아래로 순회합니다. 이때 통과한 노드는 A이고 요소는 1이다.


두 번째 단계 는 B 노드에 와서 B 노드를 얻는 것입니다. 노드 B에 왼쪽 하위 트리가 있는지 확인합니다. 그렇다면 다음 왼쪽 하위 트리로 이동합니다. 오른쪽 하위 트리가 없으면 오른쪽 하위 트리를 순회하고, 오른쪽 하위 트리가 없으면 부모 노드를 반환합니다. 부모 노드가 없으면 프로그램이 종료됩니다!

이 단계는 B의 왼쪽 하위 트리를 순회하고 B에 왼쪽 하위 트리가 있는 것을 발견하면 B의 왼쪽 하위 트리 노드를 아래로 순회합니다. 이때 통과한 노드는 AB이고 요소는 12입니다.

 


세 번째 단계 는 D 노드에 와서 D 노드를 얻는 것입니다. 그런 다음 D 노드에 왼쪽 하위 트리가 있는지 판단하고 다음 노드로 이동합니다. 오른쪽 하위 트리가 없으면 오른쪽 하위 트리를 순회하고, 오른쪽 하위 트리가 없으면 부모 노드를 반환합니다.

이때 D는 왼쪽 하위 트리가 없는 것을 확인하고, D의 오른쪽 하위 트리를 순회하면 오른쪽 하위 트리가 없음을 알게 되므로 노드 B로 돌아가서 노드 B의 오른쪽 하위 트리까지 순회한다. 이때 통과하는 노드는 ABD이고 요소는 124입니다.


네 번째 단계 는 E 노드에 와서 E 노드를 얻는 것입니다. E에 왼쪽 하위 트리가 있는지 확인합니다. 그렇다면 다음 노드로 이동합니다. 오른쪽 하위 트리가 없으면 오른쪽 하위 트리를 순회하고, 오른쪽 하위 트리가 없으면 부모 노드를 반환합니다.

이때, E 노드에 좌우 서브트리가 없는 것으로 확인되면 B 노드로 돌아가고, B 노드는 A 노드로 돌아가고, A 노드는 다시 C 노드로 순회한다. , 순회 노드는 ABDE이고 요소는 1245입니다.


다섯 번째 단계 는 C 노드에 와서 C 노드를 얻는 것입니다. C에 왼쪽 하위 트리가 있는지 확인합니다. 그렇다면 다음 노드로 이동합니다. 오른쪽 하위 트리가 없으면 오른쪽 하위 트리를 순회하고, 오른쪽 하위 트리가 없으면 부모 노드를 반환합니다.

이때, C 노드는 왼쪽 서브트리가 없는 것을 확인하고, C 노드의 오른쪽 서브트리 F 노드에 접근하여 F 노드의 루트 노드를 획득한다. F의 왼쪽 하위 트리로 이동하면 이때 얻은 노드는 ABDEC이고 요소는 12453입니다.


마지막 단계 는 F 노드에 와서 F 노드를 얻는 것입니다. F 노드는 좌우 부트리가 없고, F 노드의 부모 노드 C 노드가 반환되고, C 노드는 C의 부모 노드 A 노드로 반환된다. 마지막으로 A에 부모 노드가 없음을 확인하고 프로그램이 종료됩니다. 이때 얻은 노드는 ABDECF이고 요소는 124536이다.


위는 선주문 순회 단계에 대한 자세한 설명입니다. 코드 구현을 살펴보겠습니다. 

//MyBinaryTree.java文件下
public class MyBinaryTree {

    //静态内部类BinaryTree
    static class BinaryTree {
        public int val;
        public BinaryTree left;
        public BinaryTree right;

        public BinaryTree(int val) {
            this.val = val;
        }
    }

    //根节点
    public BinaryTree root;

    //创建一个二叉树
    public void initBinaryTree() {
        BinaryTree A = new BinaryTree(1);
        BinaryTree B = new BinaryTree(2);
        BinaryTree C = new BinaryTree(3);
        BinaryTree D = new BinaryTree(4);
        BinaryTree E = new BinaryTree(5);
        BinaryTree F = new BinaryTree(6);
        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        C.right = F;
        root = A;
    }

    //前序遍历二叉树
    public void preOrder(BinaryTree tree) {
        if( tree == null) {
            return;
        }
        //节点的元素
        System.out.print(tree.val+" ");
        //节点的左子树
        preOrder(tree.left);
        //节点的右子树
        preOrder(tree.right);
    }
}

//Test.java文件下
public class Test {
    public static void main(String[] args) {
        MyBinaryTree myBinaryTree = new MyBinaryTree();
        myBinaryTree.initBinaryTree();
        myBinaryTree.preOrder(myBinaryTree.root);
    }
}

실행 후 출력:  

실행할 수 있는 결과는 위 연습의 최종 결과와 일치합니다. 프로그램을 통해서 보면 이진 트리의 순회가 재귀적인 생각이고 그 종료 조건이 노드 자체가 비어있지 않다는 것을 어렵지 않게 알 수 있다. 또한 신중한 친구는 헤드 노드가 가장 먼저 순회되기 때문에 전위 순회에 의해 얻은 첫 번째 결과가 이 이진 트리의 헤드 노드임을 알 수 있습니다. 


3. 중위 순회

순회 순서는 다음과 같습니다. 루트 노드의 왼쪽 노드 = "루트 노드 =" 루트 노드의 오른쪽 노드 . 따라서 현재 이진 트리의 순서 순회를 통해 얻은 루트 노드의 순서는 DBEACF이고 루트 노드 요소는 425136입니다.

첫 번째 단계는 A의 왼쪽 노드를 순회하는 것입니다. 노드 A가 A의 왼쪽 노드로 이동할 왼쪽 노드가 있으면 존재하지 않으면 노드 A를 가져오고 노드 A의 오른쪽 노드로 이동하고 오른쪽 노드도 비어 있으면 부모 노드로 돌아갑니다. 이 시점에서 노드 B가 통과되었습니다. 다음 각 노드도 이 단계에서 수행됩니다.


두 번째 단계는 B 노드로 이동하는 것입니다. 노드 B의 왼쪽 노드가 비어 있지 않은지 확인합니다. 노드 D로 이동하여 노드 D의 왼쪽 하위 트리가 비어 있다고 판단하고 노드 D를 획득하고 D의 오른쪽 하위 트리가 비어 있음을 방문하여 상위 노드 B로 돌아가서 노드 B의 루트 노드를 얻습니다. 이때 통과한 노드는 DB이고 요소는 42이다.


세 번째 단계는 E 노드로 이동하는 것입니다. E 노드의 왼쪽 하위 트리가 비어 있고 E 노드를 가져오고 오른쪽 하위 트리도 비어 있고 부모 노드 B를 반환하고 B 노드는 부모 노드 A를 반환하고 A 노드의 루트 노드를 얻습니다. 이때 통과한 노드는 DBEA이고 요소는 4251이다.


네 번째 단계는 C 노드로 이동하는 것입니다. C 노드의 왼쪽 하위 트리가 비어 있으면 C 노드를 획득하고 C 노드의 오른쪽 하위 트리가 비어 있지 않은지 판단합니다. 노드 F까지 순회하는데 이때 순회한 노드는 DBEAC이고 요소는 42513이다.


다섯 번째 단계 는 F 노드로 이동하는 것입니다. F 노드의 왼쪽 하위 트리가 비어 있고, F 노드를 가져오고, F 노드의 오른쪽 하위 트리도 비어 있고, 부모 노드 C를 반환하고, C 노드는 부모 노드 A를 반환하고, A 노드에는 부모 노드가 없으며 프로그램이 종료됩니다. 이때 순회하는 노드는 DBEACF이고 요소는 425136입니다. 프로그램이 종료됩니다.


in-order traversal의 경우 위 코드의 preOrder 메서드에서 액세스 노드의 루트 노드 위치를 약간만 변경하면 되며 나머지 코드는 변경되지 않은 상태로 유지됩니다. 

    
//中序遍历二叉树
public void inOrder(BinaryTree tree) {
        if( tree == null) {
            return;
        }
        //节点的左子树
        preOrder(tree.left);
        //节点的元素
        System.out.print(tree.val+" ");
        //节点的右子树
        preOrder(tree.right);
    }

 실행 후 출력 :

위의 결과를 통해 출력 결과가 위에 표시된 결과와 일치함을 알 수 있습니다. 조심스러운 친구는 순서대로 탐색할 때 헤드 노드의 왼쪽이 왼쪽 하위 트리이고 헤드 노드의 오른쪽이 오른쪽 하위 트리임을 알 수 있습니다. 위의 코드에서 1의 왼쪽은 425이고 1의 오른쪽은 36입니다. 이는 이진 트리와 정확히 일치합니다. 따라서 이진 트리의 헤드 노드가 누구인지 알면 순회를 통해 이진 트리의 왼쪽 트리와 오른쪽 트리를 추론할 수 있습니다. 


4. 사후 순회

후위 순회 단계는 다음과 같습니다. 루트 노드의 왼쪽 노드 = "루트 노드의 오른쪽 노드 =" 루트 노드 . 이 기사의 예제 이진 트리에서 순회 노드의 해당 순서는 DEBFCA, 노드 요소는 452631입니다.

위에서 pre-order traversal과 post-order traversal의 순서도와 구현 단계를 보여드렸는데요, 사실 post-order traversal도 왼쪽 노드, 오른쪽 노드, 그리고 루트 노드.여기서 블로거는 더 이상 설명하지 않고 누구나 스스로 그림을 그릴 수 있습니다.

이진 트리의 사후 순회 코드의 경우 preOrder 메서드에서 루트 노드의 위치를 ​​교환할 수도 있습니다.

//后序遍历二叉树    
public void postOrder(BinaryTree tree) {
        if( tree == null) {
            return;
        }
        //节点的左子树
        preOrder(tree.left);
        //节点的右子树
        preOrder(tree.right);
        //节点的元素
        System.out.print(tree.val+" ");
    }

실행 후 출력:

결과를 실행하면 위 순회에서 얻은 결과가 일치함을 알 수 있습니다. 관찰을 통해서도 알 수 있습니다. 이진 트리의 후위 순회를 알면 후위 순회의 마지막 데이터가 헤드 노드이기 때문에 헤드 노드를 얻을 수 있습니다.


이진 트리의 사전 순회 또는 후속 순회 결과와 순차 순회 결과를 알면 이진 트리의 전체 그림을 쉽게 추론할 수 있습니다.

예를 들어 이진 트리의 사전 순회 결과는 ABDECF이고 순회 결과는 DBEACF입니다. 그러면 이 이진 트리의 헤드 노드는 A, 왼쪽 하위 트리는 DBE, 오른쪽 하위 트리는 CF입니다. 따라서 이 이진 트리의 전체 그림은 다음과 같다고 추론할 수 있습니다.

물론 이진 트리의 in-order traversal과 post-order traversal을 알면 이 이진 트리도 쉽게 추론할 수 있지만 pre-order traversal과 post-order traversal을 알면 이 이진 트리를 추론할 수 없습니다. 우리는 왼쪽을 얻을 수 없는 방법, 오른쪽의 하위 트리는 무엇입니까?


이 블로그는 여기에 있습니다. 누구나 이해하지 못하는 것을 이해하기 위해 그림을 그리거나 블로거에게 개인 메시지를 보내거나 댓글을 남길 수 있습니다. 읽어 주셔서 감사합니다. 다음에 뵙겠습니다!

추천

출처blog.csdn.net/weixin_64916311/article/details/130157918