#include #include #include using namespace std; template struct Cvor { Tip element; Cvor *prethodni; Cvor *veza; Cvor() = default; Cvor(Tip element, Cvor *p, Cvor *q) { this->element=element; prethodni=p; veza=q; } }; template class Iterator; template class Lista { public: Lista() {}; virtual int brojElemenata() const=0; virtual Tip &trenutni() = 0; virtual Tip trenutni() const = 0; virtual bool prethodni() = 0; virtual bool sljedeci() = 0; virtual void pocetak() = 0; virtual void kraj() = 0; virtual void obrisi() = 0; virtual void dodajIspred(const Tip &el) = 0; virtual void dodajIza(const Tip &el) = 0; virtual Tip &operator [](int i) = 0; virtual Tip operator[](int i) const = 0; virtual ~Lista() {} }; template class DvostrukaLista:public Lista { Cvor *pocetni; Cvor *krajnji; Cvor *tekuci; int brojelemenata; int pozicijaTekuceg; void Dealociraj() { tekuci=nullptr; while(pocetni!=krajnji) { Cvor *p=pocetni; pocetni=pocetni->veza; delete p; p=nullptr; } delete krajnji; krajnji=nullptr; } public: DvostrukaLista() { pocetni=nullptr; krajnji=nullptr; tekuci=nullptr; brojelemenata=0; pozicijaTekuceg=0; } DvostrukaLista(const DvostrukaLista &lista) { brojelemenata=lista.brojElemenata(); pozicijaTekuceg=lista.pozicijaTekuceg; Cvor *p=lista.pocetni; pocetni = new Cvor(p->element, nullptr, nullptr); Cvor *poc=pocetni; krajnji=poc; tekuci=poc; p=p->veza; while(p!=nullptr) { poc->veza=new Cvor(p->element, poc, nullptr); poc=poc->veza; krajnji=poc; if(p==lista.tekuci) tekuci=poc; p=p->veza; } } int brojElemenata() const { return brojelemenata; } Tip &trenutni() { if(brojelemenata==0) throw std::domain_error("Prazna lista"); return tekuci->element; } Tip trenutni() const { if(brojelemenata==0) throw std::domain_error("Prazna lista"); return tekuci->element; } bool prethodni() { if(brojelemenata==0) throw std::domain_error("Prazna lista"); if(tekuci==pocetni) return false; tekuci=tekuci->prethodni; pozicijaTekuceg--; return true; } bool sljedeci() { if(brojelemenata==0) throw std::domain_error("Prazna lista"); if(tekuci==krajnji) return false; tekuci=tekuci->veza; pozicijaTekuceg++; return true; } void pocetak() { tekuci=pocetni; pozicijaTekuceg=0; } void kraj() { tekuci=krajnji; pozicijaTekuceg=brojelemenata-1; } void dodajIza(const Tip &el) { Cvor *p = new Cvor(); p->element = el; if(brojelemenata == 0) { p->prethodni = nullptr; p->veza = nullptr; tekuci=p; pocetni=p; krajnji=p; brojelemenata=1; pozicijaTekuceg=0; } else { p->prethodni=tekuci; p->veza=tekuci->veza; tekuci->veza=p; if(p->veza == nullptr) krajnji=p; else p->veza->prethodni=p; brojelemenata++; } } void dodajIspred(const Tip &el) { Cvor *p= new Cvor(); p->element=el; if(brojelemenata==0) { p->prethodni=nullptr; p->veza=nullptr; tekuci=p; pocetni=p; krajnji=p; brojelemenata=1; pozicijaTekuceg=0; } else { p->prethodni=tekuci->prethodni; p->veza = tekuci; tekuci->prethodni = p; if(p->prethodni == nullptr) pocetni=p; else p->prethodni->veza=p; brojelemenata++; pozicijaTekuceg++; } } void obrisi() { if(pocetni==krajnji) { delete pocetni; pocetni=nullptr; tekuci=nullptr; krajnji=nullptr; pozicijaTekuceg=0; } else if(tekuci==krajnji) { tekuci=tekuci->prethodni; tekuci->veza=nullptr; delete krajnji; krajnji=tekuci; tekuci->veza=nullptr; pozicijaTekuceg--; } else if(tekuci==pocetni) { tekuci=tekuci->veza; tekuci->prethodni=nullptr; delete pocetni; pocetni=tekuci; tekuci->prethodni=nullptr; pozicijaTekuceg=0; } else { Cvor *p= tekuci->veza; tekuci->prethodni->veza=p; p->prethodni=tekuci->prethodni; delete tekuci; tekuci=p; } brojelemenata--; } Tip operator [] (int i) const { int razlika1, razlika2, razlika3; razlika1=i; razlika2=brojelemenata-1-i; razlika3=abs(pozicijaTekuceg-i); if(razlika1<=razlika2 && razlika1<=razlika3) { Cvor *p=pocetni; for(int j=0; jveza; return p->element; } else if(razlika3=0) { Cvor *p=tekuci; for(int j=0; jveza; return p->element; } else if(razlika<0) { Cvor *p=tekuci; for(int j=0; jprethodni; return p->element; } } else { Cvor *p=krajnji; for(int j=0; jprethodni; return p->element; } } Tip &operator [](int i) { int razlika1, razlika2, razlika3; razlika1=i; razlika2=abs(brojelemenata-1-i); razlika3=abs(pozicijaTekuceg-i); if(razlika1<=razlika2 && razlika1<=razlika3) { Cvor *p=pocetni; for(int j=0; jveza; return p->element; } else if(razlika3=0) { Cvor *p=tekuci; for(int j=0; jveza; return p->element; } else if(razlika<0) { Cvor *p=tekuci; for(int j=0; jprethodni; return p->element; } } else { Cvor *p=krajnji; for(int j=0; jprethodni; return p->element; } } ~DvostrukaLista() { Dealociraj(); } DvostrukaLista &operator= (const DvostrukaLista &lista) { if(this!=&lista) { Dealociraj(); brojelemenata=lista.brojelemenata; pozicijaTekuceg=lista.pozicijaTekuceg; Cvor *p=lista.pocetni; pocetni=new Cvor(p->element, nullptr, nullptr); Cvor *poc=pocetni; krajnji=poc; tekuci=poc; p=p->veza; while(p!=nullptr) { poc->veza=new Cvor(p->element, poc, nullptr); poc=poc->veza; krajnji=poc; if(p==lista.tekuci) tekuci=poc; p=p->veza; } } return *this; } friend class Iterator; }; template class Iterator { const DvostrukaLista *lista; Cvor *trenutniLista; public: Iterator(const DvostrukaLista &l) { lista=&l; trenutniLista=l.pocetni; } Tip trenutni() { return trenutniLista->element; } bool prethodni() { if(lista->brojelemenata==0) throw std::domain_error("Prazna lista"); if(lista->tekuci==lista->pocetni) return false; trenutniLista=trenutniLista->prethodni; return true; } bool sljedeci() { if(lista->brojElemenata()==0) throw std::domain_error("Prazna lista"); if(lista->tekuci == lista->pocetni) return false; trenutniLista=trenutniLista->veza; return true; } void pocetak() { trenutniLista=lista->pocetni; } void kraj() { trenutniLista=lista->krajnji; } }; template Tip dajMaksimum(const Lista &n) { const DvostrukaLista *l=(DvostrukaLista*)(&n); Iterator iter(*l); iter.pocetak(); Tip max = iter.trenutni(); for(int **0; imax) max=iter.trenutni(); iter.sljedeci(); } return max; } template bool testbrojElemanata(const DvostrukaLista &lista, int velicina_liste) { if(velicina_liste==lista.brojElemenata()) return true; return false; } template bool testtrenutni(const DvostrukaLista &lista, Tip element) { if(element==lista.trenutni()) return true; return false; } template bool testprethodni(DvostrukaLista &lista, Tip prethodni) { lista.prethodni(); if(prethodni==lista.trenutni()) return true; return false; } template bool testsljedeci(DvostrukaLista &lista, Tip sljedeci) { lista.sljedeci(); if(sljedeci==lista.trenutni()) return true; return false; } template bool testpocetak(DvostrukaLista &lista, Tip pocetak) { lista.pocetak(); if(pocetak==lista.trenutni()) return true; return false; } template bool testkraj(DvostrukaLista &lista, Tip kraj) { lista.kraj(); if(kraj==lista.trenutni()) return true; return false; } template bool testOperatorZagrade(const DvostrukaLista &lista, int i, Tip element) { if(lista[i]==element) return true; return false; } template bool testOperatorJednako(const DvostrukaLista &lista) { DvostrukaLista nova; nova=lista; if(lista.brojElemenata()!=nova.brojElemenata())return false; for(int **0; i bool testObrisi(DvostrukaLista &lista, int brojelemenata, Tip tekuci) { lista.obrisi(); if(lista.brojElemenata()!=brojelemenata) return false; if(lista.trenutni()!=tekuci) return false; return true; } int main() { DvostrukaLista lista; for(int **0; i<7; i++) lista.dodajIza(i); if(testbrojElemanata(lista, 7)) std::cout << "Test funkcije brojElemenata: Uspjesan" << std::endl; else std::cout << "Test funkcije brojElemenata: Neuspjesan" << std::endl; if(testtrenutni(lista, 0)) std::cout << "Test funkcije trenutni: Uspjesan" << std::endl; else std::cout << "Test funkcije trenutni: Neuspjesan" << std::endl; if(testsljedeci(lista, 6)) std::cout << "Test funkcije sljedeci: Uspjesan" << std::endl; else std::cout << "Test funkcije sljedeci: Neuspjesan" << std::endl; if(testprethodni(lista, 0)) std::cout << "Test funkcije prethodni: Uspjesan" << std::endl; else std::cout << "Test funkcije prethodni: Neuspjesan" << std::endl; if(testpocetak(lista, 0)) std::cout << "Test funkcije pocetak: Uspjesan" << std::endl; else std::cout << "Test funkcije pocetak: Neuspjesan" << std::endl; if(testkraj(lista, 1)) std::cout << "Test funkcije kraj: Uspjesan" << std::endl; else std::cout << "Test funkcije kraj: Neuspjesan" << std::endl; if(testOperatorZagrade(lista, 3, 4)) std::cout << "Test funkcije operator []: Uspjesan" << std::endl; else std::cout << "Test funkcije operator []: Neuspjesa" << std::endl; if(testOperatorJednako(lista)) std::cout << "Test funkcije operator =: Uspjesan" << std::endl; else std::cout << "Test funkcije operator =: Neuspjesan" << std::endl; if(testObrisi(lista, 6, 2)) std::cout << "Test funkcije obrisi: Uspjesan" << std::endl; else std::cout << "Test funkcije obrisi: Neuspjesan" << std::endl; DvostrukaLista nova(lista); nova.dodajIspred(16); nova.dodajIspred(22); if(nova[5]==16 && nova[6]==22) std::cout << "Test funkcije dodajIspred: Uspjesan" << std::endl; else std::cout << "Test funkcije doadjIspred: Neuspjesan" << std::endl; return 0; }