Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <stdexcept>
- #include <vector>
- #include <queue>
- #include <string>
- #include <list>
- using std::vector;
- using std::list;
- //Prekopiran kod iz 10. pripremne (klase cvor, grana, granaiterator, usmjereni graf, kao i dvije funkcije bfs i dfs)
- //Ovo kopirano jer sam vec jednom uradio pa da ne bih kucao dva puta isti kod
- //Prvo navodimo prototipe kako ne bismo morali misliti na raspored generisanja klasa, a iste implementiramo ispod
- template<typename TipOznaka> class Cvor;
- template<typename TipOznaka> class Grana;
- template<typename TipOznaka> class GranaIterator;
- template<typename TipOznaka>
- class UsmjereniGraf{
- protected:
- UsmjereniGraf(){}
- public:
- UsmjereniGraf(int){}
- virtual ~UsmjereniGraf(){}
- virtual int dajBrojCvorova() const = 0;
- virtual void postaviBrojCvorova(int) = 0;
- virtual void dodajGranu(int, int, float = 0) = 0;
- virtual void obrisiGranu(int, int) = 0;
- virtual void postaviTezinuGrane(int, int, float = 0) = 0;
- virtual float dajTezinuGrane(int, int) const = 0;
- virtual bool postojiGrana(int, int) const = 0;
- virtual void postaviOznakuCvora(int, TipOznaka) = 0;
- virtual TipOznaka dajOznakuCvora(int) const = 0;
- virtual void postaviOznakuGrane(int, int, TipOznaka) = 0;
- virtual TipOznaka dajOznakuGrane(int, int) const = 0;
- virtual Grana<TipOznaka> dajGranu(int polazni, int dolazni) = 0;
- virtual Cvor<TipOznaka> dajCvor(int cvor) = 0;
- GranaIterator<TipOznaka> dajGranePocetak() { return ++GranaIterator<TipOznaka>(this, 0, -1); }
- GranaIterator<TipOznaka> dajGraneKraj() { return GranaIterator<TipOznaka>(this, dajBrojCvorova(), 0); }
- };
- template<typename TipOznaka>
- class Grana{
- UsmjereniGraf<TipOznaka>* graf;
- int polazni, dolazni;
- public:
- Grana(UsmjereniGraf<TipOznaka>* graf, int polazni, int dolazni) : polazni(polazni), dolazni(dolazni), graf(graf){}
- float dajTezinu() const {return graf->dajTezinuGrane(polazni, dolazni);}
- void postaviTezinu(float x){graf->postaviTezinuGrane(polazni, dolazni, x);}
- TipOznaka dajOznaku(){return graf->dajOznakuGrane(polazni, dolazni);}
- void postaviOznaku(TipOznaka oznaka) const {graf->postaviOznakuGrane(polazni, dolazni, oznaka);}
- Cvor<TipOznaka> dajPolazniCvor(){return graf->dajCvor(polazni);}
- Cvor<TipOznaka> dajDolazniCvor(){return graf->dajCvor(dolazni);}
- };
- template<typename TipOznaka>
- class Cvor{
- UsmjereniGraf<TipOznaka>* graf;
- int redniBroj;
- public:
- Cvor(UsmjereniGraf<TipOznaka>* ug, int rb){graf = ug; redniBroj = rb;}
- TipOznaka dajOznaku() const {return graf->dajOznakuCvora(redniBroj);}
- void postaviOznaku(TipOznaka oznaka){graf->postaviOznakuCvora(redniBroj, oznaka);}
- int dajRedniBroj() const {return redniBroj;}
- };
- template <typename TipOznaka>
- class GranaIterator {
- UsmjereniGraf<TipOznaka>* graf;
- int polazni, dolazni;
- public:
- GranaIterator(UsmjereniGraf<TipOznaka>* graf, int polazni, int dolazni) : graf(graf), polazni(polazni), dolazni(dolazni){}
- Grana<TipOznaka> operator*() { return graf->dajGranu(polazni, dolazni); }
- bool operator==(const GranaIterator &iter) const { return graf == iter.graf && polazni == iter.polazni && dolazni == iter.dolazni; }
- bool operator!=(const GranaIterator &iter) const { return !(*this == iter); }
- GranaIterator& operator++(){
- do {
- if(dolazni+1>=graf->dajBrojCvorova()) dolazni=0,polazni++;
- else dolazni++;
- } while(polazni<graf->dajBrojCvorova() && !graf->postojiGrana(polazni,dolazni));
- return *this;
- }
- GranaIterator operator++(int) {
- if(polazni == -1 && dolazni == -1) throw std::logic_error("Iterator pokazuje iza kraja");
- GranaIterator tmp(*this);
- ++(*this);
- return tmp;
- }
- friend class Grana<TipOznaka>;
- };
- template <typename Tip1, typename Tip2>
- class Mapa{
- public:
- Mapa(){}
- virtual ~Mapa(){}
- virtual int brojElemenata() const { return 0; }
- virtual Tip2 &operator [] (Tip1 kljuc) = 0;
- virtual Tip2 operator [](Tip1 kljuc) const = 0;
- virtual void obrisi(){}
- virtual void obrisi(const Tip1 &kljuc) {}
- };
- template <typename Tip1, typename Tip2>
- struct Par{
- Tip1 kljuc;
- Tip2 vrijednost;
- };
- template <typename TipOznaka>
- struct Element{
- TipOznaka oznaka;
- int cvor;
- float tezina;
- };
- template <typename Tip1, typename Tip2>
- class HashMapaLan : public Mapa<Tip1, Tip2>{
- int broj = 0;
- vector<list<Par<Tip1, Tip2>>> mapa;
- static const int kapacitet = 10000;
- unsigned int (*hash)(Tip1, unsigned int) = 0;
- typename list<Par<Tip1, Tip2>>::iterator trazi(Tip1 kljuc);
- typename list<Par<Tip1, Tip2>>::const_iterator trazi(Tip1 kljuc) const;
- public:
- HashMapaLan() : mapa(kapacitet, list<Par<Tip1, Tip2>>()) {}
- int brojElemenata() const { return broj; }
- void obrisi();
- void obrisi(const Tip1 &kljuc);
- void definisiHashFunkciju(unsigned int (*fun)(Tip1, unsigned int)) {hash = fun;}
- Tip2 &operator [](Tip1 kljuc);
- Tip2 operator [](Tip1 kljuc) const;
- };
- template <typename TipOznaka>
- class ListaGraf : public UsmjereniGraf<TipOznaka>{
- vector<list<Element<TipOznaka>>> L;
- vector<TipOznaka> cvorOznake;
- void ispravanCvor(int) const;
- void ispravnaGrana(int, int) const;
- void existG(int, int) const;
- typename list<Element<TipOznaka>>::iterator findEl(int x, int y){
- auto it(L[x].begin());
- while(it != L[x].end()){
- if(y == it->cvor) return it;
- else if(y < it->cvor) return L[x].end();
- }
- return it;
- }
- typename list<Element<TipOznaka>>::const_iterator findEl(int x, int y) const{
- auto it(L[x].begin());
- while(it != L[x].end()){
- if(y == it->cvor) return it;
- else if(y < it->cvor) return L[x].end();
- }
- return it;
- }
- public:
- ListaGraf(int);
- ~ListaGraf(){}
- int dajBrojCvorova() const { return L.size(); }
- void postaviBrojCvorova(int);
- void dodajGranu(int, int, float = 0);
- void obrisiGranu(int, int);
- void postaviTezinuGrane(int, int, float = 0);
- float dajTezinuGrane(int, int) const;
- bool postojiGrana(int, int) const;
- void postaviOznakuCvora(int, TipOznaka);
- TipOznaka dajOznakuCvora(int) const;
- void postaviOznakuGrane(int, int, TipOznaka);
- TipOznaka dajOznakuGrane(int, int) const;
- Grana<TipOznaka> dajGranu(int, int);
- Cvor<TipOznaka> dajCvor(int);
- };
- template<typename TipOznaka>
- void bfs(UsmjereniGraf<TipOznaka>* graf, vector<Cvor<TipOznaka>> &bfsP, Cvor<TipOznaka> cvor);
- template<typename TipOznaka>
- void dfs(UsmjereniGraf<TipOznaka>* graf, vector<Cvor<TipOznaka>> &dfsP, Cvor<TipOznaka> cvor);
- int main() {
- return 0;
- }
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////// IMPLEMENTACIJA HASH MAPE LAN ////////////////////////////////
- template <typename Tip1, typename Tip2>
- typename list<Par<Tip1, Tip2>>::const_iterator HashMapaLan<Tip1, Tip2>::trazi(Tip1 kljuc) const{
- if(!hash) throw std::domain_error("Izuzetak");
- int indeks(hash(kljuc, mapa.size()));
- auto iter(mapa[indeks].begin());
- while(iter != mapa[indeks].end() && kljuc > iter->kljuc) iter++;
- return iter;
- }
- template <typename Tip1, typename Tip2>
- typename list<Par<Tip1, Tip2>>::iterator HashMapaLan<Tip1, Tip2>::trazi(Tip1 kljuc){
- if(!hash) throw std::domain_error("Izuzetak");
- int indeks(hash(kljuc, mapa.size()));
- auto iter(mapa[indeks].begin());
- while(iter != mapa[indeks].end() && kljuc > iter->kljuc) iter++;
- return iter;
- }
- template <typename Tip1, typename Tip2>
- void HashMapaLan<Tip1, Tip2>::obrisi(){
- for(auto &clan : mapa)
- clan.clear();
- broj = 0;
- }
- template <typename Tip1, typename Tip2>
- void HashMapaLan<Tip1, Tip2>::obrisi(const Tip1 &kljuc){
- auto iter(trazi(kljuc));
- int indeks(hash(kljuc, mapa.size()));
- if(iter == mapa[indeks].end() || iter->kljuc != kljuc) throw std::domain_error("Izuzetak!");
- auto iter2(iter++);
- mapa[indeks].erase(iter2, iter);
- broj--;
- }
- template <typename Tip1, typename Tip2>
- Tip2 &HashMapaLan<Tip1, Tip2>::operator [](Tip1 kljuc){
- auto iter(trazi(kljuc));
- int indeks(hash(kljuc, mapa.size()));
- if(iter == mapa[indeks].end() || iter->kljuc != kljuc){
- Par<Tip1, Tip2> temp;
- temp.kljuc = kljuc;
- temp.vrijednost = Tip2();
- iter = mapa[indeks].insert(iter, temp);
- broj++;
- }
- return iter->vrijednost;
- }
- template <typename Tip1, typename Tip2>
- Tip2 HashMapaLan<Tip1, Tip2>::operator [](Tip1 kljuc) const {
- auto iter(trazi(kljuc));
- int indeks(hash(kljuc, mapa.size()));
- if(iter == mapa[indeks].end() || iter->kljuc != kljuc)
- return Tip2();
- return iter->vrijednost;
- }
- template<typename TipOznaka>
- void dfs(UsmjereniGraf<TipOznaka>* graf, vector<Cvor<TipOznaka>> &dfsP, Cvor<TipOznaka> cvor){
- cvor.postaviOznaku(1);
- dfsP.push_back(cvor);
- for(GranaIterator<TipOznaka> it = graf->dajGranePocetak(); it != graf->dajGraneKraj(); ++it){
- Cvor<TipOznaka> susjed = (*it).dajDolazniCvor();
- if((*it).dajPolazniCvor().dajRedniBroj() == cvor.dajRedniBroj() && susjed.dajOznaku() != 1)
- dfs(graf, dfsP, susjed);
- }
- }
- template<typename TipOznaka>
- void bfs(UsmjereniGraf<TipOznaka>* graf, vector<Cvor<TipOznaka>> &bfsP, Cvor<TipOznaka> cvor){
- cvor.postaviOznaku(1);
- bfsP.push_back(cvor);
- std::queue<Cvor<TipOznaka>> q;
- q.push(cvor);
- while(!q.empty()){
- Cvor<TipOznaka> c=q.front();
- q.pop();
- for(GranaIterator<TipOznaka> it = graf->dajGranePocetak(); it != graf->dajGraneKraj(); it++){
- Cvor<TipOznaka> susjed = (*it).dajDolazniCvor();
- if((*it).dajPolazniCvor().dajRedniBroj() == c.dajRedniBroj() && susjed.dajOznaku() != 1){
- susjed.postaviOznaku(1);
- bfsP.push_back(susjed);
- q.push(susjed);
- }
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////// IMPLEMENTACIJA GRAFA POMOCU LISTE ///////////////////////////
- template <typename TipOznaka>
- void ListaGraf<TipOznaka>::ispravanCvor(int redniBroj) const{
- if(redniBroj < 0 || redniBroj >= dajBrojCvorova()) throw std::domain_error("Izuzetak!");
- }
- template <typename TipOznaka>
- void ListaGraf<TipOznaka>::ispravnaGrana(int polazni, int dolazni) const{
- ispravanCvor(polazni);
- ispravanCvor(dolazni);
- }
- template <typename TipOznaka>
- void ListaGraf<TipOznaka>::existG(int polazni, int dolazni) const{
- ispravnaGrana(polazni, dolazni);
- if(!postojiGrana(polazni, dolazni)) throw std::domain_error("Izuzetak");
- }
- template <typename TipOznaka>
- ListaGraf<TipOznaka>::ListaGraf(int n){
- if(n < 0) throw std::domain_error("Izuzetak");
- L = vector<list<Element<TipOznaka>>>(n, list<Element<TipOznaka>>());
- cvorOznake = vector<TipOznaka>(n);
- }
- template <typename TipOznaka>
- Cvor<TipOznaka> ListaGraf<TipOznaka>::dajCvor(int cvor){
- ispravanCvor(cvor);
- return Cvor<TipOznaka>(this, cvor);
- }
- template <typename TipOznaka>
- Grana<TipOznaka> ListaGraf<TipOznaka>::dajGranu(int polazni, int dolazni){
- existG(polazni, dolazni);
- return Grana<TipOznaka>(this, polazni, dolazni);
- }
- template <typename TipOznaka>
- TipOznaka ListaGraf<TipOznaka>::dajOznakuGrane(int polazni, int dolazni) const{
- existG(polazni, dolazni);
- return findEl(polazni, dolazni)->oznaka;
- }
- template <typename TipOznaka>
- void ListaGraf<TipOznaka>::postaviOznakuGrane(int polazni, int dolazni, TipOznaka o){
- existG(polazni, dolazni);
- findEl(polazni, dolazni)->oznaka = o;
- }
- template <typename TipOznaka>
- TipOznaka ListaGraf<TipOznaka>::dajOznakuCvora(int cvor) const{
- ispravanCvor(cvor);
- return cvorOznake[cvor];
- }
- template <typename TipOznaka>
- void ListaGraf<TipOznaka>::postaviOznakuCvora(int cvor, TipOznaka o){
- ispravanCvor(cvor);
- cvorOznake[cvor] = o;
- }
- template <typename TipOznaka>
- bool ListaGraf<TipOznaka>::postojiGrana(int polazni, int dolazni) const {
- ispravnaGrana(polazni, dolazni);
- return findEl(polazni, dolazni) != L[polazni].end();
- }
- template <typename TipOznaka>
- float ListaGraf<TipOznaka>::dajTezinuGrane(int polazni, int dolazni) const{
- existG(polazni, dolazni);
- return findEl(polazni, dolazni)->tezina;
- }
- template <typename TipOznaka>
- void ListaGraf<TipOznaka>::postaviTezinuGrane(int polazni, int dolazni, float tezina){
- existG(polazni, dolazni);
- findEl(polazni, dolazni)->tezina = tezina;
- }
- template <typename TipOznaka>
- void ListaGraf<TipOznaka>::obrisiGranu(int polazni, int dolazni){
- existG(polazni, dolazni);
- L[polazni].erase(findEl(polazni, dolazni));
- }
- template <typename TipOznaka>
- void ListaGraf<TipOznaka>::dodajGranu(int polazni, int dolazni, float tezina){
- ispravnaGrana(polazni, dolazni);
- auto it(L[polazni].begin());
- while(it != L[polazni].end() && dolazni > it->cvor)
- it++;
- Element<TipOznaka> tmp;
- tmp.tezina = tezina;
- tmp.oznaka = TipOznaka();
- tmp.cvor = dolazni;
- L[polazni].insert(it, tmp);
- }
- template <typename TipOznaka>
- void ListaGraf<TipOznaka>::postaviBrojCvorova(int n){
- if(n < dajBrojCvorova()) throw std::domain_error("Izuzetak!");
- L.resize(n);
- cvorOznake.resize(n);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement