...
Linkitetty
...
lista
...
on
...
tietorakenne,
...
jossa
...
listan
...
jäsenet
...
tietävät
...
seuraavan
...
listan
...
jäsenen
...
(yhteen
...
suuntaan
...
linkitetty
...
lista)
...
tai
...
vaihtoehtoisesti
...
edellisen
...
ja
...
seuraavan
...
jäsenen
...
listassa
...
(kahteen
...
suuntaan
...
linkitetty
...
lista).
...
Koodissa
...
on
...
vähän
...
sekoitettu
...
C:tä
...
ja
...
C++,
...
mutta
...
älä
...
anna
...
sen
...
häiritä.
Code Block |
---|
{code} //============================================================================ // Name : LinkitettyLista.cpp // Author : jes // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #define DATATIEDOSTO "tietoll.dat" using namespace std; void valikko(); struct Kaverit //Tietueen kuvaus { char Nimi[50]; char Osoite[50]; char PuhNo[50]; Kaverit *pSeuraava; //osoitin seuraavaan tietueeseen }; int KokoTiedostonKirjoitusLevylle(Kaverit *pEnsimmainen); void TiedostonLukuLevylta(Kaverit **ppListanAlku, Kaverit **ppListanLoppu); void TalletaListaan(Kaverit *pUusi, //uusi tieto listaan Kaverit **ppListanAlku, //osoitin listan alkuun Kaverit **ppListanLoppu);//osoitin listan loppuun void TuhoaTietue(Kaverit *pEdellinen, Kaverit *pTuhottava, Kaverit **ppAlku, Kaverit **ppLoppu); Kaverit *EtsiNimella(Kaverit *pAlku,Kaverit **ppEdellinen, char *pEtsittavaNimi); Kaverit *HaeNimella(Kaverit *pAlku,Kaverit **pEdellinen); void NaytaTietueetJarjestyksessa(Kaverit *pAlku); void TietueidenTaytto(Kaverit *pUusi,Kaverit **ppListanAlku, Kaverit **ppListanLoppu); int Debug=1;// int main() { int apu; int valitsin = '1'; Kaverit *pUusi=NULL,*pTietue=NULL; Kaverit *pEdellinen=NULL, *pAlku=NULL,*pLoppu=NULL; TiedostonLukuLevylta(&pAlku,&pLoppu); for (;;) {valikko(); cin >>valitsin; switch (valitsin) { case 0: /*free(pTutut);*/ exit(1); break; case 1: pUusi=new Kaverit; TietueidenTaytto(pUusi,&pAlku,&pLoppu); KokoTiedostonKirjoitusLevylle(pAlku); break; case 2: pTietue=pAlku; pTietue=HaeNimella(pTietue,&pEdellinen); //printf("\n %s %s %s ", // pTietue->Nimi,pTietue->Osoite,pTietue->PuhNo); //cin>>apu; break; case 3: NaytaTietueetJarjestyksessa(pAlku); break; case 4: pTietue=pAlku; pTietue=HaeNimella(pTietue,&pEdellinen); if(pTietue!=NULL) { if(Debug==1) cout<<"\nAion tuhota tietueen"; TuhoaTietue( pEdellinen, pTietue, &pAlku, &pLoppu); KokoTiedostonKirjoitusLevylle(pAlku); } else { cout<<"EI TUHOTTAVAA"; //cin>>apu; } break; } } } void TietueidenTaytto(Kaverit *pUusi, Kaverit **ppListanAlku,Kaverit **ppListanLoppu) { //system("cls"); cout<<"\nAnna kaverin nimi max. 50 kirjainta "; cin>>pUusi->Nimi; cout<<"\nAnna kaverin osoite max. 50 kirjainta"; cin>>pUusi->Osoite; cout<<"\nAnna kaverin puh.no max. 50 kirjainta"; cin>>pUusi->PuhNo; TalletaListaan( pUusi, ppListanAlku, ppListanLoppu); } void valikko(void) { //clrscr(); cout<<"\n\n\n"; cout<<"\n 0........Lopetus"; cout<<"\n 1........Tietojen taytto tietokantaan"; cout<<"\n 2........Haku nimell ja tietojen nytt"; cout<<"\n 3........Kaikkien tietojen nytt"; cout<<"\n 4........Halutun tietueen tuhoaminen"; } /****************************************************************** Funktion nimi HaeNimella Paluuarvo : Kaverit tyyppi oleva osoitin Parametrit: 1. Kaverit tyyppi oleva osoitin, joka osoittaa linkitetyn listan ensimmiseen elementtiin 2. Kaverit tyyppinen osoitin, osoittimeen Kaverit. Parametri tytyy vlitt nin, jotta kutsuva ohjelma "nkisi" tietueosoittimen muutoksen. *******************************************************************/ Kaverit *HaeNimella(Kaverit *pAlku,Kaverit **ppEdellinen ) { char pEtsittavaNimi[50]; Kaverit *pEtsittava; cout<<"\nAnna etsittvn nimi"; cin>>pEtsittavaNimi; pEtsittava = EtsiNimella(pAlku, ppEdellinen,pEtsittavaNimi); if(pEtsittava!=NULL) cout << pEtsittava->Nimi <<" "<< pEtsittava->Osoite<<" "<<pEtsittava->PuhNo; return pEtsittava; } //tietueet sisltvn tiedoston luku void TiedostonLukuLevylta(Kaverit **ppListanAlku, Kaverit **ppListanLoppu) { FILE *Tiedosto; int iLukum=0; //esitellaan paikallinen tietuemuuttuja Kaverit Henkilo,*pUusi; Tiedosto=fopen(DATATIEDOSTO,"rb"); if(Tiedosto==NULL) { cout<<"tiedostoa ei ole"; return ; } do {//luetaan levylta yksi tietue muuttujaan henkilo iLukum=fread(&Henkilo,sizeof(Kaverit),1,Tiedosto); if(iLukum==1) { pUusi = new Kaverit; *pUusi=Henkilo; TalletaListaan( pUusi, ppListanAlku, ppListanLoppu); } }while (iLukum==1); fclose(Tiedosto); return ; } /******************************************************************* kaikkien tietueiden yhtaikainen kirjoitus levylle funktio ottaa parametreikseen ensimmisen tietueen osoitteen, sek talletettavien tietueiden mrn *******************************************************************/ int KokoTiedostonKirjoitusLevylle(Kaverit *pEnsimmainen) { int apu; FILE *Tiedosto; int iLukum=0; Tiedosto=fopen(DATATIEDOSTO,"wb"); if(Tiedosto==NULL) { printf("\nTiedosto ei aukea kirjoitettavaksi"); //cin>>apu; return iLukum; } iLukum=fwrite(pEnsimmainen,sizeof(struct Kaverit),1,Tiedosto); pEnsimmainen=pEnsimmainen->pSeuraava; fclose(Tiedosto); Tiedosto=fopen(DATATIEDOSTO,"ab"); if(Tiedosto==NULL) { cout<<"Tiedosto ei aukea kirjoitettavaksi"; //cin>>apu; return iLukum; } while(pEnsimmainen) { iLukum=fwrite(pEnsimmainen,sizeof(struct Kaverit),1,Tiedosto); pEnsimmainen=pEnsimmainen->pSeuraava; } if(iLukum!=1) { cout<<"Uuden tietueen kirjoitus ei onnistu"; //cin>>apu; exit(1); } fclose(Tiedosto); return iLukum; } /******************************************************************* Funktio tallettaa uuden tietueen listassa oikeaan paikkaan *******************************************************************/ void TalletaListaan(Kaverit *pUusi, //uusi tieto listaan Kaverit **ppListanAlku, //osoitin listan alkuun Kaverit **ppListanLoppu)//osoitin listan loppuun { int apu; Kaverit *pVanha, *pTemp; pTemp = *ppListanAlku; if(!*ppListanLoppu)//viimeist ei ole { pUusi->pSeuraava = NULL; *ppListanLoppu = pUusi; *ppListanAlku = pUusi; if(Debug==1) { cout<<"\nEnsimminen"; cout<<"\nAlku" <<(*ppListanAlku)->Nimi; cout<<"\n Uusi "<<pUusi->Nimi; cout<<"\nLoppu "<<(*ppListanLoppu)->Nimi; //cin>>apu; } return; } pVanha= NULL; while(pTemp) { if(strcmp(pTemp->Nimi, pUusi->Nimi)<0) { pVanha = pTemp; pTemp = pTemp->pSeuraava; } else { if (pVanha) { pVanha->pSeuraava = pUusi; pUusi->pSeuraava = pTemp; if(Debug==1) { cout<<"Valiin"; cout<<"\nAlku "<<(*ppListanAlku)->Nimi; cout<<" Uusi "<<pUusi->Nimi; cout<<" Loppu "<<(*ppListanLoppu)->Nimi; //cin>>apu; } return; } pUusi->pSeuraava =pTemp;//uusi ensimminen elementti *ppListanAlku=pUusi; if(Debug==1) { cout<<"\nAlkuun"; cout<<"\nAlku "<<(*ppListanAlku)->Nimi; cout<<" Uusi "<<pUusi->Nimi; cout<<" Loppu "<<(*ppListanLoppu)->Nimi; //cin>>apu; } return; } } (*ppListanLoppu)->pSeuraava=pUusi;//laitetaan listan loppuun pUusi->pSeuraava=NULL;//"maadoitetaan loppu" *ppListanLoppu= pUusi; if(Debug==1) { cout<<"\nLoppuun"; cout<<"\nAlku ",(*ppListanAlku)->Nimi; cout<<" Uusi "<<pUusi->Nimi; cout<<" Loppu "<<(*ppListanLoppu)->Nimi; //cin>>apu; } } /******************************************************************* *******************************************************************/ void NaytaTietueetJarjestyksessa(Kaverit *pAlku) { int apu; // clrscr(); cout<<"\nNimi Osoite Puhelin "; while(pAlku) { cout<< "\n"<<pAlku->Nimi<<" "<<pAlku->Osoite<<" "<<pAlku->PuhNo; //siirretn osoitin seuraavaan tietueeseen pAlku=pAlku->pSeuraava; } //cout<<"\nPAINA ENTER"; //cin>>apu; } /************************************************************ Funktio etsii listasta nime vastaavan tietueen Huom! Funktio EI MUUTA pAlku osoittimen paikkaa Funktio palauttaa etsityn tietueen osoitteen *************************************************************/ Kaverit *EtsiNimella(Kaverit *pAlku, Kaverit **ppEdellinen ,char *pEtsittavaNimi) { while(pAlku) { if (!strcmp(pEtsittavaNimi,pAlku->Nimi)) return pAlku; //Siirretaan nykyinen edelliseksi *ppEdellinen=pAlku; // pAlku=pAlku->pSeuraava; } if(Debug==1){cout<<"Ei loydy";} return NULL; //ei lytynyt } /******************************************************************* *******************************************************************/ void TuhoaTietue(Kaverit *pEdellinen, Kaverit *pTuhottava, Kaverit **ppAlku, Kaverit **ppLoppu) { if(pEdellinen) pEdellinen->pSeuraava= pTuhottava->pSeuraava; else *ppAlku=pTuhottava->pSeuraava; if(pTuhottava==*ppLoppu && pEdellinen) *ppLoppu =pEdellinen; delete pTuhottava; } {code} |