Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0
Wiki Markup
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}