You are on page 1of 8

#include <iostream>

using namespace std;


template<typename TipKljuca, typename TipVrijednosti>
class Mapa
{
public:
Mapa() {}
virtual ~Mapa() {}
virtual TipVrijednosti& operator[] (const TipKljuca& k)=0;
virtual const TipVrijednosti& operator[] (const TipKljuca& k) const=0;
virtual int brojElemenata() const=0;
virtual void obrisi()=0;
virtual void obrisi(const TipKljuca& kljuc)=0;
};

template<typename TipKljuca, typename TipVrijednosti>


struct Pair {
TipKljuca kljuc;
TipVrijednosti vrijednost;
};

template<typename TipKljuca, typename TipVrijednosti>


class NizMapa: public Mapa<TipKljuca,TipVrijednosti>
{
private:

Pair<TipKljuca,TipVrijednosti>* niz;
int kapacitet;
int brojEl;
TipVrijednosti pom;

void promijeniKapacitet() {

kapacitet*=2;
Pair<TipKljuca,TipVrijednosti>* tmp = new
Pair<TipKljuca,TipVrijednosti>[kapacitet];

for(int i=0; i<brojEl; i++) {


tmp[i].kljuc=niz[i].kljuc;
tmp[i].vrijednost=niz[i].vrijednost;
}

delete[] niz;

niz=tmp;

public:
NizMapa(): kapacitet(1000), brojEl(0), pom(TipVrijednosti()) {
niz = new Pair<TipKljuca,TipVrijednosti>[1000];
}

~NizMapa() {
delete[] niz;
}
NizMapa(const NizMapa<TipKljuca,TipVrijednosti>& mapa): niz(new
Pair<TipKljuca,TipVrijednosti>[1000]) {
kapacitet=mapa.kapacitet;
brojEl=mapa.brojEl;

for(int i=0; i<brojEl; i++) {


niz[i].kljuc = mapa.niz[i].kljuc;
niz[i].vrijednost = mapa.niz[i].vrijednost;
}
}

NizMapa<TipKljuca,TipVrijednosti>& operator = (const


NizMapa<TipKljuca,TipVrijednosti>& mapa) {
if(&mapa == this) return *this;

delete[] niz;

kapacitet=mapa.kapacitet;
brojEl=mapa.brojEl;

niz = new Pair<TipKljuca,TipVrijednosti>[1000];

for(int i=0; i<brojEl; i++) {


niz[i].kljuc = mapa.niz[i].kljuc;
niz[i].vrijednost = mapa.niz[i].vrijednost;
}

return *this;

TipVrijednosti& operator[] (const TipKljuca& k) override {

for(int i=0; i<brojEl; i++) {


if(niz[i].kljuc == k) return niz[i].vrijednost;
}

if(brojEl == kapacitet) promijeniKapacitet();

niz[brojEl].kljuc = k;
niz[brojEl].vrijednost = TipVrijednosti();

brojEl++;
return niz[brojEl-1].vrijednost;
}

const TipVrijednosti& operator[] (const TipKljuca& k) const override {


for(int i=0; i<brojEl; i++) {
if(niz[i].kljuc == k) return niz[i].vrijednost;
}

return pom;
}

int brojElemenata() const override {


return brojEl;
}

void obrisi() override {


brojEl=0;
}

void obrisi(const TipKljuca& k) override {


bool nasla=false;
for(int i=0; i<brojEl; i++) {
if(niz[i].kljuc == k) {
nasla=true;
niz[i].kljuc=niz[brojEl-1].kljuc;
niz[i].vrijednost=niz[brojEl-1].vrijednost;
brojEl--;
}
}

if(!nasla) throw("Kljuc nije pronadjen!");

};

template<typename TipKljuca, typename TipVrijednosti>


class BinStabloMapa: public Mapa<TipKljuca,TipVrijednosti>
{
protected:
struct Cvor {
TipKljuca kljuc;
TipVrijednosti vrijednost;
Cvor* desno;
Cvor* lijevo;
Cvor* prvi;
Cvor(const TipKljuca& k, const TipVrijednosti& v, Cvor* d, Cvor* l, Cvor*
p): kljuc(k),
vrijednost(v), desno(d), lijevo(l), prvi(p) {}
};

Cvor* pocetak;
int duzina;
TipVrijednosti pomocni;

Cvor* pretraga(const TipKljuca& k, Cvor* c) const {


if(c==0) return 0;
if(k==c->kljuc) return c;
if(k>c->kljuc) return pretraga(k, c->desno);
return pretraga(k,c->lijevo);
}

Cvor* dodaj(const TipKljuca& k, const TipVrijednosti& v, Cvor*& c, Cvor* prvi)


{
if(c==0) {
duzina++;
c = new Cvor(k,v,0,0,prvi);
return c;
}
if(c->kljuc==k) return c;
if(k<c->kljuc) return dodaj(k,v, c->lijevo, c);
return dodaj(k,v,c->desno, c);
}
void brisi(Cvor* c) {
if(c) {
brisi(c->lijevo);
brisi(c->desno);
delete c;
duzina--;
}
}

bool brisi2(const TipKljuca& k, Cvor* prvi) {

Cvor* p=pocetak, *m=0, *pm=0;


prvi=0;
while(p!=0 && k!=p->kljuc) {
prvi=p;
if(k<p->kljuc) p=p->lijevo;
else p=p->desno;
}
if(p==0) return false;

if(p->lijevo==0) m=p->desno;
else {
if(p->desno==0) m=p->lijevo;
else {
pm=p;
m=p->lijevo;
Cvor* tmp=m->desno;
while(tmp!=0) {
pm=m;
m=tmp;
tmp=m->desno;
}
if(pm!=p) {
pm->desno=m->lijevo;
m->lijevo=p->lijevo;
}
m->desno=p->desno;
}

if(prvi==0) pocetak=m;
else {
if(p==prvi->lijevo) prvi->lijevo=m;
else prvi->desno=m;
}
delete p;
return true;

void kopija(Cvor*& jedan, Cvor* dva, Cvor* prvi) {


if(dva==0) return;
jedan = new Cvor(dva->kljuc, dva->vrijednost,0,0,prvi);
kopija(jedan->lijevo, jedan->lijevo, jedan);
kopija(jedan->desno, jedan->desno, jedan);
duzina++;
}
public:

BinStabloMapa(): Mapa<TipKljuca,TipVrijednosti>(), pomocni(TipVrijednosti()),


pocetak(0), duzina(0) {

~BinStabloMapa() {
brisi(pocetak);
}

BinStabloMapa(const BinStabloMapa<TipKljuca,TipVrijednosti>& mapa): pocetak(0),


duzina(0) {
kopija(pocetak, mapa.pocetak,0);
duzina=mapa.duzina;
}

BinStabloMapa<TipKljuca,TipVrijednosti>& operator=(const
BinStabloMapa<TipKljuca,TipVrijednosti>& mapa) {
if(this==&mapa) return *this;
brisi(pocetak);
pocetak=0;
kopija(pocetak, mapa.pocetak,0);
duzina=mapa.duzina;
return *this;
}

TipVrijednosti& operator[] (const TipKljuca& k) override {


Cvor* pom=dodaj(k,TipVrijednosti(),pocetak,0);
return pom->vrijednost;
}

const TipVrijednosti& operator[] (const TipKljuca& k) const override {


Cvor* pom=pretraga(k,pocetak);
if(pom==0) return pomocni;
return pom->vrijednost;
}

int brojElemenata() const override {


return duzina;
}

void obrisi() override {


brisi(pocetak);
pocetak=0;
}

void obrisi(const TipKljuca& k) override {

if(brisi2(k, 0)) duzina--;


}
};

template<typename TipKljuca, typename TipVrijednosti>


class HashMapa: public Mapa<TipKljuca,TipVrijednosti>
{
private:
Pair<TipKljuca,TipVrijednosti>* niz;
unsigned int kapacitet;
int brojEl;
TipVrijednosti pom;
unsigned int (*fun)(TipKljuca, unsigned int);
bool definisana;

void promijeniKapacitet() {
unsigned int kap=kapacitet;
kapacitet*=2;
Pair<TipKljuca,TipVrijednosti>* tmp = new
Pair<TipKljuca,TipVrijednosti>[kapacitet];

for(int i=0; i<kap; i++) {


tmp[i].kljuc=niz[i].kljuc;
tmp[i].vrijednost=niz[i].vrijednost;
}

delete[] niz;

niz=tmp;

}
public:
HashMapa(): kapacitet(5000), brojEl(0), pom(TipVrijednosti()) {
niz=new Pair<TipKljuca, TipVrijednosti>[kapacitet];
fun=nullptr;
definisana=0;

for(int i=0; i<kapacitet; i++) {


niz[i].kljuc=TipKljuca();
niz[i].vrijednost=TipVrijednosti();
}
}

~HashMapa() {
delete[] niz;
brojEl=0;
fun=nullptr;
}

HashMapa(const HashMapa<TipKljuca,TipVrijednosti>& mapa) {


kapacitet=mapa.kapacitet;
brojEl=mapa.brojEl;
pom=TipVrijednosti();
definisana=mapa.definisana;
niz=new Pair<TipKljuca,TipVrijednosti>[kapacitet];

fun=mapa.fun;
for(int i=0; i<kapacitet; i++) {
niz[i].kljuc=mapa.niz[i].kljuc;
niz[i].vrijednost=mapa.niz[i].vrijednost;
}

HashMapa<TipKljuca,TipVrijednosti>& operator = (const


HashMapa<TipKljuca,TipVrijednosti>& mapa) {
if(this==&mapa) return *this;

delete[] niz;
definisana=mapa.definisana;
kapacitet=mapa.kapacitet;
brojEl=mapa.brojEl;
pom=TipVrijednosti();
fun=mapa.fun;
niz=new Pair<TipKljuca,TipVrijednosti>[kapacitet];

for(int i=0; i<kapacitet; i++) {


niz[i].kljuc=mapa.niz[i].kljuc;
niz[i].vrijednost=mapa.niz[i].vrijednost;
}

return *this;
}

int brojElemenata()const override {


return brojEl;
}

void definisiHashFunkciju(unsigned int (*f)(TipKljuca, unsigned int)) {


definisana=1;
fun=f;
}

void obrisi() override {


brojEl=0;
delete[] niz;

niz=new Pair<TipKljuca,TipVrijednosti>[kapacitet];
for(int i=0; i<kapacitet; i++) {
niz[i].kljuc=TipKljuca();
niz[i].vrijednost=TipVrijednosti();
}

void obrisi(const TipKljuca& k) override {


if(definisana==0) throw("Nedefinisan hash");

unsigned int i=fun(k,kapacitet);


if(niz[i].kljuc==TipKljuca()) return;
else if(niz[i].kljuc==k) {
niz[i].kljuc=TipKljuca();
niz[i].vrijednost=TipVrijednosti();
brojEl--;
}
else {
while(1) {

if(i==kapacitet-1) i=0;
if(niz[i].kljuc==k) {
niz[i].kljuc=-1;
niz[i].vrijednost=TipVrijednosti();
brojEl--;
return;
}
}
}
return ;
}

TipVrijednosti& operator[](const TipKljuca& k) override


{
if(definisana==0) throw("Nedefinisan hash");

unsigned int i=fun(k,kapacitet);


if(niz[i].kljuc==k) return niz[i].vrijednost;
else if(niz[i].kljuc==TipKljuca()) {
niz[i].kljuc=k;
brojEl++;
return niz[i].vrijednost;
} else {
if(i==kapacitet-1) i=0;
while(niz[i].kljuc!=TipKljuca()){
if(niz[i].kljuc==k) return niz[i].vrijednost;
if(i==kapacitet-1) i=0;
i++;
}

niz[i].kljuc=k;
brojEl++;
return niz[i].vrijednost;
}

const TipVrijednosti& operator[] (const TipKljuca& k) const override


{
if(definisana==0) throw("Nedefinisan hash");
for(int i=0; i<kapacitet; i++) {
if(niz[i].kljuc == k) return niz[i].vrijednost;
}

return pom;
}

};

You might also like