Saltar al contenido principal

Análisis

Note que todas las operaciones del árbol tienen un costo proporcional a la operación splaysplay que las sigue. Por lo tanto, podemos concentrarnos en el costo de esta operación (si bien luego consideraremos la modificación que hacen en el árbol la inserción y el borrado).

Para analizar esta operación en forma amortizada definiremos una función potencial. Sea Si(x)S_i(x) el subárbol con raíz xx luego de la operación ii, y sea si(x)=Si(x)s_i(x) = |S_i(x)| su número de nodos. Finalmente, sea ri(x)=log2si(x)r_i(x) = \log_2 s_i(x) el rango de xx luego de la operación ii. La función potencial del árbol TT, visto como un conjunto de nodos, es entonces

ϕi  =  xTri(x).\phi_i ~~=~~ \sum_{x \in T} r_i(x).

Analicemos cómo cambia Δϕi\Delta\phi_i luego de realizar las rotaciones.

Zig-zig y zag-zag

Los únicos nodos cuyos rangos se modifican son los de xx, yy, y zz. Por lo tanto,

Δϕi  =  (ri(x)ri1(x))+(ri(y)ri1(y))+(ri(z)ri1(z)).\Delta\phi_i ~~=~~ (r_i(x)-r_{i-1}(x)) + (r_i(y)-r_{i-1}(y)) + (r_i(z)-r_{i-1}(z)).

Note también los siguientes hechos simples: (1) ri(x)=ri1(z)r_i(x) = r_{i-1}(z); (2) ri1(y)ri1(x)r_{i-1}(y) \ge r_{i-1}(x); (3) ri(y)ri(x)r_i(y) \le r_i(x). El costo real de hacer un zig-zig es ci=2c_i=2, mientras que el costo amortizado es

ci^  =  ci+Δϕi=2+(ri(x)ri1(x))+(ri(y)ri1(y))+(ri(z)ri1(z))=2+[ri(x)ri1(z)]+ri(y)+ri(z)ri1(x)ri1(y)2+ri(x)+ri(z)ri1(x)ri1(x)=2+ri(x)+ri(z)2ri1(x),\begin{array}{c c c} \hat{c_i} ~~=~~ c_i + \Delta\phi_i &=& 2 + (r_i(x)-r_{i-1}(x)) + (r_i(y)-r_{i-1}(y)) + (r_i(z)-r_{i-1}(z))\\ & = & 2 + [r_i(x)-r_{i-1}(z)] + r_i(y) + r_i(z) - r_{i-1}(x) - r_{i-1}(y)\\ & \le & 2 + r_i(x) + r_i(z) - r_{i-1}(x) - r_{i-1}(x) \\ & = & 2 + r_i(x) + r_i(z) - 2 r_{i-1}(x), \end{array}

donde en la desigualdad usamos los tres hechos simples mencionados.

Vamos a usar la siguiente propiedad, que se deduce de la concavidad del logaritmo, pero igual mostramos su deducción:

0(ab)2,2aba2+b2,4ab(a+b)2,log2(4ab)log2((a+b)2),log2(ab)2log2(a+b)2,log2a+log2b2log2(a+b)2.\begin{array}{c c c} 0 & \le & (a-b)^2, \\ 2ab & \le & a^2 + b^2, \\ 4ab & \le & (a+b)^2, \\ \log_2(4ab) & \le & \log_2((a+b)^2), \\ \log_2(ab) & \le & 2\log_2(a+b)-2, \\ \log_2 a + \log_2 b & \le & 2\log_2(a+b)-2. \\ \end{array}

Usaremos esta propiedad y el hecho simple de que si1(x)+si(z)si(x)s_{i-1}(x)+s_i(z) \le s_i(x) para obtener lo siguiente:

ri1(x)+ri(z)=log2si1(x)+log2si(z)    2log2(si1(x)+si(z))22log2si(x)2  =  2ri(x)2.\begin{array}{c c c} r_{i-1}(x) + r_i(z) &=& \log_2 s_{i-1}(x) + \log_2 s_i(z) ~~\le~~ 2\log_2 (s_{i-1}(x)+s_i(z))-2 \\ &\le & 2\log_2 s_i(x) - 2 ~~=~~ 2 r_i(x)-2. \end{array}

Por lo tanto, podemos reemplazar ri(z)r_i(z) por 2ri(x)ri1(x)22r_i(x)-r_{i-1}(x)-2 en nuestra ecuación de ci^\hat{c_i} para obtener

ci^    3(ri(x)ri1(x)).\hat{c_i} ~~\le~~ 3(r_i(x)-r_{i-1}(x)).

Zig-zag y zag-zig

Partimos de la misma forma que antes y luego acotamos:

