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).
Code Block |
---|
//============================================================================
// 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 Block |
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).
|