[Estructura de datos y algoritmo] Recorrido de árbol binario fácil de entender

En la explicación fácil de entender de los árboles de búsqueda binarios (por favor, hágame un toque), el artículo presenta principalmente la naturaleza de los árboles de búsqueda binarios. Este artículo continuará presentando el recorrido de los árboles binarios.

Recorrido del árbol de búsqueda binaria

Atravesar todos los nodos del árbol es visitar solo una vez. Según la posición del nodo raíz, se divide principalmente en recorrido de preorden, recorrido de orden medio y recorrido de postorden. Tenga en cuenta que el recorrido del árbol de búsqueda binario y el árbol binario ordinario es exactamente el mismo, por lo que a continuación, no se distingue si es un árbol de búsqueda binario o un árbol binario.

Recorrido de reserva

La operación de recorrido de preorden de un árbol binario es la siguiente:

  • Visita el nodo raíz
  • Preorder atraviesa el subárbol izquierdo
  • Preorder atraviesa el subárbol derecho

Por ejemplo, en la siguiente figura, el orden de acceso al nodo de recorrido de preorden del árbol binario es 3 1 2 5 4 6:
[Estructura de datos y algoritmo] Recorrido de árbol binario fácil de entender
De acuerdo con los pasos de operación de recorrido de preorden analizados anteriormente, no es difícil ver que es fácil implementar el acceso de preorden del árbol binario por método recursivo:

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

De hecho, el recorrido de preorden del árbol binario también se puede implementar de una manera no recursiva: dado que el nodo raíz debe recuperarse después de atravesar el nodo raíz para atravesar el subárbol derecho correspondiente al nodo raíz, puede considerar usar la pila para almacenar los datos visitados. El nodo raíz de la implementación del código es el siguiente:

//前序遍历的非递归版本
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;  
}  

Recorrido en orden

La operación transversal de orden medio de un árbol binario es la siguiente:

  • Recorrido de orden medio del subárbol izquierdo
  • Visita el nodo raíz
  • Recorrido en orden del subárbol derecho

Por ejemplo, en la siguiente figura, el orden de acceso de los nodos en el recorrido del árbol binario es 1 2 3 4 5 6:
[Estructura de datos y algoritmo] Recorrido de árbol binario fácil de entender

Al igual que el recorrido de preorden, también se puede implementar de forma recursiva o no recursiva, y la idea es similar, excepto que el orden de acceso es diferente.Las dos implementaciones son las siguientes:

//中序遍历递归版本
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;  
}  

Travesía posterior

La operación transversal posterior al pedido de un árbol binario es la siguiente:

  • Recorrido posterior al orden del subárbol izquierdo
  • Recorrido posterior a la orden del subárbol derecho
  • Visita el nodo raíz

Por ejemplo, en la siguiente figura, el orden de acceso al nodo transversal posterior al pedido del árbol binario es 2 1 4 6 5 3: La
[Estructura de datos y algoritmo] Recorrido de árbol binario fácil de entender
versión recursiva del recorrido posterior al pedido del árbol binario es similar al orden intermedio del pedido previo, como sigue:

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

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

El algoritmo no recursivo de recorrido posterior al orden es más complicado y se puede implementar usando una pila, pero el proceso es muy engorroso. Podemos considerar el uso de dos pilas para implementar el algoritmo no recursivo del recorrido posterior al pedido. Tenga en cuenta que el recorrido posterior al orden se puede considerar como el proceso inverso del siguiente recorrido: es decir, primero atraviesa un cierto nodo, luego atraviesa su hijo derecho y luego atraviesa su hijo izquierdo. El reverso de este proceso es el recorrido posterior al pedido. Los pasos del algoritmo son los siguientes:

(1) Empuje el nodo raíz a la primera pila s.
(2) Extraiga un nodo de la pila y empújelo hacia la salida de la pila.
(3) Luego empuje el hijo izquierdo y el hijo derecho del nodo a la primera pila s.
(4) Repita los procedimientos 2 y 3 hasta que la pila esté vacía.
(5) Ahora todos los nodos se han enviado a la salida de la pila y se han almacenado en el orden de recorrido posterior al pedido, y la salida emergente directamente es el resultado del recorrido posterior al pedido del árbol binario.

El código se implementa de la siguiente manera:

//后序遍历的非递归版本
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;  
}  

Lectura recomendada:

[Bienestar] Uso compartido de videos de cursos boutique en línea recopilados por mí mismo (
Parte 1 ) [Diseño del sistema] Caché LRU
[Estructura de datos y algoritmo] Lista enlazada fácil de entender
[Estructura de datos y algoritmo] Clasificación de bits fácil de entender
[Notas de C ++] C ++ 11 Programación concurrente (1) Inicie el viaje del hilo
[Notas de C ++] Errores comunes en el uso de punteros de C / C ++
[Notas de C ++] Explicación detallada de bibliotecas estáticas y dinámicas (encendido)

Céntrese en compartir resumen de conocimientos de pila de tecnología de fondo del servidor

Bienvenido a prestar atención a la comunicación y al progreso común.

[Estructura de datos y algoritmo] Recorrido de árbol binario fácil de entender

Codificación

¡El productor de códigos tiene la manera correcta de proporcionarle artículos técnicos fáciles de entender para facilitar la tecnología!

Supongo que te gusta

Origin blog.51cto.com/15006953/2552022
Recomendado
Clasificación