ci^  =  ci+Δϕi=2+(ri(x)ri1(x))+(ri(y)ri1(y))+(ri(z)ri1(z))=2+[ri(x)ri1(z)]+ri(y)+ri(z)ri1(x)ri1(y)2+ri(y)+ri(z)2ri1(x),\begin{array}{c c c} \hat{c_i} ~~=~~ c_i + \Delta\phi_i &=& 2 + (r_i(x)-r_{i-1}(x)) + (r_i(y)-r_{i-1}(y)) + (r_i(z)-r_{i-1}(z))\\ & = & 2 + [r_i(x)-r_{i-1}(z)] + r_i(y) + r_i(z) - r_{i-1}(x) - r_{i-1}(y)\\ & \le & 2 + r_i(y) + r_i(z) - 2r_{i-1}(x), \end{array}

donde en la desigualdad usamos que ri(x)=ri1(z)r_i(x)=r_{i-1}(z) y que ri1(y)ri1(x)r_{i-1}(y) \ge r_{i-1}(x). Ahora volvemos a usar que log2a+log2b2log2(a+b)2\log_2 a + \log_2 b \le 2\log_2(a+b)-2 y que si(y)+si(z)si(x)s_i(y) + s_i(z) \le s_i(x) para acotar

ri(y)+ri(z)=log2si(y)+log2si(z)    2log2(si(y)+si(z))22log2si(x)2  =  2ri(x)2.\begin{array}{c c c} r_i(y) + r_i(z) & = & \log_2 s_i(y) + \log_2 s_i(z) ~~\le~~ 2\log_2 (s_i(y)+s_i(z))-2 \\ & \le & 2\log_2 s_i(x) - 2 ~~=~~ 2r_i(x) - 2. \end{array}

Sustituyendo en la fórmula de ci^\hat{c_i} tenemos entonces

ci^    2(ri(x)ri1(x))    3(ri(x)ri1(x))\hat{c_i} ~~\le~~ 2(r_i(x)-r_{i-1}(x)) ~~\le~~ 3(r_i(x)-r_{i-1}(x))

Zig y zag

En estas operaciones tenemos ci=1c_i=1. Como ri(y)ri1(y)r_i(y) \le r_{i-1}(y) y ri(x)ri1(x)r_i(x) \ge r_{i-1}(x),

ci^=ci+(ri(x)ri1(x))+(ri(y)ri1(y))1+ri(x)ri1(x)1+3(ri(x)ri1(x)).\begin{array}{c c c} \hat{c_i} &=& c_i + (r_i(x)-r_{i-1}(x)) + (r_i(y)-r_{i-1}(y)) \\ & \le & 1 + r_i(x) - r_{i-1}(x) \\ & \le & 1 + 3(r_i(x) - r_{i-1}(x)). \end{array}

Splay

Una operación splaysplay se compone de una secuencia de mm rotaciones dobles consecutivas, posiblemente terminadas por una simple, todas aplicadas sobre el mismo nodo xx. Su costo amortizado es entonces

c^    1+i=1m3(ri(x)ri1(x))  =  1+3(rm(x)r0(x))    1+3log2n\hat{c} ~~\le~~ 1 + \sum_{i=1}^m 3(r_i(x)-r_{i-1}(x)) ~~=~~ 1+3(r_m(x)-r_0(x)) ~~\le~~ 1+3\log_2 n

donde la última desigualdad se obtiene notando que rm(x)=log2nr_m(x)=\log_2 n porque xx termina siendo la raíz, y despreciando r0(x)0r_0(x) \ge 0.

Operaciones del árbol

La cota de splay implica directamente una cota amortizada de O(logn)O(\log n) para las operaciones de búsqueda exitosa sobre un splay tree. Lo mismo ocurre con la búsqueda infructuosa, la inserción y el borrado, ya que hemos hecho que su costo sea proporcional a la operación de splay correspondiente. La única consideración final que necesitamos es que la inserción, al agregar un elemento xx, puede incrementar el potencial ϕ\phi, lo cual debe ser absorbido por el costo amortizado de la inserción. La diferencia de potencial que produce la inserción de una hoja xx, siendo y1,,ymy_1,\ldots,y_m los nodos de su camino hacia la raíz y s(yj)s(y_j) sus tamaños, son

Δϕ=j=1m(log2(s(yj)+1)log2s(yj))(log2(s(ym)+1)log2s(ym))+j=1m1(log2s(yj+1)log2s(yj))=log2(s(ym)+1)log2s(ym)+log2s(ym)log2s(y1)log2(n+1)1log2n,\begin{array}{c c c} \Delta\phi & = & \sum_{j=1}^m (\log_2 (s(y_j)+1) - \log_2 s(y_j)) \\ & \le & (\log_2(s(y_m)+1) - \log_2 s(y_m)) + \sum_{j=1}^{m-1} (\log_2 s(y_{j+1}) - \log_2 s(y_j)) \\ & = & \log_2(s(y_m)+1) - \log_2 s(y_m) + \log_2 s(y_m) - \log_2 s(y_1) \\ & \le & \log_2 (n+1) - 1 \\ & \le & \log_2 n, \end{array}

donde usamos que, como yj+1y_{j+1} es el padre de yjy_j, debe valer s(yj+1)s(yj)+1s(y_{j+1}) \ge s(y_j)+1. El incremento de potencial de la inserción es también O(logn)O(\log n), lo que completa el análisis.