--|::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
--| Solucion practica 5 de EDA del curso 98/99 (modulo de implementacion)
--|::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
--| Version: 1.0
--| Fecha: 7-XII-98
--| Autor: Javier Campos
with ada.strings.unbounded, ustrings, unchecked_deallocation;
use ada.strings.unbounded, ustrings;
package body dicc is
-- type tipoNodo is (hoja,interior);
-- type nodo;
-- type ptNodo is access nodo;
-- type nodo(tipo:tipoNodo) is record
-- case tipo is
-- when hoja =>
-- clave:ustring;
-- info:ustring;
-- when interior =>
-- pri,seg,ter:ptNodo;
-- minseg,minter:ustring;
-- end case;
-- end record;
-- type diccionario is record
-- numpal:integer;
-- nodos:ptNodo;
-- end record;
procedure disponer is new unchecked_deallocation(nodo,ptNodo);
procedure vacio(d:out diccionario) is
begin
d.numpal:=0;
d.nodos:=null;
end vacio;
procedure busca_rec(p:in ptNodo; palabra:in ustring; definicion:out ustring) is
-- es la busqueda en el arbol (la pongo aqui porque se usa tambien en "=")
begin
if p.tipo=hoja then
if palabra=p.clave then --palabra encontrada
definicion:=p.info;
else --palabra no encontrada
definicion:=null_unbounded_string;
end if;
else --p.tipo=interior
if palabra
0 then --caso contrario el diccionario sigue vacio
if d.numpal=1 then --el diccionario es una sola hoja
if d.nodos.clave=palabra then --hay que borrarla
disponer(d.nodos);
d.nodos:=null;
d.numpal:=0;
end if;
else --el diccionario tiene mas de un elemento
borra_rec(d.nodos,palabra,unHijo,menor,hayBorrado);
if hayBorrado then
d.numpal:=d.numpal-1;
end if;
if unHijo then --la raiz solo tiene un hijo; hay que eliminar la raiz
pAux:=d.nodos;
d.nodos:=d.nodos.pri;
disponer(pAux);
end if;
end if;
end if;
end borra;
procedure asignar(dout:out diccionario; din:in diccionario) is
procedure asignar_rec(pout:out ptNodo; pin:in ptNodo) is
a1,a2,a3:ptNodo;
begin
if pin=null then --es vacio
pout:=null;
elsif pin.tipo=hoja then --un solo nodo
pout:=new nodo'(hoja,pin.clave,pin.info);
else --la raiz es un nodo interior
asignar_rec(a1,pin.pri);
asignar_rec(a2,pin.seg);
if pin.ter/=null then
asignar_rec(a3,pin.ter);
end if;
pout:=new nodo'(interior,a1,a2,a3,pin.minseg,pin.minter);
end if;
end asignar_rec;
begin
dout.numpal:=din.numpal;
asignar_rec(dout.nodos,din.nodos);
end asignar;
function "="(d1,d2:in diccionario) return boolean is
function incluido(p1,p2: ptNodo) return boolean is
--devuelve verdad si y solo si todas las palabras de p1 estan en p2 (con iguales def.)
def:ustring; aux:boolean;
begin
if p1=null then
return true; --trivialmente
elsif p1.tipo=hoja then
busca_rec(p2,p1.clave,def);
return def=p1.info; --solo hay una palabra en p1 y esta en p2
else --p1 es un nodo interior
aux:=incluido(p1.pri,p2);
if not aux then
return false;
else
aux:=incluido(p1.seg,p2);
if not aux then
return false;
elsif p1.ter/=null then
aux:=incluido(p1.ter,p2);
return aux;
else
return true;
end if;
end if;
end if;
end incluido;
begin
if d1.numpal/=d2.numpal then
return false;
else
return incluido(d1.nodos,d2.nodos);
end if;
end "=";
procedure liberar(d:in out diccionario) is
procedure liberar_rec(p:in out ptNodo) is
begin
if p/=null then --hay algo que liberar
if p.tipo=hoja then --solo una hoja
disponer(p);
p:=null;
else --la raiz es un nodo interior
liberar_rec(p.pri);
liberar_rec(p.seg);
liberar_rec(p.ter);
disponer(p);
p:=null;
end if;
end if;
end liberar_rec;
begin
liberar_rec(d.nodos);
d.numpal:=0;
end liberar;
procedure listado(d:in diccionario) is
procedure listado_rec(p:in ptNodo) is
begin
if p/=null then --hay algo que listar
if p.tipo=hoja then --un solo nodo
put_line(p.clave);
put_line(p.info);
else
listado_rec(p.pri);
listado_rec(p.seg);
listado_rec(p.ter);
end if;
end if;
end listado_rec;
begin
listado_rec(d.nodos);
end listado;
end dicc;