Concatenar/Fusionar / Unir dos árboles AVL


Supongamos que tengo dos árboles AVL y que cada elemento del primer árbol es más pequeño que cualquier elemento del segundo árbol. ¿Cuál es la forma más eficiente de concatenar en un solo árbol AVL? He buscado por todas partes pero no he encontrado nada útil.

Author: liviucmg, 2010-01-10

4 answers

Suponiendo que puede destruir los árboles de entrada:

  1. elimine el elemento más a la derecha del árbol izquierdo, y utilícelo para construir un nuevo nodo raíz, cuyo hijo izquierdo es el árbol izquierdo, y cuyo hijo derecho es el árbol derecho: O (log n)
  2. determine y establezca el factor de equilibrio de ese nodo: O(log n). En la violación (temporal) del invariante, el factor de equilibrio puede estar fuera del rango {-1, 0, 1}
  3. gire para obtener el factor de equilibrio de nuevo en el rango: O (log n) rotaciones: O (log n)

Por lo tanto, toda la operación se puede realizar en O(log n).

Editar: Pensándolo bien, es más fácil razonar sobre las rotaciones en el siguiente algoritmo. También es muy probable que sea más rápido:

  1. Determinar la altura de ambos árboles: O(log n).
    Suponiendo que el árbol derecho es más alto (el otro caso es simétrico):
  2. elimine el elemento más a la derecha del árbol left (girando y ajustando su altura calculada si es necesario). Sea n que elemento. O (log n)
  3. En el árbol derecho, navegue a la izquierda hasta llegar a un nodo cuyo subárbol sea como máximo un 1 más alto que left. Sea r ese nodo. O (log n)
  4. Reemplace ese nodo con un nuevo nodo con el valor n, y subárboles left y r. O (1)
    Por construcción, el nuevo nodo es AVL-balanceado, y su subárbol 1 más alto que r.

  5. Incremente el saldo de su padre en consecuencia. O(1)

  6. y reequilibrar como lo haría después de insertar. O (log n)
 29
Author: meriton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-06 21:03:55

Una solución ultra simple (que funciona sin ninguna suposición en las relaciones entre los árboles) es esta:

  1. Haga un tipo de fusión de ambos árboles en una matriz combinada (itere simultáneamente ambos árboles).
  2. Construye un árbol AVL desde el array - toma el elemento central como la raíz, y aplica recursivamente a las mitades izquierda y derecha.

Ambos pasos son O(n). El problema principal con él es que toma O (n) espacio adicional.

 6
Author: ripper234,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-18 08:08:43

La mejor solución que he leído para este problema se puede encontrar aquí. Está muy cerca de la respuesta de meriton si corrige este problema:

En el tercer paso del algoritmo navega a la izquierda hasta llegar al nodo cuyo sub árbol tiene la misma altura que el árbol izquierdo. Esto no siempre es posible, (ver imagen de contraejemplo). La forma correcta de hacer este paso es encontrar dos para un subárbol con altura h o h+1 donde h es la altura de la izquierda arbol contraejemplo

 4
Author: agarwaen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-11 20:46:53

Sospecho que solo tendrás que caminar un árbol (con suerte el más pequeño) y agregar individualmente cada uno de sus elementos al otro árbol. Las operaciones de inserción/eliminación de AVL no están diseñadas para manejar la adición de un subárbol entero a la vez.

 1
Author: Dale Hagglund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-10 14:12:53