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