[데이터 구조 및 알고리즘] 이해하기 쉬운 이진 트리 순회

이진 검색 트리에 대한 이해하기 쉬운 설명 (날 찔러주세요)에서이 기사는 주로 이진 검색 트리의 특성을 소개하고 있으며,이 기사에서는 계속해서 이진 트리 탐색에 대해 소개합니다.

이진 검색 트리 탐색

트리의 모든 노드를 순회하는 것은 한 번만 방문하는 것입니다. 루트 노드의 위치에 따라 주로 선주문 순회, 중순 순회, 후 주문 순회로 나뉩니다. 이진 검색 트리와 일반 이진 트리의 순회는 정확히 동일하므로 다음에서 이진 검색 트리인지 이진 트리인지 구별되지 않습니다.

선주문 순회

이진 트리의 사전 주문 순회 작업은 다음과 같습니다.

  • 루트 노드로 이동
  • 왼쪽 하위 트리를 가로 지르는 선주문
  • 사전 주문은 오른쪽 하위 트리를 통과합니다.

예를 들어, 다음 그림에서 이진 트리의 선주문 순회 노드 접근 순서는 3 1 2 5 4 6 :
[데이터 구조 및 알고리즘] 이해하기 쉬운 이진 트리 순회
위에서 분석 한 선주문 순회 동작 단계에 따르면 재귀 적 방법으로 이진 트리의 선주문 접근을 구현하는 것이 용이하다는 것을 알기 어렵지 않습니다.

//前序遍历递归版本
void preOrder(struct node *root)
{
    if(root != NULL)
    {
        cout << root->data << " ";
        preOrder(root->left);
        preOrder(root->right);
    }
}

사실, 바이너리 트리의 사전 주문 순회는 비 재귀적인 방식으로도 구현 될 수 있습니다. 루트 노드에 해당하는 오른쪽 하위 트리를 순회하기 위해 루트 노드를 순회 한 후 루트 노드를 검색해야하므로 방문한 정보를 저장하는 데 스택을 사용할 수 있습니다. 코드 구현의 루트 노드는 다음과 같습니다.

//前序遍历的非递归版本
void preOrder(struct node *root)  
{  
    stack<struct node *> s;  
    while (root != NULL || !s.empty()) 
    {  
        if (root != NULL) 
        {  
        //访问结点并入栈
            cout << root->data << " ";   
            s.push(root);                
            root = root->left; //访问左子树  
       } 
       else 
       {  
            root = s.top();  //回溯至父亲结点  
            s.pop();  
            root = root->right; //访问右子树  
       }  
    }  
    cout << endl;  
}  

순회 순회

이진 트리의 중간 순서 순회 작업은 다음과 같습니다.

  • 왼쪽 하위 트리의 중간 순서 순회
  • 루트 노드로 이동
  • 오른쪽 하위 트리의 순서대로 순회

예를 들어 다음 그림에서 이진 트리 순회에서 노드의 액세스 순서는 1 2 3 4 5 6입니다.
[데이터 구조 및 알고리즘] 이해하기 쉬운 이진 트리 순회

사전 주문 순회와 마찬가지로 재귀 적 또는 비재 귀적 방식으로 구현할 수도 있으며 액세스 순서가 다르다는 점을 제외하면 아이디어가 비슷합니다. 두 가지 구현은 다음과 같습니다.

//中序遍历递归版本
void inOrder(struct node *root)
{
    if(root != NULL)
    {
        inOrder(root->left);
    //和前序遍历相比,只是输出语句换了个位置唯一
    cout << root->data << " ";
        inOrder(root->right);
    }
}
//中序遍历的非递归版本
void inOrder(struct node *root)  
{  
    stack<struct node *> s;  
    while (root != NULL || !s.empty()) 
    {  
        if (root != NULL) 
        {  
            s.push(root);  
            root = root->left;  
        }  
        else 
        {  
        //访问完左子树后才访问根结点  
            root = s.top();  
            cout << root->data << " ";  
            s.pop();  
            root = root->right; //访问右子树  
        }  
    }  
    cout << endl;  
}  

