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;
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 //-----------------------------------------------------------
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;