Está en la página 1de 27

ARBOL ROJO NEGRO

1) CONCEPTOS:
A. Un rbol rojo negro es un tipo abstracto de datos, concretamente es
un rbol binario de bsqueda equilibrado.
B. Un rbol binario de bsqueda auto- balanceable o equilibrado es
un rbol binario de bsqueda que intenta mantener su altura, o el
nmero de niveles de nodos bajo la raz, tan pequeos como sea
posible en todo momento.
C. Podemos recordar que: Los rboles AVL estn siempre equilibrados
de tal modo que para todos los nodos, la altura de la rama izquierda
no difiere en ms de una unidad de la altura de la rama derecha o
viceversa. Gracias a esta forma de equilibrio (o balanceo), la
complejidad de una bsqueda en uno de estos rboles se mantiene
siempre en orden de complejidad O(log n). esto permite que al
insertar o eliminar algn nodo, el rbol siga siendo balanceado o
equilibrado.
D. Un rbol binario de bsqueda es un rbol con una restriccin
adicional - que mantiene los elementos en el rbol en un orden
determinado. Oficialmente, cada nodo en el ABB tiene dos hijos (si
falta alguno consideramos que es un nodo cero) a la izquierda, un
nio y un nio de la derecha. Los nodos estn enraizados en el lugar
sobre la base de sus valores, con la ms pequea a la izquierda y el
ms grande de la derecha.
E. Un rbol rojo-negro es un rbol binario de bsqueda en el que cada
nodo almacena un bit adicional de informacin llamado color, el cual
puede ser rojo o negro. Sobre este atributo de color se aplican
restricciones que resultan en un rbol en el que ningn camino de la
raz a una hoja es ms de dos veces ms largo que cualquier otro, lo
cual significa que el rbol es balanceado.
F. Cada nodo de un rbol rojo negro contiene la siguiente informacin:
color, dato, hijo izquierdo, hijo derecho y padre. Si un hijo o el padre
de un nodo no existe, el apuntador correspondiente contiene el valor
NULO, el cual consideraremos como un nodo cuyo color es negro. En
lo sucesivo nos referiremos a los nodos distintos a las hojas (NULO)

1
como nodos internos del rbol y a las hojas y al padre de la raz como
nodos externos.
G. Es una representacin en rbol binario de un rbol 2-3-4.
H. rboles rojo-negro son una evolucin de los rboles binarios de
bsqueda que tienen como objetivo mantener el rbol balanceado sin
afectar a la complejidad de las operaciones primitivas. Esto se hace
mediante la coloracin de cada nodo en el rbol con rojo o negro y la
preservacin de un conjunto de propiedades que garantizan que el
ms profundo camino en el rbol no es ms largo que el doble de la
ms corta.

De su creacin podemos decir:

La estructura original fue creada por Rudolf Bayer en 1972, que le dio el
nombre de rboles-B binarios simtricos, pero tom su nombre moderno
en un trabajo de Leo J. Guibas y Robert Sedgewick realizado en 1978.

B) Terminologa:
El rbol rojo negro es un tipo especial de rbol binario, utilizado en
informtica para organizar informacin compuesta por datos comparables,
como son los nmeros.

C) Caractersticas y propiedades:
Todo nodo es o bien rojo o bien negro.
La raz es de color negra
Un nodo rojo puede tener solo hijos negros.
Todas las hojas son negras (las hojas son los hijos nulos).
Cada camino simple desde un nodo a un nodo hijo descendiente
contiene el mismo nmero de nodos negros, ya sea contando siempre
los nodos negros nulos o bien no contndolos nunca. Tambin es
llamada propiedad del camino y por tanto el camino no puede tener
dos rojos seguidos.

2
El camino largo desde la raz hasta una hoja no es ms largo que 2
veces el camino ms corto desde la raz del rbol hasta una hija en
dicho rbol. El resultado es que dicho rbol esta aproximadamente
equilibrado.

En muchas presentaciones de estructuras arbreas de datos, es posible


para un nodo tener solo un hijo y las hojas contienen informacin. Es
posible presentar los rboles rojo-negros en este paradigma, pero cambian
algunas de las propiedades y se complican los algoritmos. Se utiliza el
trmino hojas nulas, porque no contienen informacin y simplemente
sirven para indicar dnde el rbol acaba, como se mostr antes.
Habitualmente estos nodos son omitidos en las representaciones, lo cual no
lo hace ver como realmente se describe tericamente. Como consecuencia
de esto todos los nodos internos tienen dos hijos, aunque uno o ambos
nodos podran ser una hoja nula.