후속 순회

이진 트리의 사후 순회 작업은 다음과 같습니다.

  • 왼쪽 하위 트리의 주문 후 순회
  • 오른쪽 하위 트리의 주문 후 순회
  • 루트 노드로 이동

예를 들어 다음 그림에서 이진 트리의 사후 순회 노드 액세스 순서는 2 1 4 6 5 3 :
[데이터 구조 및 알고리즘] 이해하기 쉬운 이진 트리 순회
이진 트리의 사후 순회의 재귀 버전은 다음과 같이 사전 주문 중간 주문과 유사합니다.

//后序遍历递归版本
void postOrder(struct node *root)
{
    if(root != NULL)
    {
        postOrder(root->left);
        postOrder(root->right);

        //最后访问根节点
        cout << root->data << " ";
    }
}

포스트 오더 순회의 비 재귀 알고리즘은 더 복잡하고 하나의 스택으로 구현할 수 있지만 프로세스가 매우 번거롭기 때문에 포스트 오더 순회의 비 재귀 알고리즘을 구현하기 위해 두 개의 스택을 사용하는 것을 고려할 수 있습니다. 주문 후 순회는 다음 순회의 역 프로세스로 간주 될 수 있습니다. 즉, 먼저 특정 노드를 순회 한 다음 오른쪽 자식을 순회 한 다음 왼쪽 자식을 순회합니다. 이 프로세스의 반대는 주문 후 순회입니다. 알고리즘 단계는 다음과 같습니다.

(1) 루트 노드를 첫 번째 스택으로 푸시합니다.
(2) 스택에서 노드를 꺼내 스택 출력으로 푸시합니다.
(3) 그런 다음 노드의 왼쪽 자식과 오른쪽 자식을 첫 번째 스택으로 푸시합니다.
(4) 스택이 비워 질 때까지 절차 2와 3을 반복합니다.
(5) 이제 모든 노드가 스택 출력으로 푸시되고 사후 순회 순서로 저장되었으며 직접 팝업은 이진 트리의 사후 순회 결과입니다.

코드는 다음과 같이 구현됩니다.

//后序遍历的非递归版本
void postOrder(struct node *root)  
{  
    if (!root) return;  
    stack<struct node*> s, output;  
    s.push(root);  
    while (!s.empty()) 
    {  
        struct node *curr = s.top();  
        output.push(curr);  
        s.pop();  
        if (curr->left)  
            s.push(curr->left);  
        if (curr->right)  
            s.push(curr->right);  
    }  

    while (!output.empty()) 
    {  
        cout << output.top()->data << " ";  
        output.pop();  
    }  
    cout << endl;  
}  

추천 자료 :

[복지] 직접 수집 한 온라인 부티크 강좌 영상 공유 (
Part 1 ) [시스템 설계] LRU 캐시
[데이터 구조 및 알고리즘] 이해하기 쉬운 링크 목록
[데이터 구조 및 알고리즘] 이해하기 쉬운 비트 정렬
[C ++ Notes] C ++ 11 동시 프로그래밍 (1) 스레드 여정 시작
[C ++ 노트] C / C ++ 포인터 사용시 일반적인 함정
[C ++ 노트] 정적 및 동적 라이브러리에 대한 자세한 설명 (on)

서버 배경 기술 스택 지식 요약 공유에 집중

의사 소통 및 공동 진행에 관심을 기울이는 것을 환영합니다.

[데이터 구조 및 알고리즘] 이해하기 쉬운 이진 트리 순회

코딩

코드 농부는 이해하기 쉬운 기술 문서를 제공하여 기술을 더 쉽게 만들 수있는 올바른 방법을 가지고 있습니다!

추천

출처blog.51cto.com/15006953/2552022