Neusporiadaný lineárny zoznam (riešené príklady)

Z Kiwiki
Skočit na navigaci Skočit na vyhledávání
Imbox draft.png
Toto je projekt, na ktorom sa ešte stále pracuje!!

Aj keď sú v tomto dokumente použiteľné informácie, ešte nie je dokončený. Svoje návrhy môžete vyjadriť v diskusii o tejto stránke.

Algoritmy a programovanie - zbierka úloh


Štruktúry

Rekurzia

Dynamická alokácia pamäti

Vyhľadávanie

Triedenie

Lineárny zoznam

>Neusporiadaný lineárny zoznam
>Usporiadaný lineárny zoznam

Binárny strom

Numerické algoritmy

Zadanie

Vo vstupnom súbore máme zoznam študentov - v každom riadku sa nachádza meno, priezvisko, známka zo ZI, den, mesiac a rok narodenia. V poslednom riadku je 5 núl. Zostavte program, ktorý zo súboru načíta všetkých študentov a vytvorí lineárny zreťazený zoznam, ktorého jednotlivé prvky budú obsahovať údaje jedného riadku. Prvky do zoznamu na koniec zoznamu. Na konci zoznam vypíšte a zmažte.

Vzorový príklad

Vstup

Jan Mrkvicka A 4 6 1985
Ferdinand Tell C 4 12 1986
Viliam Tell F 1 1 1987
johanka Z_arku C 5 4 1238
0 0 0 0 0 0

Výstup

výpis zoznamu: je rovnaký ako vstupné dáta.

Analýza úlohy

Na reprezentáciu dát si vytvoríme štruktúry TDatum a TStudent, ktorá nám opisujú jedného študenta.

struct TDatum
{
  int d,m,y;
};
struct TStudent
{
  char meno[32],priezvisko[32];
  TDatum datum_narodenia;
  char znamka_ZI;
};

Príklad sa má riešiť pomocou lineárneho zoznamu. Vytvoríme si štruktúru TPrvok, ktorá bude jedným prvkom zoznamu.

struct TPrvok
{
   TStudent student;
   TPrvok *dalsi;
};

Nakoniec ešte potrebujeme samotnú štruktúru zoznam.

struct TZoznam
{
   TPrvok *prvy, *posledny;
};

Vo vstupnom súbore nám každý riadok reprezentuje jedného študenta. Takže budeme naraz načítavať všetky údaje v riadku a uložíme ich do patričných položiek štruktúry TStudent. Na načítavanie použijeme funkciu Nacitaj(TStudent &s,istream &vstup). Zaujímavý je druhý parameter, je to odkaz na vstupný prúd (istream) - môže to byť cin, alebo vlastný dátový prúd (súbor).

Pre výpis prvku môžeme použiť funkciu VypisPrvok(TPrvok *p), ktorá bude vypisovať obsah prvku p (p obsahuje štrukúru TStudent, ktorá obsahuje položky meno, priezvisko, datum a znamka_ZI)

V ukážke sú uvedené aj ďalšie funkcie, VlozNaKoniec (funkcia vloží prvok do zoznamu na koniec), PorovnajS2 (funkcia bude porovnávať podľa dátumu, priezviska, mena), Vypis (funkcia vypíše celý zoznam), Zmaz (funkcia zmaže zoznam) a ZmazPosledny (funkcia zmaže zo zoznamu posledný prvok)

Riešenie v jazyku C

  1 #include <iostream.h>
  2 #include <fstream.h>
  3 #include <string.h>
  4 //-----------------datove struktury-------------------//
  5 struct datum
  6     {    int d,m,y;
  7     };
  8 struct TStudent
  9     {    char meno[32],priezvisko[32];
 10         datum datum_narodenia;
 11         char znamka_ZI;
 12     };
 13 struct TPrvok
 14     {    TStudent student;
 15         TPrvok *dalsi;
 16     };     
 17 struct TZoznam
 18 {
 19   TPrvok *prvy, *posledny;
 20 };
 21 
 22 //-------------------funkcie-----------------------------//
 23 
 24 int JePrazdny(TZoznam z)
 25 {
 26   return z.prvy == NULL;
 27 }
 28 
 29 void VypisPrvok(TPrvok *p)
 30 {
 31     cout << p->student.priezvisko <<" "<<p->student.meno<<" ("<<p->student.znamka_ZI<<") ";
 32     cout<<p->student.datum_narodenia.d<<". "<<p->student.datum_narodenia.m<<". ";
 33     cout<<p->student.datum_narodenia.y<<endl;    
 34 }
 35 
 36 void Vypis(TZoznam z)
 37 {
 38   if (JePrazdny(z)) return;
 39   TPrvok *p = z.prvy;
 40   while (p->dalsi != NULL)
 41   {
 42     VypisPrvok(p);
 43     p = p->dalsi;
 44   }
 45   VypisPrvok(p);
 46 }
 47 
 48 void ZmazPosledny(TZoznam &z)
 49 {
 50   if (z.prvy == NULL)  // prazdny zoznam
 51     return;
 52 
 53   TPrvok *p = z.prvy;
 54   if (p->dalsi == NULL)  // je len jeden prvok
 55   {
 56     delete p;
 57     z.prvy = z.posledny = NULL;
 58     return;
 59   }
 60 
 61   // najdeme predposledny prvok
 62   while (p->dalsi->dalsi != NULL)
 63     p = p->dalsi;
 64   delete p->dalsi;
 65   p->dalsi = NULL;
 66   z.posledny = p;
 67 }
 68 
 69 void Zmaz(TZoznam &z)
 70 {
 71   while (!JePrazdny(z))
 72     ZmazPosledny(z);
 73 }
 74 
 75 void Nacitaj(TStudent &s,istream &vstup)
 76 {
 77  vstup>>s.meno>>s.priezvisko>>s.znamka_ZI;    
 78  vstup>>s.datum_narodenia.d>>s.datum_narodenia.m>>s.datum_narodenia.y;
 79 }
 80 
 81 void VlozNaKoniec(TZoznam &z,TStudent s)
 82 {
 83  TPrvok *novy = new TPrvok;
 84   novy->student = s;
 85   novy->dalsi = NULL;
 86 
 87   if (z.prvy == NULL)  // prazdny zoznam
 88     z.prvy = novy;
 89   else
 90     z.posledny->dalsi = novy;
 91   z.posledny = novy;
 92 }
 93 
 94 int main()
 95 {
 96   TZoznam zoznam;
 97   zoznam.prvy = zoznam.posledny = NULL;
 98   TStudent s;
 99   int n=0;
100 
101   ifstream vstup;
102   vstup.open("prvaci.txt");
103  
104   Nacitaj(s,vstup);
105   VlozNaKoniec(zoznam,s);
106   while(s.datum_narodenia.d)
107   {
108           Nacitaj(s,vstup);
109           if(s.datum_narodenia.d)
110              VlozNaKoniec(zoznam,s);
111           n++;
112   }
113   vstup.close();
114   cout<<"--------vypis zoznamu--------------"<<endl;
115   cout<<"Pocet studentov: "<<n<<endl;;
116   Vypis(zoznam);
117   Zmaz(zoznam);
118 
119   system("pause");
120 }