Otra explicacin que se da del rbol rojo-negro es la de tratarlo como


un rbol binario de bsqueda cuyas aristas, en lugar de nodos, son
coloreadas de color rojo o negro.

3
2) IMPORTANCIA DEL USO DE RBOLES ROJO NEGROS:

Los rboles rojo-negros ofrecen un peor caso con tiempo garantizado


para la insercin, el borrado y la bsqueda. No es esto nicamente lo
que los hace valiosos en aplicaciones sensibles al tiempo como las
aplicaciones en tiempo real, sino que adems son apreciados para la
construccin de bloques en otras estructuras de datos que garantizan
un peor caso. Por ejemplo, muchas estructuras de datos usadas en
geometra computacional pueden basarse en rboles rojo-negro.
Los rboles rojo-negro son particularmente valiosos en programacin
funcional, donde son una de las estructuras de datos persistentes
ms comnmente utilizadas en la construccin de arrays asociativos y
conjuntos que pueden retener versiones previas tras mutaciones. La
versin persistente del rbol rojo-negro requiere un espacio O(log n)
para cada insercin o borrado, adems del tiempo.
Los rboles rojo-negro son isomtricos a los rboles 2-3-4. En otras
palabras, para cada rbol 2-3-4, existe un rbol correspondiente rojo-
negro con los datos en el mismo orden. La insercin y el borrado en
rboles 2-3-4 son tambin equivalentes a los cambios de colores y las
rotaciones en los rboles rojo-negro. Esto los hace ser una
herramienta til para la comprensin del funcionamiento de los
rboles rojo-negro y por esto muchos textos introductorios sobre
algoritmos presentan los rboles 2-3-4 justo antes que los rboles
rojo-negro, aunque frecuentemente no sean utilizados en la prctica.

3. OPERACIONES
A. Rotacin.
B. Bsqueda (similar a los rboles binarios de bsqueda. Los colores de
los hijos no se usan)
C. Insercin (se utilizarn las transformaciones de los 4-nodos descritas
para los rboles 2-3-4)
D. Eliminacin

4
Las operaciones que veremos a continuacin son las que se aplican de una
forma particular a los arboles rojo negros; sin embargo las operaciones de
lectura (las ms simples), son las mismas que en los arboles binarios de
bsqueda y no tienen alteracin; ya que recordemos que los arboles rojo
negros son arboles ABB; por lo tanto no se tendrn en cuenta en este texto.

NOTA IMPORTANTE: Sin embargo, el resultado inmediato de una


insercin o la eliminacin de un nodo utilizando los algoritmos de un
rbol binario de bsqueda normal podra violar las propiedades de un
rbol rojo-negro. Restaurar las propiedades rojo-negro requiere un
pequeo nmero (O(log n))de cambios de color (que son muy rpidos
en la prctica) y no ms de 3 rotaciones (2 por insercin). A pesar de
que las operaciones de insercin y borrado son complicadas, sus
tiempos de ejecucin siguen siendo O(log n).

A) ROTACIN:
Para conservar las propiedades que debe cumplir todo rbol rojo-
negro, en ciertos casos de la insercin y la eliminacin ser necesario
reestructurar el rbol, si bien no debe perderse la ordenacin relativa
de los nodos. Para ello, se llevan a cabo una o varias rotaciones, que
no son ms que reestructuraciones en las relaciones padre-hijo-to-
nieto.
Las rotaciones que se consideran a continuacin son simples; sin
embargo, tambin se dan las rotaciones dobles.

5
En las imgenes pueden verse de forma simplificada cmo se llevan a
cabo las rotaciones simples hacia la izquierda y hacia la derecha en
cualquier rbol binario de bsqueda, en particular en cualquier rbol
rojo-negro. Podemos ver tambin la implementacin en C de dichas
operaciones.

Void rotar_izda(struct node *p)

struct node *aux;

aux = p;

p = p->dcho;

aux-> dcho = p->izdo;

p->izdo = aux;

//reenraizar subarbol

6
if(aux->padre->izdo == aux)

aux->padre->izdo = p;

