Árboles avl cont

20
Árboles AVL cont.

Upload: svea

Post on 14-Jan-2016

35 views

Category:

Documents


0 download

DESCRIPTION

Árboles AVL cont. Algoritmo de Inserción. En la construcción de un árbol AVL todo nodo que se inserte, se insertará como una hoja . Los pasos son: 1. Buscar donde insertar el nuevo nodo 2. Insertar el nuevo nodo 3. Recalcular factores de balance - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Árboles AVL cont

Árboles AVLcont.

Page 2: Árboles AVL cont

Algoritmo de Inserción

En la construcción de un árbol AVL todo nodo que se inserte, se insertará como una hojahoja. Los pasos son:

1. Buscar donde insertar el nuevo nodo2. Insertar el nuevo nodo3. Recalcular factores de balance4. Rebalancear el árbol si es necesario

Page 3: Árboles AVL cont

Para el primer paso, el cual consiste en buscar

dónde insertar el nuevo nodo se utilizan las

siguientes variables:

– p: Para recorrer el árbol buscando donde insertar el nuevo nodo

– q: Apuntará hacia el padre de p

Inicialmente p será la raíz y q será NULL

Page 4: Árboles AVL cont

• Cuando p se haga NULL, q apuntará hacia el nodo que será el padre del nodo que contiene el nuevo dato

• Ahora bien, como el tercer paso es rebalancear el árbol, se requiere conocer cuál será el nodo "raíz" del sub-árbol a balancear. Se llamará a este nodo PIVOTE. Es decir, PIVOTE será la raíz del árbol a balancear

Page 5: Árboles AVL cont

• Como al rebalancear un árbol, éste siempre cambia de raíz, la nueva raíz, (que queda en Q), habrá que pegarla del nodo que era padre de PIVOTE. Esto implica que se debe conocer el padre de PIVOTE. Se llamará a este nodo pp

Page 6: Árboles AVL cont

• Para determinar PIVOTE se debe tener en cuenta que los únicos nodos que pueden quedar desbalanceados son aquellos cuyo factor de balance es diferente de cero

• En concreto, PIVOTE es el nodo más cercano al nodo donde se hará la inserción, con factor de balance diferente de cero. Es bueno aclarar que es el nodo más cercano en la trayectoria desde la raíz hasta el nodo que será el padre del nuevo nodo

• Puede suceder que PIVOTE sea RAIZ, con factor de balance cero

• Inicialmente PIVOTE será la raíz y pp será NULL

Page 7: Árboles AVL cont

class Nodo{ public:

int clave; Nodo *hijoIzq; //Apuntador a hijo izquierdo Nodo *hijoDer; //Apuntador a hijo derecho int FB; //Factor de Balance

public: Nodo(int dato);

};

Nodo::Nodo(int dato) //Constructor{

clave = dato;hijoIzq = NULL;hijoDer = NULL;FB=0;

}

Page 8: Árboles AVL cont

class ArbolAVL{ public:

Nodo *raiz; //Apunta a la raíz del arbol Nodo *actual;

public:ArbolAVL(); //Constructorvoid insertar(int dato);

//Recorrido void inorden(Nodo *r);

//Rotacionesvoid Rotacion_a_la_Derecha(Nodo *P, Nodo *Q);void Rotacion_a_la_Izquierda(Nodo *P, Nodo *Q);

Nodo *Doble_Rotacion_a_la_Derecha(Nodo *P, Nodo *Q); Nodo *Doble_Rotacion_a_la_Izquierda(Nodo *P, Nodo *Q);};

Page 9: Árboles AVL cont

//Constructor

ArbolAVL::ArbolAVL()

{

raiz=NULL;

actual=NULL;

}

Page 10: Árboles AVL cont

//Rotaciones:void ArbolAVL::Rotacion_a_la_Derecha(Nodo *P, Nodo *Q){ P -> hijoIzq = Q -> hijoDer; Q -> hijoDer = P; P -> FB = 0; Q -> FB = 0;}

void ArbolAVL::Rotacion_a_la_Izquierda(Nodo *P, Nodo *Q){ P -> hijoDer = Q -> hijoIzq; Q -> hijoIzq = P; P -> FB = 0; Q -> FB = 0;}

Page 11: Árboles AVL cont

