Sunteți pe pagina 1din 12

Profesores: Carlos Rodriguez, Mario Perello, Jose Racker

Lic. en Sistemas de Informacin


Programacin 2

UNIDAD: ARBOLES BINARIOS

Objetivo:
TAD de Arboles Binarios. Este archivo incluye las implementacin de
Apuntadores.

Contenido:

IMPLEMENTACION DE ARBOLES CON APUNTADORES

unit ArbolesBinarios;

interface
Uses Tipos, Dialogs, Colas_Pointer, Stack_Array;

Const
MAX = 10000;
Nulo = Nil;

Type
PosicionArbol = ^NodoArbol;

NodoArbol = record
Datos: TipoElemento;
HI, HD: PosicionArbol;
FE: -1..1; // Para el Balanceo
End;

Arbol = Record
Raiz: PosicionArbol;
Q_Items: LongInt;
End;

Procedure CrearArbolNulo(Var A:Arbol);
Function ArbolNulo(A:Arbol): Boolean; // Sinonimo de arbol vacio
Function ArbolLleno(A:Arbol): Boolean;
Function RamaNula(P:PosicionArbol): Boolean; // Controla si un apuntador es nil
Function RecuperarDatos(A: Arbol; P:PosicionArbol; Var X:TipoElemento): Boolean;
Function CargarArbol(Var A:Arbol): Boolean;
Function PreOrden(A: Arbol): String;
Function InOrden(A: Arbol): String;
Function PostOrden(A: Arbol): String;
Function Anchura(A: Arbol): String;
Function PreOrdenITE(A: Arbol): String;
Function Altura(A: Arbol): Integer;
Function BuscarPreOrden(A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
PosicionArbol;
Function Nivel(A: Arbol; Q:PosicionArbol): Integer;
Function HijoIzquierdo(A: Arbol; P:PosicionArbol): PosicionArbol;
Function HijoDerecho(A: Arbol; P:PosicionArbol): PosicionArbol;
Function Padre(A: Arbol; Hijo:PosicionArbol): PosicionArbol;
// Busqueda Binaria
Function InsertarNodo(Var A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
Boolean;
Function EliminarNodo(Var A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
Boolean;
Function BusquedaBinaria(A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
PosicionArbol;
// Busqueda Binaria Balanceado


Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2
Function InsertarNodoAVL(Var A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
Boolean;
Function EliminarNodoAVL(Var A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
Boolean;


implementation

Procedure CrearArbolNulo(Var A:Arbol);
Begin
A.raiz := Nulo;
A.q_items := 0;
End;

Function ArbolNulo(A:Arbol): Boolean; // Sinonimo de arbol vacio
Begin
ArbolNulo := (A.raiz = Nulo);
End;

Function ArbolLleno(A:Arbol): Boolean;
Begin
ArbolLLeno := (A.q_items = MAX);
End;

Function RamaNula(P:PosicionArbol): Boolean; // Controla si un apuntador es nil
Begin
RamaNula := (P = Nulo);
End;

Function CargarArbol(Var A:Arbol): Boolean;
Var X: TipoElemento;
// Procedimiento que carga el arbol en preorden
Procedure Cargar(Var P: PosicionArbol);
Begin
X.DS := InputBox('Ingresar un Caracter', 'Ingresar Datos', '.');
If X.DS = '.' Then P := Nulo
Else Begin
New(P);
P^.Datos := X;
Inc(A.Q_Items);
Cargar(P^.HI);
Cargar(P^.HD);
End;
End;
// Inicio de la Funcion
Begin
Cargar(A.raiz);
CargarArbol := True;
End;

Function RecuperarDatos(A: Arbol; P:PosicionArbol; Var X:TipoElemento): Boolean;
Begin
RecuperarDatos := False;
If Not RamaNula(P) Then Begin
X := P^.Datos;
RecuperarDatos := True;
End ;
End;





Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2

// Recorrido Pre-Orden Recursivo
Function PreOrden(A: Arbol): String;
Var S: String;
// Proceso que lee en preorden
Procedure PreOrd(P: PosicionArbol);
Begin
If RamaNula(P) Then S := S + '.'
Else Begin
S := S + P^.Datos.DS ;
PreOrd(P^.HI);
PreOrd(P^.HD);
End;
End;
// Inicio de la funcion
Begin
S := '';
PreOrd(A.Raiz);
PreOrden := S;
End;

// Recorrido IN-Orden Recursivo
Function InOrden(A: Arbol): String;
Var S: String;
// Proceso que lee en preorden
Procedure InOrd(P: PosicionArbol);
Begin
If RamaNula(P) Then S := S + '.'
Else Begin
InOrd(P^.HI);
S := S + P^.Datos.DS ;
InOrd(P^.HD);
End;
End;
// Inicio de la funcion
Begin
S := '';
InOrd(A.Raiz);
InOrden := S;
End;

// Recorrido Post-Orden Recursivo
Function PostOrden(A: Arbol): String;
Var S: String;
// Proceso que lee en preorden
Procedure PostOrd(P: PosicionArbol);
Begin
If RamaNula(P) Then S := S + '.'
Else Begin
PostOrd(P^.HI);
PostOrd(P^.HD);
S := S + P^.Datos.DS ;
End;
End;
// Inicio de la funcion
Begin
S := '';
PostOrd(A.Raiz);
PostOrden := S;
End;



Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2

// Recorre el arbol por niveles
Function Anchura(A: Arbol): String;
Var S: String;
C: Cola;
Q: PosicionArbol;
X: TipoElemento;
Begin
S := '';
If Not ArbolNulo(A) Then Begin
CrearColaVacia(C);
X.DP := A.Raiz;
Encolar(C, X);
While Not ColaVacia(C) Do Begin
RecuperarFrente(C, X);
DesEncolar(C);
Q := X.DP;
S := S + Q^.Datos.DS;
// Si no es nulo encolo el hijo izq.
If Not RamaNula(Q^.HI) Then Begin
X.DP := Q^.HI;
Encolar(C, X);
End;
// Si no es nulo encolo el hijo der.
If Not RamaNula(Q^.HD) Then Begin
X.DP := Q^.HD;
Encolar(C, X);
End;
End;
End;
Anchura := S;
End;

// Realiza el recorrido pre-orden en forma iterativa
Function PreOrdenITE(A: Arbol): String;
Var S: String;
P: Pila;
Q: PosicionArbol;
X: TipoElemento;
Begin
S := '';
CrearPilaVacia(P);
Q := A.Raiz;
While Not(PilaVacia(P)) OR Not(RamaNula(Q)) Do Begin // Ciclo del Loop de llamada
por derecha
While Not(RamaNula(Q)) Do begin // Simula la llamada recursiva por Izquierda
S := S + Q^.Datos.DS ;
X.DP := Q;
Apilar(P, X);
Q := Q^.HI ;
End;
// Corto las llamada por izquierda. Tengo que desapilar e ir por derecha
S := S + '.';
RecuperarTope(P, X);
Q := X.DP;
DesApilar(P);
Q := Q^.HD ;
End;
PreOrdenITE := S;
End;



Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2

// Funcion Que Busca un Elemento en un Arbol Desordenado
Function BuscarPreOrden(A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
PosicionArbol;
Var Pos: PosicionArbol;
Procedure Buscar(P: PosicionArbol);
Begin
If Not RamaNula(P) Then Begin
If CompararTE(X, P^.Datos, ComparaPor) = igual Then Pos := P
Else Begin
Buscar(P^.HI);
Buscar(P^.HD);
End;
End;
End;
Begin
Pos := Nulo;
Buscar(A.Raiz);
BuscarPreOrden := Pos;
End;

// Sacamos la altura del Arbol usando el recorrido pre-orden
Function Altura(A: Arbol): Integer;
Var H: Integer;
// Proceso que resuelve la altura. C cuenta los pasos desde la raiz a cada nodo
Procedure Alt(P: PosicionArbol; C: Integer);
Begin
If RamaNula(P) Then Begin
If C > H Then H := C; // cada vez que llega a la hoja pregunta si la cantidad
de pasos fue mayor que la de la hoja anterior
End
Else Begin
Alt(P^.HI, C + 1);
Alt(P^.HD, C + 1);
End;
End;
// Inicio de la funcion
Begin
H := 0;
Alt(A.Raiz, 0);
Altura := H;
End;

Function Nivel(A: Arbol; Q:PosicionArbol): Integer;
Var N: Integer;
B: Boolean;
Procedure Niv(P: PosicionArbol; C: Integer);
Begin
If RamaNula(P) Then
Else Begin
If P = Q Then N := C;
Niv(P^.HI, C + 1);
Niv(P^.HD, C + 1);
End;
End;
Begin
N := 0;
B := False;
Niv(A.Raiz, 0);
Nivel := N;
End;


Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2

Function Padre(A: Arbol; Hijo:PosicionArbol): PosicionArbol;
Var Pad: PosicionArbol;
Procedure BuscaPadre(P: PosicionArbol);
Begin
If Not RamaNula(P) Then Begin
If Not RamaNula(P^.HI) Then
If P^.HI = Hijo Then Pad := P
Else If Not RamaNula(P^.HD) Then
If P^.HD = Hijo Then Pad := P
Else Begin
BuscaPadre(P^.HI);
BuscaPadre(P^.HD);
End;
End;
End;
Begin
Pad := Nulo;
BuscaPadre(A.Raiz);
Padre := Pad;
End;

Function HijoIzquierdo(A: Arbol; P:PosicionArbol): PosicionArbol;
Begin
HijoIzquierdo := Nulo;
If Not RamaNula(P) Then HijoIzquierdo := P^.HI;
End;

Function HijoDerecho(A: Arbol; P:PosicionArbol): PosicionArbol;
Begin
HijoDerecho := Nulo;
If Not RamaNula(P) Then HijoDerecho := P^.HD;
End;

//-----------------------------------------------------------
// Rutinas de Arboles Binarios de Busqueda SIN BALANCEO
//-----------------------------------------------------------

Procedure CrearNodoArbol(Var P:PosicionArbol; X:TipoElemento);
Begin
New(P);
P^.Datos := X;
P^.HI := Nulo;
P^.HD := Nulo;
P^.FE := 0;
End;

Function InsertarNodo(Var A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
Boolean;
Var P, Q: PosicionArbol;
Begin
If ArbolNulo(A) Then Begin // Inserta la Raiz. Primer Nodo
CrearNodoArbol(Q, X);
A.Raiz := Q;
Inc(A.Q_Items);
End
Else Begin
Q := A.Raiz;
While Not(RamaNula(Q)) Do Begin // Busca la Hoja donde insertar
P := Q;
If CompararTE(X, Q^.Datos, ComparaPor) = menor Then Q := Q^.HI


Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2
Else Q := Q^.HD;
End;
// Crea el Nodo Nuevo
CrearNodoArbol(Q, X);
Inc(A.Q_Items);
// Conecta el Nodo Nueva con la Hoja por el Hijo que corresponda segun sea menor
o mayor
If CompararTE(X, P^.Datos, ComparaPor) = menor Then P^.HI := Q
Else P^.HD := Q;
End;
InsertarNodo := True;
End;


Function EliminarNodo(Var A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
Boolean;
Var Q: PosicionArbol;

Procedure Eliminar(Var P: PosicionArbol);

Procedure Buscar_Clave_Reemplazar(Var R: PosicionArbol);
begin
If Not (RamaNula(R^.HI)) Then Buscar_Clave_Reemplazar(R^.HI)
Else Begin
Q^.Datos := R^.Datos;
Q := R;
R := Q^.HD;
End;
End;

// Inicio de Eliminar
Begin
If Not RamaNula(P) Then
// Busca la clave por izquierda
If CompararTE(X, P^.Datos, ComparaPor) = menor Then Eliminar(P^.HI)
Else // Busca la clave por derecha
If CompararTE(X, P^.Datos, ComparaPor) = mayor Then Eliminar(P^.HD)
Else Begin // aca encontre la clave
Q := P; // Asigna P para hacer el Dispose
// Pregunta si solo tiene hijo derecho
If RamaNula(Q^.HI) Then P := Q^.HD
Else // Pregunta si solo tiene hijo izquierdo
If RamaNula(Q^.HD) Then P := Q^.HI
Else // Tiene 2 hijos. Busca la clave para reemplazar
Buscar_Clave_Reemplazar(Q^.HD);
Dispose(Q);
Dec(A.Q_Items);
End;
End;
// Inicio de la Funcion
Begin
Eliminar(A.raiz);
EliminarNodo := True;
End;

// Busca en Forma Binaria la Clave en Funcion de uno de los Campos del TipoElemento
Function BusquedaBinaria(A: Arbol; X:TipoElemento; ComparaPor:CampoComparar):
PosicionArbol;
Var Q: PosicionArbol;
Encontre: Boolean;
RtaComp: Comparacion;


Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2
Begin
BusquedaBinaria := Nulo;
Encontre := False;
Q := A.Raiz;
While Not(RamaNula(Q)) And (Not(Encontre)) Do Begin // Busca a izquierda y Derecha
RtaComp := CompararTE(X, Q^.Datos, ComparaPor);
If RtaComp = menor Then Q := Q^.HI
Else If RtaComp = mayor Then Q := Q^.HD
Else Encontre := True
End;

If Encontre Then BusquedaBinaria := Q;
End;

//----------------------------------------------------------
// RUTINAS DE BALANCEO
//----------------------------------------------------------
Procedure R_II(Var N: PosicionArbol; N1: PosicionArbol);
Begin
// Rotacion
N^.hi := N1^.hd;
N1^.hd:= N;
// Acomoda los factores de equilibrio
If N1^.fe = -1 then Begin
N1^.fe := 0;
N^.fe := 0;
End
Else Begin
N^.fe := -1;
N1^.fe := 1;
End;
// retorna la nueva raiz
N := N1;
End;

Procedure R_DD(Var N: PosicionArbol; N1: PosicionArbol);
Begin
// Rotacion
N^.hd := N1^.hi;
N1^.hi:= N;
// Acomodo FE
If N1^.fe = 1 then Begin
N1^.fe := 0;
N^.fe := 0;
End
Else Begin
N^.fe := 1;
N1^.fe := -1;
End;
// Raiz nueva
N := N1;
End;

Procedure R_ID(Var N: PosicionArbol; N1: PosicionArbol);
Var N2: PosicionArbol;
Begin
N2:= N1^.hd;
// 1er. Rotacion
N^.hi := N2^.hd;
N2^.hd:= N;
// Segunda rotacion


Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2
N1^.hd:= N2^.hi;
N2^.hi:= N1;
// Acomoda FE
If N2^.fe = -1 then N^.fe := 1
Else N^.fe := 0;
If N2^.fe = 1 Then N1^.fe := -1
Else N1^.fe := 0;
// FE de N2 siempre es cero
N2^.fe := 0;
// retorna nueva raiz
N := N2;
End;

Procedure R_DI(Var N: PosicionArbol; N1: PosicionArbol);
Var N2: PosicionArbol;
Begin
N2:= N1^.hi;
// 1er. rotacion
N^.hd := N2^.hi;
N2^.hi:= N;
// 2 da. rotacion
N1^.hi:= N2^.hd;
N2^.hd:= N1;
// Acomoda el FE
If N2^.fe = -1 then N1^.fe := 1
Else N1^.fe := 0;
If N2^.fe = 1 Then N^.fe := -1
Else N^.fe := 0;
// FE de N2
N2^.fe := 0;
// retorna raiz nueva
N := N2;
End;

Function InsertarNodoAVL(Var A: Arbol; X: TipoElemento; ComparaPor:CampoComparar):
Boolean;
Var bh: Boolean;

Procedure Insertar(Var R: PosicionArbol; Var bh: Boolean);
Var N1: PosicionArbol;
Begin
If RamaNula(R) Then Begin
CrearNodoArbol(R, X);
bh := True;
End
Else
If CompararTE(X, R^.Datos, ComparaPor) = menor Then Begin
Insertar(R^.hi, bh);
If bh Then
Case R^.fe of
1: Begin
R^.fe := 0;
bh := False;
End;
0: R^.Fe := -1;
-1: Begin
N1:= R^.hi;
If N1^.fe <= 0 Then R_II(R, N1)
Else R_ID(R, N1);
bh:= False;
End;


Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2
End;
End
Else
If (CompararTE(X, R^.Datos, ComparaPor) = mayor) OR (CompararTE(X, R^.Datos,
ComparaPor) = igual) Then Begin
Insertar(R^.hd, bh);
If bh Then
Case R^.fe Of
-1: Begin
R^.fe := 0;
bh := False;
End;
0: R^.fe := 1;
1: Begin
N1:= R^.hd;
If N1^.fe >= 0 Then R_DD(R, N1)
Else R_DI(R, N1);
bh:= False;
End;
End;
End;
End;
Begin
InsertarNodoAVL := False;
bh := False;
Insertar(A.raiz, bh);
InsertarNodoAVL := True;
End;

{ --- Al Borrar un Nodo por la Izquierda entonces crece la derecha --- }
Procedure Equilibrar_I(Var N:PosicionArbol; Var bh: Boolean);
Var N1: PosicionArbol;
Begin
Case N^.fe Of
-1: N^.fe:= 0;
0: Begin
N^.fe:= 1;
bh:= False;
End;
1: Begin
N1:= N^.hd;
If N1^.fe >= 0 Then Begin
If N1^.fe = 0 Then bh:= false;
R_DD(N, N1);
End
Else R_DI(N, N1);
End;
End;
End;

{ --- Al Borrar un Nodo por la Derecha entonces crece la izquierda --- }
Procedure Equilibrar_D(Var N:PosicionArbol; Var bh: Boolean);
Var N1: PosicionArbol;
Begin
Case N^.fe Of
1: N^.fe:= 0;
0: Begin
N^.fe:= -1;
bh:= False;
End;
-1: Begin


Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2
N1:= N^.hi;
If N1^.fe <= 0 Then Begin
If N1^.fe = 0 Then bh:= false;
R_II(N, N1);
End
Else R_ID(N, N1);
End;
End;
End;


Function EliminarNodoAVL(Var A: Arbol; X: Tipoelemento; ComparaPor:CampoComparar):
Boolean;
Var bh: Boolean;

Procedure Eliminar(Var R: PosicionArbol; Var bh: Boolean);
Var Q: PosicionArbol;
{ Busca el Nodo a Reemplazar Todo por la Izquierda}
Procedure B_N_R(Var P: PosicionArbol; Var bh: Boolean);
Begin
If P^.hi <> Nulo Then Begin
B_N_R(P^.hi, bh);
If bh = True Then Equilibrar_I(P, bh);
End
Else Begin
Q^.Datos := P^.Datos;
Q := P;
P := P^.hd;
bh:= True;
End;
End;

{ Aqui Comienza el procedure Eliminar }
Begin
If Not(RamaNula(R)) Then
If CompararTE(X, R^.Datos, ComparaPor) = menor Then Begin
Eliminar(R^.hi, bh);
If bh Then Equilibrar_I(R, bh);
End
Else
If CompararTE(X, R^.Datos, ComparaPor) = mayor Then Begin
Eliminar(R^.hd, bh);
If bh Then Equilibrar_D(R, bh);
End
Else Begin
Q := R;
If Q^.hd = Nulo Then Begin
R := Q^.hi;
bh:= True;
End
Else If Q^.hi = Nulo Then Begin
R := Q^.hd;
bh:= True;
End
Else Begin
B_N_R(Q^.hd, bh);
If bh Then Equilibrar_D(R, bh);
End;
Dispose(Q);
End;
End;


Profesores: Carlos Rodriguez, Mario Perello, Jose Racker
Lic. en Sistemas de Informacin
Programacin 2
Begin
EliminarNodoAVL := False;
Eliminar(A.raiz, bh);
EliminarNodoAVL := True;
End;

End.

S-ar putea să vă placă și