else {

// Aqui aux->padre->dcho == aux

aux->padre->dcho = p;

// actualizar los padres de los nodos modificados

p->padre = aux->padre;

aux->padre = p;

aux->dcho->padre = aux; // No hacer si usamos una sola hoja


nula y aux->dcho es nulo

7
void
rotar_dcha(struct node *p)
{
struct node *aux;
aux = p;
p = p->izdo;
aux->izdo = p->dcho;
p->dcho = aux;
// reenraizar subarbol
if(aux->padre->izdo == aux)
aux->padre->izdo = p;
else {
// aqui aux->padre->dcho == aux
aux->padre->dcho = p;
}
// actualizar los padres de los nodos modificados
p->padre = aux->padre;
aux->padre = p;
aux->izdo->padre = aux; // No hacer si usamos una sola hoja nula y
aux->izdo es nulo
}

B) BSQUEDA
La bsqueda consiste acceder a la raz del rbol, si el elemento a
localizar coincide con ste la bsqueda ha concluido con xito, si
el elemento es menor se busca en el subrbol izquierdo y si es mayor
se buscar en el derecho. Si llegamos a un nodo hoja y el elemento
no ha sido encontrado se supone que no existe en el rbol. Cabe
destacar que la bsqueda en este tipo de rboles es muy
eficiente, representa una funcin logartmica.
NOTA PARA RECORDAR: La bsqueda de un elemento en
un ABB (rbol Binario de Bsqueda) en general, y en un rbol
rojo negro en particular, se puede realizar de dos formas,
iterativa o recursiva.
8
Ejemplo de versin iterativa en el lenguaje de programacin C,
suponiendo que estamos buscando una clave alojada en un nodo
donde est el correspondiente "dato" que precisamos encontrar:
data Buscar_ABB(abb t,clave k)
{
abb p;
dato e;
e=NULL;
p=t;
if (!estaVacio(p))
{
while (!estaVacio(p) && (p->k!=k) )
{
if (k < p->k)
{
p=p->l;
}
if (p->k < k)
{
p=p->r;
}
}
if (!estaVacio(p) &&(p->d!=NULL) )
{
e=copiaDato(p->d);
}
}

9
return e;
}
Vase ahora la versin recursiva en ese mismo lenguaje:
int buscar(tArbol *a, int elem)
{
if (a == NULL)
return 0;
else if (a->clave < elem)
return buscar(a->hDerecho, elem);
else if (a->clave > elem)
return buscar(a->hIzquierdo, elem);
else
return 1;
}

C) INSERCIN:
La insercin comienza aadiendo el nodo como lo haramos en
un rbol binario de bsqueda convencional y pintndolo de rojo. Lo
que sucede despus depende del color de otros nodos cercanos.
El trmino to nodo ser usado para referenciar al hermano del padre
de un nodo, como en los rboles familiares humanos. Conviene notar
que:

La propiedad Todas las hojas, incluyendo las nulas, son negras


siempre se cumple.

10
La propiedad Ambos hijos de cada nodo rojo son negros est
amenazada solo por aadir un nodo rojo, por repintar un nodo negro
de color rojo o por una rotacin.
La propiedad Todos los caminos desde un nodo dado hasta sus
nodos hojas contiene el mismo nmero de nodos negros est
amenazada solo por repintar un nodo negro de color rojo o por una
rotacin.
Al contrario de lo que sucede en otros rboles como puede ser
el rbol AVL, en cada insercin se realiza un mximo de una rotacin,
ya sea simple o doble. Por otra parte, se asegura un tiempo de
recoloracin mximo de por cada insercin.
NOTA IMPORTANTE: En los esquemas que acompaan a los
algoritmos, la etiqueta N ser utilizada por el nodo que est
siendo insertado, P para los padres del nodo N, G para los
abuelos del nodo N, y U para los tos del nodo N. Notamos que
los roles y etiquetas de los nodos estn intercambiados entre
algunos casos, pero en cada caso, toda etiqueta contina
representando el mismo nodo que representaba al comienzo del
caso. Cualquier color mostrado en el diagrama est o bien
supuesto en el caso o implicado por dichas suposiciones.

Los nodos to y abuelo pueden ser encontrados por las siguientes


funciones:

struct node *abuelo(struct node *n)


{
if ((n != NULL) && (n->padre != NULL))
return n->padre->padre;
else
return NULL;
}