Nodo *ArbolAVL::Doble_Rotacion_a_la_Derecha(Nodo *P, Nodo *Q){

Nodo *R = Q -> hijoDer; //Se obtiene R a partir de Qint factor_R = R->FB; //Se guarda el factor de balance de R

Rotacion_a_la_Izquierda(Q, R);Rotacion_a_la_Derecha(P, R);switch ( factor_R )

{ case 0: P -> FB = 0;

Q -> FB = 0; break;

case 1: P -> FB = -1;Q -> FB = 0;

break; case -1: P -> FB = 0;

Q -> FB = 1; break;

}R -> FB = 0; //Aunque sobra ya que las rotaciones ya lo han puesto en 0return R; //Se devuelve la raíz del árbol balanceado

}

Page 12: Árboles AVL cont

Nodo *ArbolAVL::Doble_Rotacion_a_la_Izquierda(Nodo *P, Nodo *Q){

Nodo *R = Q -> hijoIzq; //Se obtiene R a partir de Qint factor_R = R->FB; //Se guarda el factor de balance de R

Rotacion_a_la_Derecha(Q, R); Rotacion_a_la_Izquierda(P, R);switch ( factor_R )

{ case 0: P -> FB = 0;

Q -> FB = 0;break;

case 1: P -> FB = 0;Q -> FB = -1;

break; case -1: P -> FB = 1;

Q -> FB = 0; break;

}R -> FB = 0; //Aunque sobra ya que las rotaciones ya lo han puesto en 0return R; //Se devuelve la raíz del árbol balanceado

}

Page 13: Árboles AVL cont

//Algoritmo de Inserción:void ArbolAVL::insertar(int dato){

Nodo *x= new Nodo(dato); //Crea el nodo para el nuevo

Nodo *p = raiz; //Asigna valores iniciales a las variablesNodo *q = NULL; //que se utilizan para buscar el sitio dondeNodo *pivote = raiz; //se insertará el nuevo nodo y determinarNodo *pp= NULL; //pivote y su padre.

if(raiz == NULL) //Si árbol vacío{

raiz = actual = x; //El nuevo a su vez es la raíz y el actual}

Page 14: Árboles AVL cont

else {

while (p != NULL){

if (p-> clave == dato) { //Controla repetidos delete(x);

return; } if (p->FB != 0) { //O sea que es -1 ó +1

pivote = p; //Determina el PIVOTE pp = q; //y su padre.

} q = p; //Actualiza qif ( p->clave > dato)

p = p -> hijoIzq; //Avanza con pelse

p = p -> hijoDer; //Avanza con p

}

Page 15: Árboles AVL cont

if (q->clave > dato) q->hijoIzq = x; //Inserta x como hijo izquierdo

else // o como hijo derecho de q q->hijoDer = x;

//Recalcula factor de balance de PIVOTEif (pivote-> clave > dato)

{pivote->FB = pivote->FB +1; q = pivote-> hijoIzq;

}else{

pivote->FB = pivote->FB -1; q = pivote-> hijoDer;

}

Page 16: Árboles AVL cont

//Recalcula factores de balance de todos los nodos en la//trayectoria desde PIVOTE hasta el nodo insertado x

p = q; while (p != x){

if (p->clave > dato) {

p->FB = 1; p = p->hijoIzq;

}else{

p->FB = -1; p = p->hijoDer;

} }

Page 17: Árboles AVL cont

if (pivote->FB == 0 || pivote-> FB == -1 || pivote-> FB == 1)//Si el árbol siguió balanceado retorna return;

//Determina el tipo de rotaciónif (pivote->FB == 2 && q->FB == 1) Rotacion_a_la_Derecha(pivote,q);if (pivote->FB == -2 && q->FB == -1) Rotacion_a_la_Izquierda(pivote,q);if (pivote->FB == 2 && q->FB == -1) q=Doble_Rotacion_a_la_Derecha(pivote,q);if (pivote->FB == -2 && q->FB == 1) q=Doble_Rotacion_a_la_Izquierda(pivote,q);

Page 18: Árboles AVL cont

// Si el nodo desbalanceado era la raíz lo actualiza y regresa. if (pp == NULL) {

raiz = q; return;

}

// Pega la nueva raíz del árbol rebalanceado (q) al nodo pp.if (pivote == pp->hijoIzq)

pp->hijoIzq = q; else

pp->hijoDer = q;}

}

Page 19: Árboles AVL cont

void ArbolAVL::inorden(Nodo *r){

if(r){

inorden(r->hijoIzq);cout<<" "<<r->clave<<" ";inorden(r->hijoDer);

}}

Page 20: Árboles AVL cont

void main(void){ //Se crea un árbol AVL

ArbolAVL miarbolAVL;

//Se insertan claves en el árbol:

miarbolAVL.insertar(9);miarbolAVL.insertar(6);miarbolAVL.insertar(1); //Desencadena rotación por la derecha

miarbolAVL.inorden(miarbolAVL.raiz);}