-- MODULO DE IMPLEMENTACION DEL TAD 'diccionario',
-- ALMACENADO EN UN ARBOL 2-3 (ARBOL B DE GRADO 3)
--
-- Version: 3.0
-- Fecha: 15-I-04
-- Autor: Javier Campos Laclaustra (jcampos@unizar.es)
-- Cambios: se ha corregido un error en la línea 177
with ada.text_io, unchecked_deallocation;
use ada.text_io;
package body arbol_23 is
procedure disponer is new unchecked_deallocation(nodo,ptNodo);
procedure vacio(a:out a23) is
begin
a.numclaves:=0;
a.nodos:=null;
end vacio;
procedure busca_rec(p:in ptNodo; clave:in tp_clave;
exito:out boolean; valor:out tp_valor) is
-- es la búsqueda en el arbol
-- (la pongo aquí porque se usa también en "=")
begin
if p.tipo=hoja then
if clave=p.clave then --clave encontrada
exito:=true;
valor:=p.valor;
else --clave no encontrada
exito:=false;
end if;
else --p.tipo=interior
if clave
0 then --caso contrario el diccionario sigue vacío
if a.numclaves=1 then --el diccionario es una sola hoja
if a.nodos.clave=clave then --hay que borrarla
disponer(a.nodos);
a.nodos:=null;
a.numclaves:=0;
end if;
else --el diccionario tiene más de un elemento
borra_rec(a.nodos,clave,unHijo,menor,hayBorrado);
if hayBorrado then
a.numclaves:=a.numclaves-1;
end if;
if unHijo then --la raíz sólo tiene un hijo;
--hay que eliminar la raíz
pAux:=a.nodos;
a.nodos:=a.nodos.pri;
disponer(pAux);
end if;
end if;
end if;
end borrar;
function es_vacio(a:a23) return boolean is
begin
return a.numclaves=0;
end es_vacio;
procedure asignar(aout:out a23; ain:in a23) is
procedure asignar_rec(pout:out ptNodo; pin:in ptNodo) is
a1,a2,a3:ptNodo;
begin
if pin=null then --es vacío
pout:=null;
elsif pin.tipo=hoja then --un solo nodo
pout:=new nodo'(hoja,pin.clave,pin.valor);
else --la raíz 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
aout.numclaves:=ain.numclaves;
asignar_rec(aout.nodos,ain.nodos);
end asignar;
function "="(a1,a2:in a23) return boolean is
function incluido(p1,p2: ptNodo) return boolean is
--devuelve verdad si y sólo si todas las claves de p1 están
--en p2 (con iguales valores)
valor:tp_valor; exito,aux:boolean;
begin
if p1=null then
return true; --trivialmente
elsif p1.tipo=hoja then
busca_rec(p2,p1.clave,exito,valor);
return exito and then valor=p1.valor; --sólo hay una clave en
--p1 y está 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 a1.numclaves/=a2.numclaves then
return false;
else
return incluido(a1.nodos,a2.nodos);
end if;
end "=";
procedure liberar(a:in out a23) is
procedure liberar_rec(p:in out ptNodo) is
begin
if p/=null then --hay algo que liberar
if p.tipo=hoja then --sólo una hoja
disponer(p);
p:=null;
else --la raíz 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(a.nodos);
a.numclaves:=0;
end liberar;
procedure listado(a:in a23) 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_clave(p.clave);
put(": ");
put_valor(p.valor);
new_line;
else
listado_rec(p.pri);
listado_rec(p.seg);
listado_rec(p.ter);
end if;
end if;
end listado_rec;
begin
listado_rec(a.nodos);
end listado;
end arbol_23;