11
struct node * tio(struct node *n)
{
struct node *a = abuelo(n);
if (n->padre == a->izdo)
return a->dcho;
else
return a->izdo;
}
Estudiemos ahora cada caso de entre los posibles que nos podemos
encontrar al insertar un nuevo nodo.
Caso 1: El nuevo nodo N es la raz de del rbol. En este caso, es
repintado a color negro para satisfacer la propiedad (la raz es negra).
Como esto aade un nodo negro a cada camino, la propiedad todos los
caminos desde un nodo dado a sus hojas contiene el mismo nmero de
nodos negros se mantiene. En C quedara as:

Void insercion_caso1(struct node *n)


{
if (n->padre == NULL)
n->color = NEGRO;
else
insercion_caso2(n);
}
Caso 2: El padre del nuevo nodo (esto es, el nodo P) es negro, as que
por propiedad (ambos hijos de cada nodo rojo son negros) se mantiene.
En este caso, el rbol es aun vlido. La propiedad todos los caminos
desde cualquier nodo dado a sus hojas contiene igual nmero de nodos
negros se mantiene, porque el nuevo nodo N tiene dos hojas negras
como hijos, pero como N es rojo, los caminos a travs de cada uno de
sus hijos tienen el mismo nmero de nodos negros que el camino hasta
12
la hoja que reemplaz, que era negra, y as esta propiedad se mantiene
satisfecha. Su implementacin:
Void insercion_caso2(struct node *n)
{
if (n->padre->color == NEGRO)
return; /* rbol vlido. */
else
insercion_caso3(n);
}
NOTA IMPORTANTE: En los siguientes casos se puede asumir
que N tiene un abuelo, el nodo G, porque su padre P es rojo, y si
fuese la raz, sera negro. Consecuentemente, N tiene tambin un
nodo to Ua pesar de que podra ser una hoja en los casos 4 y 5.

Caso 3: Si
el padre
P y el to U son rojos, entonces ambos nodos pueden ser
repintados de negro y el abuelo G se convierte en rojo para
mantener la propiedad todos los caminos desde cualquier nodo
dado hasta sus hojas contiene el mismo nmero de nodos
negros. Ahora, el nuevo nodo rojo N tiene un padre negro.
Como cualquier camino a travs del padre o el to debe pasar a
travs del abuelo, el nmero de nodos negros en esos caminos
no ha cambiado. Sin embargo, el abuelo G podra ahora violar la
propiedad la raz es negra o la de ambos hijos de cada nodo

13
rojo son negros, en este caso porque G podra tener un padre
rojo. Para solucionar este problema, el procedimiento completo
se realizar de forma recursiva hacia arriba hasta alcanzar el
caso 1. El cdigo en C quedara de la siguiente forma:

Void insercion_caso3(struct node *n)


{
struct node *t = tio(n), *a;

if ((t != NULL) && (t->color == ROJO)) {


n->padre->color = NEGRO;
t->color = NEGRO;
a = abuelo(n);
a->color = ROJO;
insercion_caso1(a);
} else {
insercion_caso4(n);
}
}

NOTA IMPORTANTE: En los casos restantes, se asume que el


nodo padre P es el hijo izquierdo de su padre. Si es el hijo
derecho, izquierda y derecha deberan ser invertidas a partir de
los casos 4 y 5. El cdigo del ejemplo toma esto en
consideracin.

14
Caso 4: El nodo padre P es rojo pero el to U es negro; tambin, el
nuevo nodo N es el hijo derecho de P, y P es el hijo izquierdo de su
padre G. En este caso, una rotacin a la izquierda que cambia los
roles del nuevo nodo N y su padre P puede ser realizada; entonces, el
primer nodo padre P se ve implicado al usar el caso 5 de insercin
(reetiquetando N y P ) debido a que la propiedad ambos hijos de
cada nodo rojo son negros se mantiene an incumplida. La rotacin
causa que algunos caminos (en el sub-rbol etiquetado como 1)
pasen a travs del nuevo nodo donde no lo hacan antes, pero ambos
nodos son rojos, as que la propiedad todos los caminos desde
cualquier nodo dado a sus hojas contiene el mismo nmero de nodos
negros no es violada por la rotacin. Aqu tenemos una posible
implementacin:

Void insercion_caso4(struct node *n)


{
struct node *a = abuelo(n);

if ((n == n->padre->dcho) && (n->padre == a->izdo)) {


rotar_izda(n->padre);
n = n->izdo;

15
} else if ((n == n->padre->izdo) && (n->padre == a->dcho)) {
rotar_dcha(n->padre);
n = n->dcho;
}
insercion_caso5(n);
}

