//Generikus körkörös, duplán láncolt lista interfésze
#include <iostream>
#include <fstream> // a fájlkezeléshez
using namespace std;
template <class T> // Ez kell elé, hogy a friend-nél
class Lista; // már ismert legyen a Lista<T>
// ListaElem nevű osztály deklarációja
template <class T> // Sablon kezdete (kell, mert generikus)
class ListaElem {
friend class Lista<T>;
private: // hozzá kell férnie a mezőkhöz
T adat; // adat (változhat a típusa)
ListaElem<T> *kov; // pointer következő elemre
ListaElem<T> *elo; // pointer az előző elemre
};
// Lista nevű osztály deklarációja
template <class T> // Sablon kezdete (kell, mert generikus)
class Lista {
ListaElem<T> *elso; // első pointer
public:
Lista() { elso = new ListaElem<T>; //Konstruktor
elso->kov = NULL;
elso->elo = NULL;
elso->adat = NULL;
}
//Függvények
void beszur(const T&); //ListaElem beszúrása
void beszurhelyere(T); //megkeresi a paraméterként megadott adatnak megfelelő helyét az elemnek, és a listába eszerint szúrja be
void beolvas(char*); //a megadott paraméter lesz a beovlasandó fájl, egy listát ad vissza
void torol(const T&); //ListaElem törlése
bool szerepel(const T&); //logikai visszatérés, igaz ha szerepel az adott adat a listában
int keres(const T&); //megadja, hogy az első elem után először mikor fordul elő a keresett adat
int elemszam(); //megadja az adott lista elemeinek számát
bool hasonlit(T d1, T d2) { return(d1<d2); } // default hasonlító fv.
//Operátor overload-ok
Lista<T> operator+(Lista<T>&); // Két lista egyesítve, az első paraméterként megadott listában lesznek az adatok, a második
Lista<T>& Lista<T>::operator=(Lista<T>&); //Értékadás
bool operator<(Lista<T>&); //Összehasonlítás, kisebb-e?
bool operator==(Lista<T>&); //Összehasonlítás : egyenlőek-e?
bool operator>(Lista<T>&); //Összehasonlítás : nagyobb-e?
T& operator[](int ik); //Indexedik elem
ostream& operator<<(ostream& os, const Lista<T>&); //Kiíratás overload, kiírja az adott lista összes elemét
void deleteAll(); //deleteAll függvény
~Lista() { deleteAll(); delete elso;} //Destruktor
//Iterátor osztály (bejárók)
class iterator;
/**
*Az iterátorok használata megkönnyíti a léptetést
*/
//Iterátor kifejtve
class iterator{
public:
ListaElem<T> *akt,*elotti; //kihasználjuk a két irány előnyeit
iterator() : akt(0),elotti(0){}; //Iterátor konstruktor
iterator begin() { // létrehoz egy iterátort és az elejére állítja
return(iterator(*this));
}
iterator end() { // létrehozza és az utolsó elem után állítja
return(iterator());
}
iterator(const Lista& I):akt(I.elso),elotti(I.elso)
{
if(akt->kov == elotti) akt=0;
}
iterator& operator++(){
if(akt){
akt = akt->kov;
if((akt->kov) == elotti) akt = 0;
}
return(*this);
}
iterator operator++(int) { // növeli az iterátort (post)
iterator tmp = *this; // előző érték
operator++(); // növel
return(tmp); // előzővel kell visszatérni
}
bool operator!=(const iterator &i) const { // összehasonlít
return(akt != i.akt);
}
};
//Függvények deklarációja
//beszurás függvénye
template<class T>
void Lista<T>::beszur(const T& dat){ //létrehozunk egy uj lista elemet, amit a lista
new ListaElem<T> uj; //elejére szurunk be, majd az 'adat' tagjának,
uj->adat = dat; // a paraméterül kapott 'dat' értéket adjuk
uj->kov = elso->kov;
elso->kov->elo = uj;
elso->kov = uj;
uj->elo = elso;
}
//helyére beszurás függvénye
template<class T>
void Lista<T>::beszurhelyere(const T& dat){
ListaElem<T> *temp;
for(temp=elso;temp->kov!=elso && hasonlit(temp->adat,dat);temp = temp->kov);
new ListaElem<T> uj;
uj->adat = dat; // a sima beszur függvényhez hasonloan mukordik,
uj->kov = temp->kov; //annyi különbséggel, hogy egy for ciklussal, meg-
temp->kov->elo = uj; //keressük az elem 'adat' tag szerinti helyét a listában
temp->kov = uj;
uj->elo = temp;
}
//törlés függvénye
template<class T>
void Lista<T>::torol(const T& dat){ // paraméterul egy értéket kap, az ezt tartalmazo
ListaElem<T> *temp,*torlendo; //listaelemet megkeresi a listában, majd törli azt
for(temp=elso;temp->kov!=elso && temp->adat!=dat;temp=temp->kov);
temp->kov = torlendo;
temp->kov = torlendo->kov;
torlendo->kov = temp;
delete torlendo;
}
//szerepelés függvénye
template<class T>
void Lista<T>::szerepel(const T& dat){ //megnézi, hogy szerepel e a listában
ListaElem<T> *temp; //a paraméterül kapott adatot tároló listaelem
for(temp=elso;temp->kov!=elso && temp->adat!=dat;temp=temp->kov);
if (temp->kov == NULL)
return(false);
else
return(true);
}
//keres függvénye
template<class T>
int Lista<T>::keres(const T& dat){ // a szerepel függvénytől eltérően,
ListaElem<T> *temp; //nem a jelenlét a lényeg, hanem, hogy
int db; // a keresett értéket hanyadik listaelem tárolja
for(temp=elso;temp->kov!=elso && temp->adat!=dat;temp=temp->kov)
db++;
if(temp->kov == elso && temp->adat != dat)
return -1;
else
return (db+1);
}
//elemszam függvénye
template<class T>
int Lista<T>::elemszam(){ //megadja az adott lista elemszamat
ListaElem<T> *temp;
int db;
for(temp=elso;temp->kov!=elso;temp=temp->kov)
db++;
return (db+1);
}
//Operator overloadok
//+ operator értelmezése
Lista<T> Lista<T>::operator+(Lista<T>& list){
Lista<T> uj;
ListaElem<T> *temp;
uj->adat = this->adat; //két listát összefűzünk, és egy
uj->elso->kov = this->elso->kov; //harmadikban adjuk vissza őket
this->elso->kov->elo = uj->elso;
for(temp=this->elso;temp->kov!=this->elso;temp=temp->kov);
temp->kov = list->elso->kov;
list->elso->kov->elo = temp;
list->elso->kov = uj->elso;
uj->elso->elo = list->elso;
return uj;
}
//< operator értelmezése
bool Lista<T>::operator<(Lista<T>& list){ //a benne talalhato listaelemek száma
return(this.elemszam() < list.elemszam()); //alapjan összehasonlit két listat
} //kisebb e
//> operator értelmezése
bool Lista<T>::operator<(Lista<T>& list){ //a benne talalhato listaelemek száma
return(this.elemszam() < list.elemszam()); //alapjan összehasonlit két listat
} //nagyobb e
//== operator értelmezése
bool Lista<T>::operator==(Lista<T>& list){ //a benne talalhato listaelemek száma
return(this.elemszam() == list.elemszam()); //alapjan összehasonlit két listat
} //egyenlő e
//[] operator értelmezése
T& operator[](int index){
int i;
ListaElem<T> *temp; // a paraméterként kapott indexnek megfelelő
if(this.elemszam()<i) // listaelemmel tér vissza
throw("Indexelesi hiba, tulnagy indexszam")
else
temp = elso;
for(i=0;i<=index;i++)
temp = temp->kov;
return temp;
}
//<< operator értelmezése
ostream& Lista<T>::operator<<(ostream& os, const Lista<T>& list){
int i;
for(i=0;i<=this.darabszam();i++) // lista kiírása, listaelemenként
{os<<list[i]<<endl;}
return os;
}
//törlés függvény
void Lista<T>::deleteAll(){ //egy lista törlése, az első tagon kívül
ListaElem<T> *temp;
for(temp=elso->kov;temp->kov;temp=temp->kov)
delete temp->elo;
}
};