UNIT uConjunto;
INTERFACE
USES uElem;
TYPE
TConjunto = ^TNodo;
TNodo = RECORD
info:TElem;
sig:TConjunto;
END;
PROCEDURE CrearConjuntoVacio (VAR conj:TConjunto);
PROCEDURE Poner (VAR conj:TConjunto; elem:TElem);
PROCEDURE Eliminar (VAR conj:TConjunto);
PROCEDURE Quitar (VAR conj:TConjunto; elem:TElem);
FUNCTION Pertenece (conj:TConjunto; elem:TElem):boolean;
PROCEDURE Union (conj1,conj2:TConjunto; VAR conjUnido:TConjunto);
FUNCTION EsSubconjunto (conj1,conj2:TConjunto):boolean;
PROCEDURE Interseccion (conj1,conj2:TConjunto; VAR conjInter:TConjunto);
PROCEDURE Diferencia (conj1,conj2:TConjunto; VAR conjDifer:TConjunto);
FUNCTION EsConjuntoVacio (conj:TConjunto):boolean;
IMPLEMENTATION
PROCEDURE CrearConjuntoVacio (VAR conj:TConjunto);
BEGIN
conj := NIL;
END;{CrearListaVacia}
PROCEDURE Poner (VAR conj:TConjunto; elem:TElem);
VAR
aux:TConjunto;
BEGIN
IF NOT(Pertenece(conj,elem)) THEN
BEGIN
new(aux);
Asignar(aux^.info,elem);
aux^.sig := conj;
conj := aux;
END;{IF}
END;{Poner}
PROCEDURE Eliminar (VAR conj:TConjunto);
VAR
aux:TConjunto;
BEGIN
IF NOT(EsConjuntoVacio(conj)) THEN
BEGIN
aux := conj;
conj := conj^.sig;
dispose(aux);
END;{IF}
END;{Eliminar}
PROCEDURE Quitar (VAR conj:TConjunto; elem:TElem);
VAR
ant,act:TConjunto;
BEGIN
ant := NIL;
act := conj;
WHILE NOT(EsConjuntoVacio(act)) AND NOT(Iguales(act^.info , elem)) DO
BEGIN
ant := act;
act := act^.sig;
END;{WHILE}
IF act<>NIL THEN
IF ant = NIL THEN
Eliminar(conj)
ELSE
IF (act<>NIL) AND (ant<>NIL) THEN
BEGIN
ant^.sig := act^.sig;
dispose(act);
END;{IF}
END;{Quitar}
FUNCTION Pertenece (conj:TConjunto; elem:TElem):boolean;
VAR
check:boolean;
BEGIN
check := FALSE;
IF NOT(EsConjuntoVacio(conj)) THEN
BEGIN
WHILE NOT(EsConjuntoVacio(conj)) AND (check=FALSE) DO
BEGIN
check := Iguales(conj^.info , elem);
conj := conj^.sig;
END;{WHILE}
END;{IF}
Pertenece := check;
END;{Pertenece}
PROCEDURE Union (conj1,conj2:TConjunto; VAR conjUnido:TConjunto);
VAR
puntAuxi,aux:TConjunto;
BEGIN
CrearConjuntoVacio(conjUnido);
puntAuxi := conj1;
WHILE NOT(EsConjuntoVacio(conj1)) DO
BEGIN
new(aux);
Asignar(aux^.info , conj1^.info);
aux^.sig := NIL;
IF EsConjuntoVacio(conjUnido) THEN
BEGIN
conjUnido := aux;
puntAuxi := aux;
END{IF}
ELSE
BEGIN
puntAuxi^.sig := aux;
puntAuxi := aux;
END;{ELSE}
conj1 := conj1^.sig;
END;{WHILE}
puntAuxi^.sig := conj2;
WHILE NOT(EsConjuntoVacio(conj2)) DO
BEGIN
IF NOT Pertenece(conjUnido , conj2^.info) THEN
new(aux);
Asignar(aux^.info , conj2^.info);
aux^.sig := NIL;
IF EsConjuntoVacio(conjUnido) THEN
BEGIN
conjUnido := aux;
puntAuxi := aux;
END{IF}
ELSE
BEGIN
puntAuxi^.sig := aux;
puntAuxi := aux;
END;{ELSE}
conj2 := conj2^.sig;
END;{WHILE}
END;{Union}
FUNCTION EsSubconjunto (conj1,conj2:TConjunto):boolean;
VAR
check:boolean;
BEGIN
check := TRUE;
WHILE NOT(EsConjuntoVacio(conj1)) AND (check = TRUE) DO
BEGIN
check := Pertenece(conj2 , conj1^.info);
conj1 := conj1^.sig;
END;{WHILE}
EsSubconjunto := check;
END;{EsSubconjunto}
PROCEDURE Interseccion (conj1,conj2:TConjunto; VAR conjInter:TConjunto);
BEGIN
CrearConjuntoVacio(conjInter);
WHILE NOT(EsConjuntoVacio(conj1)) DO
BEGIN
IF Pertenece(conj2 , conj1^.info) THEN
Poner(conjInter,conj1^.info);
conj1 := conj1^.sig;
END;{WHILE}
END;{Interseccion}
PROCEDURE Diferencia (conj1,conj2:TConjunto; VAR conjDifer:TConjunto);
BEGIN
CrearConjuntoVacio(conjDifer);
WHILE NOT(EsConjuntoVacio(conj1)) DO {Yo creo que esto está mal, que se necesita un puntero auxiliar apuntando a conj1 para hacer el primer while ya que si no se pierde "el mango de la sartén" de conj1 dentro del subprograma y luego, al hacer si conj2^.info pertenece en conj1, no se hace correctamente}
BEGIN
IF NOT( Pertenece(conj2 , conj1^.info) ) THEN
Poner(conjDifer,conj1^.info);
conj1 := conj1^.sig;
END;{WHILE}
WHILE NOT(EsConjuntoVacio(conj2)) DO
BEGIN
IF NOT( Pertenece(conj1 , conj2^.info) ) THEN
Poner(conjDifer,conj2^.info);
conj2 := conj2^.sig;
END;{WHILE}
END;{Diferencia}
FUNCTION EsConjuntoVacio (conj:TConjunto):boolean;
BEGIN
EsConjuntoVacio := (conj = NIL);
END;{EsConjuntoVacio}
END.