Caso 5: El padre P es rojo pero el to U es negro, el nuevo nodo N


es el hijo izquierdo de P, y P es el hijo izquierdo de su padre G. En
este caso, se realiza una rotacin a la derecha sobre el padre P; el
resultado es un rbol donde el padre P es ahora el padre del nuevo
nodo N y del inicial abuelo G. Este nodo G ha de ser negro, as
como su hijo P rojo. Se intercambian los colores de ambos y el
resultado satisface aquella propiedad de que ambos hijos de un
nodo rojo son negros. Luego la propiedad todos los caminos
desde un nodo dado hasta sus hojas contienen el mismo nmero
de nodos negros tambin se mantiene satisfecha, ya que todos los
caminos que iban a travs de esos tres nodos entraban por G
antes, y ahora entran por P. En cada caso, este es el nico nodo
negro de los tres. Una posible implementacin en C es la siguiente:

16
Void insercion_caso5(struct node *n)
{
struct node *a = abuelo(n);

n->padre->color = NEGRO;
a->color = ROJO;
if ((n == n->padre->izdo) && (n->padre == a->izdo)) {
rotar_dcha(a);
} else {
/*
* En este caso, (n == n->padre->dcho) && (n->padre ==
a->dcho).
*/
rotar_izda(a);
}
}

Ntese que la insercin se realiza sobre el propio rbol y que los


cdigos del ejemplo utilizan recursin de cola.
D) Eliminacin
En un rbol binario de bsqueda normal, cuando se borra un nodo
con dos nodos internos como hijos, tomamos el mximo elemento del
subrbol izquierdo o el mnimo del subrbol derecho, y movemos su
valor al nodo que es borrado .Borramos, entonces el nodo del que
copibamos el valor que debe tener menos de dos nodos no hojas por
hijos. Copiar un valor no viola ninguna de las propiedades rojo-
negro y reduce el problema de borrar en general al de borrar un
nodo con como mucho un hijo no hoja. No importa si este nodo

17
es el nodo que queramos originalmente borrar o el nodo del que
copiamos el valor.
Si borramos un nodo rojo, podemos simplemente reemplazarlo con su
hijo, que debe ser negro. Todos los caminos hasta el nodo borrado
simplemente pasarn a travs de un nodo rojo menos, y ambos
nodos, el padre del borrado y el hijo, han de ser negros, as que las
propiedades como todas las hojas, incluyendo las nulas, son negras
y los dos hijos de cada nodo rojo son negros se mantienen. Otro
caso simple es cuando el nodo borrado es negro y su hijo es rojo.
Simplemente eliminar un nodo negro podra romper las
propiedades los dos hijos de cada nodo rojo son negros y
todos los caminos desde un nodo dado hasta sus hojas
contienen el mismo nmero de nodos negros, pero si
repintamos su hijo de negro, ambas propiedades quedan
preservadas.
El caso complejo es cuando el nodo que va a ser borrado y su hijo
son negros. Empezamos por reemplazar el nodo que va a ser borrado
con su hijo. Llamaremos a este hijo (en su nueva posicin) N, y su
hermano (el otro hijo de su nuevo padre) S. En los diagramas de
debajo, usaremos P para el nuevo padre de N, SL para el hijo
izquierdo de S, y SR para el nuevo hijo derecho de S (se puede
mostrar que S no puede ser una hoja).
NOTA IMPORTANTE: Entre algunos casos cambiamos roles y
etiquetas de los nodos, pero en cada caso, toda etiqueta sigue
representando al mismo nodo que representaba al comienzo del
caso. Cualquier color mostrado en el diagrama es o bien
supuesto en su caso o bien implicado por dichas suposiciones.
El blanco representa un color desconocido (o bien rojo o bien
negro).
El cumplimiento de estas reglas en un rbol con n nodos,
asegura un mximo de tres rotaciones y
hasta recoloraciones.
struct node *
hermano(struct node *n)
{
18
if (n == n->padre->izdo)
return n->padre->dcho;
else
return n->padre->izdo;
}
Nota: Con el fin de preservar la buena definicin del rbol,
necesitamos que toda hoja nula siga siendo una hoja nula tras
todas las transformaciones (que toda hoja nula no tendr ningn
hijo). Si el nodo que estamos borrando tiene un hijo no hoja N, es
fcil ver que la propiedad se satisface. Si, por otra parte N fuese
una hoja nula, se verifica por los diagramas o el cdigo que para
todos los casos la propiedad se satisface tambin.

