13 ABO_MOVIMIENTO = ( ABO_raiz, ABO_izquierda, ABO_derecha, ABO_padre );
\r
15 { Crea e inicializa el arbol }
\r
16 PROCEDURE ABO_crear( VAR a: ABO_ARBOL );
\r
17 { PRE: Arbol no creado }
\r
18 { POS: Arbol creado y vacio }
\r
20 { Se fija si el arbol esta vacio }
\r
21 FUNCTION ABO_vacio( a: ABO_ARBOL): BOOLEAN;
\r
22 { PRE: Arbol creado }
\r
23 { POS: Devuelve true si el arbol esta vacio, false si no lo esta }
\r
25 { Devuelve el elemento corriente }
\r
26 PROCEDURE ABO_elem_cte( a: ABO_ARBOL; VAR e: T_REGISTRO);
\r
27 { PRE: Arbol creado y no vacio }
\r
28 { POS: en e esta almacenado el elemento corriente }
\r
30 { Modifica el elemento corriente }
\r
31 PROCEDURE ABO_modif_cte( VAR a: ABO_ARBOL; e: T_REGISTRO; VAR error: boolean );
\r
32 { PRE: Arbol creado y no vacio }
\r
33 { POS: Si la clave del elemento modificado ya estaba en el arbol (sin contar el
\r
34 elemento a modificar), devuelve error = true y no modifica el arbol.
\r
35 Si no estaba en el arbol, error es false y se modifica el elemento corriente }
\r
37 { Moueve el elemento corriente }
\r
38 PROCEDURE ABO_mover_cte( VAR a: ABO_ARBOL; m: ABO_MOVIMIENTO; VAR error: BOOLEAN );
\r
39 { PRE: Arbol creado y no vacio }
\r
40 { POS: ABO_raiz: el corriente es el elemento raiz, error es false }
\r
41 { ABO_padre: si el corriente es el elemento raiz, error es true y el corriente no cambia }
\r
42 { ABO_izquierda: si el corriente no tiene un elemento a izquierda, error es true y el corriente no cambia }
\r
43 { si el corriente tiene un elemento a izquierda, error es false y el corriente cambia }
\r
44 { ABO_derecha: si el corriente no tiene un elemento a derecha, error es true y el corriente no cambia }
\r
45 { si el corriente tiene un elemento a derecha, error es false y el corriente cambia }
\r
47 { Borra el elemento corriente }
\r
48 PROCEDURE ABO_borrar_cte( VAR a: ABO_ARBOL );
\r
49 { PRE: Arbol creado y no vacio }
\r
50 { POS: el elemento corriente fue borrado y el corriente nuevo es la raiz }
\r
52 { Inserta el elemento e en el arbol }
\r
53 PROCEDURE ABO_insertar( VAR a: ABO_ARBOL; e: T_REGISTRO; VAR error: BOOLEAN );
\r
54 { PRE: Arbol creado }
\r
55 { POS: si la clave del elemento e no estaba en el arbol, el registro e se inserto y error es false,
\r
56 si la clave del elemento estaba en el arbol, el registro no se inserto y error es true }
\r
59 PROCEDURE ABO_vaciar( VAR a: ABO_ARBOL );
\r
60 { PRE: Arbol creado }
\r
61 { POS: El arbol esta vacio }
\r
63 { Copia el arbol a en el b }
\r
64 PROCEDURE ABO_copiar( a: ABO_ARBOL; VAR b: ABO_ARBOL );
\r
65 { PRE: Arbol a creado y no vacio, arbol b creado }
\r
66 { POS: el arbol b es una copia del arbol a }
\r
68 { Busca el elemento con la clave c en el arbol }
\r
69 PROCEDURE ABO_buscar( var a: ABO_ARBOL; c: T_CLAVE; VAR error: boolean );
\r
70 { PRE: Arbol creado y no vacio }
\r
71 { POS: si habia un elemento con la clave c en el arbol, error es false y el elemento corriente es el de clave c
\r
72 si no habia un elemento con la clave c en el arbol, error es true y el elemento corriente no cambia }
\r
76 {-----------------------------------}
\r
77 { Funciones "privadas" de la unidad }
\r
78 {-----------------------------------}
\r
80 { Convierte un movimiento del ABO a uno del AB, para mantener los tipos abstractos }
\r
81 FUNCTION movABO2AB( m: ABO_MOVIMIENTO ): AB_MOVIMIENTO;
\r
86 movABO2AB := AB_raiz;
\r
88 ABO_izquierda: begin
\r
89 movABO2AB := AB_izquierda;
\r
92 movABO2AB := AB_derecha;
\r
95 movABO2AB := AB_padre;
\r
101 {-----------------------------------}
\r
102 { Funciones "públicas" de la unidad }
\r
103 {-----------------------------------}
\r
105 PROCEDURE ABO_crear( VAR a: ABO_ARBOL );
\r
108 AB_crear( a.arbol );
\r
109 end; { Procedimiento o Función }
\r
112 FUNCTION ABO_vacio( a: ABO_ARBOL ): BOOLEAN;
\r
115 ABO_vacio := AB_vacio( a.arbol );
\r
116 end; { Procedimiento o Función }
\r
119 PROCEDURE ABO_elem_cte( a: ABO_ARBOL; VAR e: T_REGISTRO );
\r
122 AB_elem_cte( a.arbol, e );
\r
123 end; { Procedimiento o Función }
\r
125 { error es true si se modifica a una clave que ya existia }
\r
126 PROCEDURE ABO_modif_cte( VAR a: ABO_ARBOL; e: T_REGISTRO; VAR error: boolean );
\r
132 ABO_elem_cte( a, r );
\r
133 if ( T_GRAL_Devolver_Clave_Elem( r ) = T_GRAL_Devolver_Clave_Elem( e ) ) then { si la clave no cambia }
\r
134 AB_modif_cte( a.arbol, e ) { se modifica con la primitiva de AB }
\r
135 else begin { Si la clave cambia ... }
\r
136 ABO_borrar_cte( a ); { Borra el corriente }
\r
137 ABO_insertar( a, e, error ); { Inserta el nuevo elemento }
\r
139 end; { Procedimiento o Función }
\r
142 PROCEDURE ABO_mover_cte( VAR a: ABO_ARBOL; m: ABO_MOVIMIENTO; VAR error: BOOLEAN );
\r
145 AB_mover_cte( a.arbol, movABO2AB( m ), error );
\r
146 end; { Procedimiento o Función }
\r
149 PROCEDURE ABO_borrar_cte( VAR a: ABO_ARBOL );
\r
150 PROCEDURE insertar_rama_de_ABO_a_ABO( VAR origen: ABO_ARBOL; VAR destino: ABO_ARBOL );
\r
155 ABO_elem_cte( origen, r );
\r
156 ABO_insertar( destino, r, er ); { No debe haber error porque no hay ninguno repetido }
\r
157 ABO_mover_cte( origen, ABO_izquierda, er );
\r
158 if ( not er ) then begin
\r
159 insertar_rama_de_ABO_a_ABO( origen, destino );
\r
160 ABO_mover_cte( origen, ABO_padre, er );
\r
162 ABO_mover_cte( origen, ABO_derecha, er );
\r
163 if ( not er ) then begin
\r
164 insertar_rama_de_ABO_a_ABO( origen, destino );
\r
165 ABO_mover_cte( origen, ABO_padre, er );
\r
177 AB_elem_cte( a.arbol, ro ); { obtengo el elemento corriente }
\r
178 ABO_crear( abo ); {}
\r
179 AB_mover_cte( a.arbol, AB_izquierda, er ); {}
\r
180 if ( not er ) then begin {}
\r
181 insertar_rama_de_ABO_a_ABO( a, abo ); {}
\r
182 AB_mover_cte( a.arbol, AB_padre, er ); { Copia todos los registros de las subramas }
\r
183 end; { del registro a borrar en un nuevo ABO }
\r
184 AB_mover_cte( a.arbol, AB_derecha, er ); { para luego insertarlos en el lugar del }
\r
185 if ( not er ) then begin { registro borrado }
\r
186 insertar_rama_de_ABO_a_ABO( a, abo ); {}
\r
187 AB_mover_cte( a.arbol, AB_padre, er ); {}
\r
189 { En este punto tengo todos los registros de la subrama en mi nuevo ABO }
\r
190 AB_mover_cte( a.arbol, AB_padre, er );
\r
191 if ( er ) then { es la raiz }
\r
192 AB_vaciar( a.arbol ) { se vacia el arbol entero }
\r
193 else begin { no es la raiz }
\r
194 AB_mover_cte( a.arbol, AB_izquierda, er ); { Ahora se fija si la subrama a borrar es la de }
\r
195 { la derecha o la de la izquierda (prueba la izquierda) }
\r
196 if ( er ) then { No hay un elemento a la izquierda }
\r
197 m := AB_derecha { Indica que hay que borrar la de la derecha }
\r
198 else begin { Hay un elemento a la izquierda }
\r
199 AB_elem_cte( a.arbol, rn ); { Extrae el elemento para compararlo con el que hay que borrar }
\r
200 if ( T_GRAL_Devolver_Clave_Elem( ro ) = T_GRAL_Devolver_Clave_Elem( rn ) ) then { si es la misma }
\r
201 m := AB_izquierda { Son iguales las claves entonces hay que borrar el de la izquierda }
\r
203 m := AB_derecha; { Son distintas las claves entonces hay que borrar el de la derecha }
\r
204 AB_mover_cte( a.arbol, AB_padre, er );
\r
206 AB_borrar_sub( a.arbol, m );
\r
208 { En este punto tengo borrada la rama con el elemento a borrar, }
\r
209 { solo queda insertar los elementos del ABO creado }
\r
210 if ( not ABO_vacio( abo ) ) then begin { Si no esta vacio }
\r
211 ABO_mover_cte( abo, ABO_raiz, er ); { Mueve el corriente a la raiz }
\r
212 insertar_rama_de_ABO_a_ABO( abo, a ); { Inserta la subrama almacenada en ABO en el arbol original }
\r
214 ABO_mover_cte( a, ABO_raiz, er ); { deja el corriente en la raiz }
\r
215 end; { Procedimiento o Función }
\r
218 PROCEDURE ABO_insertar( VAR a: ABO_ARBOL; e: T_REGISTRO; VAR error: BOOLEAN );
\r
219 FUNCTION buscar_lugar_desde_elem_cte( VAR a: ABO_ARBOL; e: T_REGISTRO ): AB_MOVIMIENTO;
\r
225 { devuelve AB_raiz si el elemento ya existe en el arbol
\r
226 devuelve AB_izquierda si hay que insertarlo a izquiera del corriente
\r
227 devuelve AB_derecha si hay que insertarlo a derecha del corriente }
\r
228 AB_elem_cte( a.arbol, r );
\r
229 if ( T_GRAL_Devolver_Clave_Elem( e ) = T_GRAL_Devolver_Clave_Elem( r ) ) then
\r
230 buscar_lugar_desde_elem_cte := AB_raiz
\r
232 if ( T_GRAL_Devolver_Clave_Elem( e ) < T_GRAL_Devolver_Clave_Elem( r ) ) then begin
\r
233 AB_mover_cte( a.arbol, AB_izquierda, er );
\r
235 buscar_lugar_desde_elem_cte := buscar_lugar_desde_elem_cte( a, e )
\r
237 buscar_lugar_desde_elem_cte := AB_izquierda;
\r
240 AB_mover_cte( a.arbol, AB_derecha, er );
\r
242 buscar_lugar_desde_elem_cte := buscar_lugar_desde_elem_cte( a, e )
\r
244 buscar_lugar_desde_elem_cte := AB_derecha;
\r
256 if ( AB_vacio( a.arbol ) ) then
\r
257 AB_insertar( a.arbol, AB_raiz, e, error )
\r
259 AB_mover_cte( a.arbol, AB_raiz, error );
\r
260 m := buscar_lugar_desde_elem_cte( a, e );
\r
261 if ( m <> AB_raiz ) then
\r
262 AB_insertar( a.arbol, m, e, error )
\r
266 end; { Procedimiento o Función }
\r
269 PROCEDURE ABO_vaciar( VAR a: ABO_ARBOL );
\r
272 AB_vaciar( a.arbol );
\r
273 end; { Procedimiento o Función }
\r
276 PROCEDURE ABO_copiar( a: ABO_ARBOL; VAR b: ABO_ARBOL );
\r
279 AB_copiar( a.arbol, b.arbol );
\r
280 end; { Procedimiento o Función }
\r
283 PROCEDURE ABO_buscar( var a: ABO_ARBOL; c: T_CLAVE; VAR error: boolean );
\r
284 { baja un nivel por el camino correcto y compara: }
\r
285 { c1 = c2 : Termina, error es false porque fue encontrada }
\r
286 { c1 > c2 : Se mueve a la derecha y llama al procedimiento recursivamente }
\r
287 { c1 < c2 : Se mueve a la izquierda y llama al procedimiento recursivamente }
\r
288 { Si hay movimiento y este da error, quiere decir que la clave no fue encontrada}
\r
289 { (se llego a una hoja, o "semihoja"). De esta forma devuelve error como true }
\r
290 PROCEDURE buscar( var a: ABO_ARBOL; c: T_CLAVE; VAR error: boolean );
\r
295 AB_elem_cte( a.arbol, e );
\r
296 co := T_GRAL_Devolver_Clave_Elem( e );
\r
301 AB_mover_cte( a.arbol, AB_izquierda, error )
\r
303 AB_mover_cte( a.arbol, AB_derecha, error );
\r
304 if ( not error ) then
\r
305 buscar( a, c, error );
\r
313 AB_elem_cte( a.arbol, r ); { Guarda el elemento corriente por si no se encuentra el buscado }
\r
314 AB_mover_cte( a.arbol, AB_raiz, error ); { Se mueve a la raiz }
\r
315 if ( not error ) then begin { Si no hubo error (no debería haberlo) ... }
\r
316 buscar( a, c, error ); { Comienza la busqueda }
\r
317 if ( error ) then begin { Si no se encontro la clave buscada ... }
\r
318 { Buscamos la clave original (nunca deberia devolver error = true porque sabemos que existe }
\r
319 ABO_buscar( a, T_GRAL_Devolver_Clave_Elem( r ), error );
\r
320 error := true; { Volvemos a poner error en true porque no se habia encontrado }
\r
321 end; { la clave deseada }
\r
323 end; { Procedimiento o Función }
\r