[Series Leetcode] [] [medio] algoritmo de secuencia de recorrido de árbol binario (recursión, pila, Morris Morris)

directorio

 

tema:

Ideas de resolución de problemas:

Método a: recursión (tiempo O (N), el espacio de O (N))

Método dos: Pila (tiempo O (N), el espacio de O (N))

Método tres: Morris transversal (tiempo O (N), el espacio O (1))

Ideas de resolución de problemas:

Método uno: recursiva

Segundo método: Pila

Método tres: Morris


tema:

enlaces a los temas:  https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

 

Ideas de resolución de problemas:

Método a: recursión (tiempo O (N), el espacio de O (N))

Cada recursividad, si el subárbol izquierdo, y luego continuar a utilizar el subárbol izquierdo de forma recursiva

Si no hay un subárbol izquierdo, se añadirá el valor actual para el conjunto de resultados, vuelve al nivel de recursividad

En una recursión capa, se añade el primer valor actual para el conjunto de resultados, determina si continuar el subárbol derecho

Si un subárbol derecho, el subárbol derecho de forma recursiva continuar, si no subárbol derecho, el retorno a la recursividad anterior continúa, esta lógica se repite

 

Método dos: Pila (tiempo O (N), el espacio de O (N))

En primer lugar empuje el nodo raíz, de desplazamiento

Siempre y cuando la pila no está vacía, a obtener los elementos de la pila de la pila, y determinar si el subárbol izquierdo

Si tiene subárbol izquierdo de la pila subárbol izquierdo, y luego continuar a recorrer; llegar al siguiente desplazamiento de la parte superior de la pila, el recorrido orientado a pila subárbol izquierdo

Si todavía no hay subárbol izquierdo, se añade el valor actual para el conjunto de resultados, y la parte superior de la pila subárbol de la pila

Continuar recibiendo subárbol de la pila, la pila y el subárbol pila, se añade al valor conjunto de resultados, y luego determina si el subárbol derecho

Si usted tiene el subárbol derecho, entonces el subárbol derecho emergente, seguir un ciclo; si no hay un subárbol derecho, pequeños ciclos continúan recibiendo el elemento superior

Se ilustra de la siguiente manera:

La pila nodo raíz

La pila subárbol izquierdo 1 de 2

La pila subárbol izquierdo 2 de 4

Puesto que no hay subárbol izquierdo 4, la pila 4, y 4 se añade al conjunto de resultados en res

4 porque no hay subárbol derecho, por lo que seguirá apilar el elemento superior 2, y se añadió al conjunto de resultados en res

Debido a que hay 2 subárbol derecho, por lo que nosotros no seguimos recibiendo los elementos de la parte superior de la pila, y la pila subárbol derecho 2 de 5

4 y 5 el mismo que el caso de la pila 5, se añade al conjunto de resultados

Desde la parte superior de la pila de una pila, se añade al conjunto de resultados

Debido a que 1 tienen el subárbol derecho, el subárbol derecho empujará 1 3

3 porque no hay subárbol izquierdo, la pila será el elemento superior 3, se añade al conjunto de resultados

El subárbol derecho de la pila 3

La pila 6, se añade al conjunto de resultados

No hay elementos en la pila, detener la caminata, los resultados de retorno

 

Método tres: Morris transversal (tiempo O (N), el espacio O (1))

La lógica es como sigue:

Variables:

  1. root: raíz del árbol
  2. curr: Los nodos atravesados ​​actuales, inicializadas a raíz
  3. prev: nodo secundario, inicializado para vaciar

proceso:

  1. Si curr subárbol izquierdo está vacío, se añade el valor curr al conjunto de resultados, y curr atravesar subárbol derecho
  2. Si curr subárbol izquierdo no está vacío, la operación se lleva a cabo bajo la nota:
    1. Anterior empezará a atravesar el subárbol derecho curr subárbol izquierdo, hasta que no haya subárbol derecho, o transversal al nodo curr
    2. Si prev subárbol derecho está vacío, entonces el subárbol derecho apuntando curr prev
    3. Si prev subárbol derecho no está vacío, entonces curr.val añaden al conjunto de resultados, actualizar curr = subárbol derecho curr.right, prev = Ninguno, siguen travesía

icono:

Supongamos que la estructura original de un árbol de la siguiente manera:

El negro es siempre nodo nodo raíz original, esta vez apuntando a la curr nodo raíz, nodo curr en el subárbol izquierdo es 2, no está vacío, entonces los puntos prev 2, a partir del subárbol derecho 2 de 5 recorrido:

Cuando la búsqueda a 8, porque no hay subárbol derecho 8, la búsqueda se detiene, cuando tres nodos de la siguiente manera (curr, raíz en posición 1):

En este momento, el subárbol derecho apuntando Curr prev, actualización curr = curr.left, posiciones de nodo y está conectado en este momento son los siguientes (línea continua representa la estructura de árbol original, la línea discontinua es conexión recién añadido):

Continuar el ciclo, esta vez prev = 2 subárbol izquierdo no está vacío, siguen apuntando a curr prev subárbol izquierdo, iniciar la búsqueda:

4 subárbol derecho, por lo que salir de la búsqueda, continuará puntos prev subárbol derecho a curr, actualizar curr = curr.left, ubicaciones de los nodos y enlaces en este momento es la siguiente (prev puntos después de 4 porque no hay recorrido subárbol derecho, por lo que este prev tiempo y curr en el mismo lugar):

Para recorrer este caso, Curr encontró ningún subárbol izquierdo, por lo que el resultado se suma al valor de res Curr fijados por la línea quebrada, la actualización de curr = curr.right, comienza el siguiente ciclo. En este momento curr = 2, por lo prev = curr.left subárbol izquierdo 2 continúa de 4 a iniciar la búsqueda, el nodo derecho 4 es 2, de acuerdo con las condiciones curr = prev, la búsqueda se detiene, esta vez de la siguiente manera:

Cuando se detiene la búsqueda, prev = 4 subárbol derecho no está vacío, por lo que en este caso 2 se agregará al conjunto de resultados, actualizar curr = curr.right, añadir más de conexión eliminado antes de que la actualización prev.right = Ninguno, continuar bucle:

Después de la lógica anterior, el proceso ilustrado es como sigue:

 

Ideas de resolución de problemas:

Método uno: recursiva

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        def order_help(node, res):
            if node and node.left:
                order_help(node.left, res)
                
            if node:
                res.append(node.val)
            
            if node and node.right:
                order_help(node.right, res)
                
        res = []
        order_help(root, res)
        return res

 

Segundo método: Pila

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        
        node_stack = [root]
        res = []
        while 0 < len(node_stack):
            if node_stack[-1].left:
                node_stack.append(node_stack[-1].left)
                continue
                
            while 0 < len(node_stack):
                last_node = node_stack[-1]
                node_stack.pop()
                res.append(last_node.val)
                if last_node.right:
                    node_stack.append(last_node.right)
                    break

        return res

 

Método tres: Morris

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        curr = root
        prev = None
        res = []
        while curr:
            if not curr.left:
                res.append(curr.val)
                curr = curr.right
            else:
                prev = curr.left
                while prev.right and prev.right != curr:
                    prev = prev.right
                    
                if not prev.right:
                    prev.right = curr
                    curr = curr.left
                else:
                    res.append(curr.val)
                    prev.right = None
                    curr = curr.right
        
        return res
                

 

Publicados 100 artículos originales · ganado elogios 4 · Vistas 1465

Supongo que te gusta

Origin blog.csdn.net/songyuwen0808/article/details/105373627
Recomendado
Clasificación