Podemos realizar los pasos resaltados arriba con el siguiente cdigo,


donde la funcin reemplazar_nodo sustituye hijo en el lugar de N en el
rbol. Por facilitar la comprensin del ejemplo, en el cdigo de esta
seccin supondremos que las hojas nulas estn representadas por
nodos reales en lugar de NULL (el cdigo de la seccin insercin
trabaja con ambas representaciones).

Void elimina_un_hijo(struct node *n)


{
/*
* Precondicin: n tiene al menos un hijo no nulo.
*/
struct node *hijo = es_hoja(n->dcho) ? n->izdo : n->dcho;

reemplazar_nodo(n, hijo);
if (n->color == NEGRO) {
if (hijo->color == ROJO)
hijo->color = NEGRO;

19
else
eliminar_caso1(hijo);
}
free(n);
}
NOTA IMPORTANTE: Si N es una hoja nula y no queremos
representar hojas nulas como nodos reales, podemos modificar
el algoritmo llamando primero a eliminar_caso1() en su padre (el
nodo que borramos, n en el cdigo anterior) y borrndolo
despus. Podemos hacer esto porque el padre es negro, as que
se comporta de la misma forma que una hoja nula (y a veces es
llamada hoja fantasma). Y podemos borrarla con seguridad, de
tal forma que n seguir siendo una hoja tras todas las
operaciones, como se muestra arriba.

Si N y su padre original son negros, entonces borrar este padre


original causa caminos que pasan por N y tienen un nodo negro
menos que los caminos que no. Como esto viola la propiedad todos
los caminos desde un nodo dado hasta su nodos hojas deben
contener el mismo nmero de nodos negros, el rbol debe ser
reequilibrado. Tenemos varios casos:
Caso 1: N es la nueva raz. En este caso, hemos acabado. Borramos
un nodo negro de cada camino y la nueva raz es negra, as las
propiedades se cumplen. Una posible implementacin en el lenguaje
de programacin C sera la siguiente:

Void eliminar_caso1(struct node *n)


{
if (n->padre!= NULL)
eliminar_caso2(n);
}

20
NOTA IMPORTANTE: En los casos 2, 5 y 6, asumimos que N es el
hijo izquierdo de su padre P. Si ste fuese el hijo derecho, la
izquierda y la derecha deberan ser invertidas en todos estos
casos. De nuevo, el cdigo del ejemplo toma ambos casos en
cuenta.
Caso 2: S es rojo. En este caso invertimos los colores de P y S, por lo
que rotamos a la izquierda P, pasando S a ser el abuelo de N. Ntese
que P tiene que ser negro al tener un hijo rojo. Aunque todos los
caminos tienen todava el mismo nmero de nodos negros, ahora N
tiene un hermano negro y un padre rojo, as que podemos proceder a
al paso 4, 5 o 6 (este nuevo hermano es negro porque ste era uno
de los hijos de S, que es rojo). En casos posteriores, re etiquetaremos
el nuevo hermano de N como S. Aqu podemos ver una
implementacin:

Void eliminar_caso2(struct node *n)

struct node *hm = hermano(n);

