
Stian Søiland, IT 112, øvingsgruppe 15 (stud.ass. Helle Haugenes)
unit telefonkatalog;
// Abstrakt datatype-enhet for telefonkatalog
// ADTen oppretter og vedlikeholder en telefonkatalog.
// Vi antar på forhånd at det alltid vil finnes bare ett telefonnummer
// til hvert navn, og kun en oppf¢ring av hvert navn.
// Vi antar også, noe naivt, at ingen har samme telefonnummer.
// offentlig del av ADT
interface
// Antall siffer i telefonnummer. Antas alltid brukt, dvs. ingen
// telefonnummer har verken FÆRRE eller FLERE siffer enn dette.
const sifferitelefonnummer = 8;
type
// Typedeklarasjon for navn. Indre formattering med hensyn til fornavn,
// etternavn, etc. defineres ikke av ADT.
navntype = string;
// Typedeklarasjon for telefonnummer. Konstanten sifferitelefonnummer er
// gitt tidligere i enheten.
nummertype = string[sifferitelefonnummer];
// Typedeklarasjoner for lenket resultatliste med navn og nummer
oppforingpeker = ^oppforing;
oppforing = record
navn : navntype;
nummer : nummertype;
neste : oppforingpeker;
end;
// Prosedyren initier oppretter telefonkatalogen, resultat er sann ved
// suksess.
procedure initier(var resultat:boolean);
// Prosedyren legginn legger til oppf¢ring med navn og nummer til
// telefonkatalogen og resultat er sann hvis prosedyren var vellykket.
// Dersom en oppf¢ring med 'navn' finnes fra f¢r vil prosedyren
// feile og resultat blir negativt.
procedure legginn(navn:navntype; nummer:nummertype;
var resultat:boolean);
// Prosedyren finnnummer returnerer telefonnummeret til navn. Navnet
// må være fullstendig. Resultat er sann dersom navnet ble funnet,
// i alle andre tilfeller er den usann.
procedure finnnummer(navn:navntype; var nummer:nummertype;
var resultat:boolean);
// Prosedyren finntelefonnummer returnerer det
// navnet som har telefonnummer likt nummer. Nummeret må
// være fullstendig. Resultat er sann dersom nummeret ble funnet,
// i alle andre tilfeller er den usann.
procedure finnnavn(nummer:nummertype;var navn:navntype;
var resultat:boolean);
// Prosedyren slettnavn sletter oppf¢ringen med det gitte navnet.
// Resultat er sann hvis prosedyren usann og navnet ble funnet,
// er navnet ikke oppf¢rt, er resultat usann.
procedure slettnavn(navn:navntype; var resultat:boolean);
// Prosedyren listalle returnerer en peker til en lenket liste,
// alfabetisk sortert etter navn, over alle oppf¢ringene i
// telefonkatalogen. Resultat er sann dersom listingen er vellykket.
procedure listalle(var resultatliste:oppforingpeker;
var resultat:boolean);
// Privat del av ADT
implementation
// Global variabel hode for å holde fast i den lenkede listen som utgj¢r
// telefonkatalogen. Bruker samme datatype som listalles resultatliste.
// Den lenkede listen er usortert.
var hode:oppforingpeker;
// Oppretter telefonkatalogen. Eventuelle eksisterende
// noder i den lenkede listen blir slettet.
// Hode-parameteren blir nullstilt i initialization-delen av
// enheten slik at den aldri vil peke til en ikkeeksisterende
// dynamisk variabel.
procedure initier(var resultat:boolean);
var temp:oppforingpeker;
begin
if hode <> nil then
begin
temp := hode;
hode := hode^.neste;
dispose(temp);
// rekursivt kall
initier(resultat);
end
else
// degenerert tilfelle
begin
resultat := true;
end;
end; // slutt initier
// Funksjonen posisjonnavn returnerer en peker til noden i den
// lenkede listen som er F¥R navn. Dersom navn ikke er oppf¢rt
// vil pekeren være NIL.
function posisjonnavn(posisjon:oppforingpeker;
navn:navntype):oppforingpeker;
begin
if (posisjon = nil) or (posisjon^.navn <> navn) then
begin
// rekursivt kall
posisjonnavn := posisjonnavn(posisjon^.neste,navn);
end
else
begin
// degenrert tilfelle
posisjonnavn := posisjon;
end;
end; // slutt posisjonnavn
// Funksjonen posisjonnummer returnerer en peker til noden i den
// lenkede listen som er F¥R nummer. Dersom nummer ikke er oppf¢rt
// vil pekeren være NIL.
function posisjonnummer(posisjon:oppforingpeker;
nummer:nummertype):oppforingpeker;
begin
if (posisjon = nil) or (posisjon^.nummer <> nummer) then
begin
// rekursivt kall
posisjonnummer := posisjonnummer(posisjon^.neste,nummer);
end
else
begin
// degenrert tilfelle
posisjonnummer := posisjon;
end;
end; // slutt posisjonnavn
procedure legginn(navn:navntype; nummer:nummertype;
var resultat:boolean);
// Prosedyre for å lage ny node
procedure nynode;
var temp:oppforingpeker;
// Lager ny node i begynnelsen av den lenkede listen
begin
new(temp);
temp^.neste := hode;
hode := temp;
end; // slutt nynode
begin
// Sjekker om navn eller nummer finnes fra f¢r i listen
if (posisjonnavn(hode,navn) <> nil) or
(posisjonnummer(hode,nummer) <> nil) then
begin
nynode;
hode^.navn := navn;
hode^.nummer := nummer;
resultat := true;
end
else
begin
// Navnet eller nummeret fantes fra f¢r, kunne ikke legge til
resultat := false;
end;
end; // slutt legginn
procedure slettnavn(navn:navntype; var resultat:boolean);
var temp1,temp2:oppforingpeker;
begin
temp1 := posisjonnavn(hode,navn);
if temp1 <> nil then
begin
temp2 := temp1^.neste;
// Linker forbi noden som skal slettes
temp1^.neste := temp2^.neste;
dispose(temp2);
resultat := true;
end
else
begin
// Navnet fantes ikke, kunne ikke slette
resultat := false;
end;
end; // slutt slettnavn
procedure finnnummer(navn:navntype; var nummer:nummertype;
var resultat:boolean);
var temp:oppforingpeker;
begin
temp := posisjonnavn(hode,navn);
if temp <> nil then
begin
// Returnerer telefonnummeret
nummer := temp^.neste^.nummer;
resultat := true;
end
else
begin
// Navnet fantes ikke, nummer kan ikke returneres
resultat := false;
end;
end; // slutt finnnummer
procedure finnnavn(nummer:nummertype; var navn:navntype;
var resultat:boolean);
var temp:oppforingpeker;
begin
temp := posisjonnummer(hode,navn);
if temp <> nil then
begin
// Returnerer navnet
navn := temp^.neste^.navn;
resultat := true;
end
else
begin
// Nummeret fantes ikke, navnet kan ikke returneres
resultat := false;
end;
end; // slutt finnnavn
procedure listalle(var resultatliste:oppforingpeker;
var resultat:boolean);
function posisjon(navn:navntype; listehode:oppforingpeker):oppforingpeker;
begin
if listehode <> nil and listehode^.navn > navn then
begin
// rekursivt kall
posisjon := posisjon(navn,listehode^.neste);
end;
else
begin
// Degenerert tilfelle
posisjon := listehode;
end;
end;
procedure settinn(navn:navntype; nummer:nummertype;
var listehode:oppforingpeker);
var temp:oppforingpeker;
begin
new(temp);
temp^.navn := navn;
temp^.nummer := nummer;
temp^.neste := listehode;
listehode := temp;
end;
function sorter(gammel,ny:oppforingpeker):oppforingpeker;
var temp:oppforingpeker;
begin
if gammel <> nil then
begin
settinn(gammel^.navn,gammel^.nummer,posisjon(gammel^.navn,ny));
sorter := sorter(gammel^.neste,ny);
end
else
begin
sorter := gammel;
end;
end; // slutt sorter
begin
resultatliste := sorter(hode,nil);
end; // slutt listalle
initialization
// Nullstiller global parameter hode
hode := nil;
end.