You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

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ä.

//============================================================================
// 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;
}

  • No labels
You must log in to comment.