21
if (hm->color == ROJO) {

n->padre->color = ROJO;

hm->color = NEGRO;

if (n == n->padre->izdo)

rotar_izda(n->padre);

else

rotar_dcha(n->padre);

eliminar_caso3(n);

Caso 3: P, S y los hijos de S son negros. En este caso, simplemente


cambiamos S a rojo. El resultado es que todos los caminos a travs
de S, precisamente aquellos que no pasan por N, tienen un nodo
negro menos. El hecho de borrar el padre original de N haciendo que
todos los caminos que pasan por N tengan un nodo negro menos
nivela el rbol. Sin embargo, todos los caminos a travs de P tienen
ahora un nodo negro menos que los caminos que no pasan por P, as
que la propiedad 5 an no se cumple (todos los caminos desde
cualquier nodo a su nodo hijo contienen el mismo nmero de nodos
negros). Para corregir esto, hacemos el proceso de reequilibrio en P,
empezando en el caso 1. Su implementacin en C:

22
void eliminar_caso3(struct node *n)

struct node *hm = hermano_menor(n);

if ((n->padre->color == NEGRO) &&

(hm->color == NEGRO) &&

(hm->izdo->color == NEGRO) &&

(hm->dcho->color == NEGRO)) {

hm->color = ROJO;

eliminar_caso1(n->padre);

} else

eliminar_caso4(n);

Caso 4: S y los hijos de ste son negros, pero P es rojo. En este


caso, simplemente intercambiamos los colores de S y P. Esto no
afecta al nmero de nodos negros en los caminos que no van a
travs de S, pero aade uno al nmero de nodos negros a los
caminos que van a travs de N, compensando as el borrado del
nodo negro en dichos caminos. Si lo implementamos en C, quedara:

23
Void eliminar_caso4(struct node *n)

struct node *hm = hermano_menor(n);

if ((n->padre->color == ROJO) &&

(hm->color == NEGRO) &&

(hm->izdo->color == NEGRO) &&

(hm->dcho->color == NEGRO)) {

hm->color = ROJO;

n->padre->color = NEGRO;

} else

eliminar_caso5(n);

Caso 5: S es negro, su hijo izquierdo es rojo, el derecho es negro, y N


es el hijo izquierdo de su padre. En este caso rotamos a la derecha S,
as su hijo izquierdo se convierte en su padre y en el hermano de N.
Entonces intercambiamos los colores de S y su nuevo padre. Todos
los caminos tienen an el mismo nmero de nodos negros, pero
ahora N tiene un hermano negro cuyo hijo derecho es rojo, as
que caemos en el caso 6. Ni N ni su padre son afectados por esta
transformacin (de nuevo, por el caso 6, reetiquetamos el nuevo
hermano de N como S). He aqu la implementacin en C:

24
Void eliminar_caso5(struct node *n)

{ struct node *hm = hermano(n);

if ((n == n->padre->izdo) &&

(hm->color == NEGRO) &&

(hm->izdo->color == ROJO) &&

(hm->dcho->color == NEGRO)) {

hm->color = ROJO;

hm->izdo->color = NEGRO;

rotar_dcha(hm);

} else if ((n == n->padre->dcho) &&

(hm->color == NEGRO) &&

(hm->dcho->color == ROJO) &&

(hm->izdo->color == NEGRO)) {

hm->color = ROJO;

hm->dcho->color = NEGRO;

rotar_izda(hm);

eliminar_caso6(n);}

25
De nuevo, todas las llamadas de la funcin usan recursin de cola as
que el algoritmo realiza sus operaciones sobre el propio rbol.
Adems, las llamadas no recursivas se harn despus de una
rotacin, luego se harn un nmero de rotaciones (ms de 3) que
ser constante.

4) DEMOSTRACION DE COTAS

Un rbol rojo-negro que contiene n nodos internos tiene una altura de


O(log(n)).

Hagamos los siguientes apuntes sobre notacin:

H(v) = altura del rbol cuya raz es el nodo v.

bh(v) = nmero de nodos negros (sin contar v si es negro) desde v


hasta cualquier hoja del subrbol (llamado altura-negra).

Lema: Un subrbol enraizado al nodo v tiene al menos nodos


internos.

Demostracin del lema (por induccin sobre la altura):

Caso base: h(v)=0 Si v tiene altura cero entonces debe ser rbol
vaco, por tanto bh(v)=0. Luego:

H
Hiptesis de Induccin: si v es tal que h(v) = k y
contiene nodos internos, veamos que esto implica
que tal que h( ) = k+1 contiene nodos internos.
Si tiene h( ) > 0 entonces es un nodo interno. Como ste tiene dos
hijos que tienen altura-negra, o bh( ) o bh( )-1 (dependiendo si es
rojo o negro). Por la hiptesis de induccin cada hijo tiene al
menos nodos internos, as que tiene :
nodos
internos.
26
Usando este lema podemos mostrar que la altura del rbol es
algortmica. Puesto que al menos la mitad de los nodos en cualquier
camino desde la raz hasta una hoja negra (propiedad 4 de un rbol
rojo-negro), la altura-negra de la raz es al menos h(raz)/2. Por el
lema tenemos que:

Por tanto, la altura de la raz es O(log(n)).


5) COMPLEJIDAD
En el cdigo del rbol hay un bucle donde la raz de la
propiedad rojo-negro que hemos querido devolver a su lugar, x,
puede ascender por el rbol un nivel en cada iteracin Como la
altura original del rbol es O(log n), hay O(log n) iteraciones. As
que en general la insercin tiene una complejidad de O(log n).

27

También podría gustarte