mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Nodrze
This commit is contained in:
parent
34276093ed
commit
92a82b7e46
876
nodrze.h
Normal file
876
nodrze.h
Normal file
@ -0,0 +1,876 @@
|
||||
#ifndef NODRZE
|
||||
#define NODRZE
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#ifndef LOGUJ
|
||||
#define LOGUJ(a) (std::cout<<a)
|
||||
#define CLOG(a) (std::cout<<a)
|
||||
#endif
|
||||
const bool CZERWONY=true, CZARNY=false;
|
||||
class TTAICore;
|
||||
extern TTAICore * C;
|
||||
|
||||
template <typename T> class wezel
|
||||
{
|
||||
public:
|
||||
bool kolor:1;
|
||||
T * zawart;
|
||||
wezel * ojciec, *lewy, *prawy;
|
||||
wezel(bool kol):kolor(kol),ojciec(NULL),lewy(NULL),prawy(NULL){zawart = new T;};
|
||||
wezel(wezel * NIL);
|
||||
~wezel(){delete zawart;}
|
||||
};
|
||||
template <typename T> std::ostream & piszAdresy(std::ostream & strum, wezel<T> & w)
|
||||
{
|
||||
strum << "Informacje o wezle: "<<&w;
|
||||
strum <<"\n\tOjciec: "<<(w.ojciec);
|
||||
strum<<"\n\tLewy syn: "<<(w.lewy);
|
||||
strum<<"\n\tPrawy syn: "<<(w.prawy);
|
||||
strum<<"\n\tKolor: "<<((w.kolor)?(std::string("Czerwony")):(std::string("Czarny")))<<std::endl<<std::endl;
|
||||
return strum;
|
||||
}
|
||||
template <typename T> std::ostream & operator<<(std::ostream & strum, wezel<T> & w)
|
||||
{
|
||||
strum << "Informacje o wezle: "<<&w<<" - "<<*w.zawart;
|
||||
strum <<"\n\tOjciec: "<<(w.ojciec)<<" - "<<*w.ojciec->zawart;
|
||||
strum<<"\n\tLewy syn: "<<(w.lewy)<<" - "<<*w.lewy->zawart;
|
||||
strum<<"\n\tPrawy syn: "<<(w.prawy)<<" - "<<*w.prawy->zawart;
|
||||
strum<<"\n\tKolor: "<<((w.kolor)?(std::string("Czerwony")):(std::string("Czarny")))<<std::endl<<std::endl;
|
||||
return strum;
|
||||
}
|
||||
template <typename T> wezel<T>::wezel(wezel * NIL)
|
||||
{
|
||||
ojciec=NIL; lewy=NIL; prawy=NIL; kolor=CZERWONY; zawart = NULL;
|
||||
}
|
||||
template <typename T> class nodrze
|
||||
{
|
||||
private:
|
||||
wezel<T> * NIL, *ostatnio;
|
||||
int ile, ktory;
|
||||
void zepsuj();
|
||||
void dodajBSTC (wezel<T> * nowy);
|
||||
void dodajBST (T co);
|
||||
void dodajRBT (wezel<T> * nowy);
|
||||
wezel<T> * usunRBT (wezel<T> * nowy);
|
||||
void naprawWstaw (wezel<T> * nowy);
|
||||
void naprawUsun (wezel<T> * x);
|
||||
wezel<T> * minimum(wezel<T> * w);
|
||||
wezel<T> * maksimum(wezel<T> * w);
|
||||
wezel<T> * nastepnik(wezel<T> * w);
|
||||
wezel<T> * poprzednik(wezel<T> * w);
|
||||
wezel<T> * szukajRek(wezel<T> * w, T co);
|
||||
wezel<T> * szukajIter(wezel<T> * w, T co);
|
||||
void in(std::ostream & strum, wezel<T> * wsk);
|
||||
void inIt(std::ostream & strum, wezel<T> * wsk);
|
||||
void pre(std::ostream & strum, wezel<T> * wsk);
|
||||
void post(std::ostream & strum, wezel<T> * wsk);
|
||||
void rotacjaLewa (wezel<T> * x);
|
||||
void rotacjaPrawa (wezel<T> * y);
|
||||
bool czyBST (wezel<T> * w);
|
||||
bool sprawdzW(wezel<T> * w);
|
||||
void destrukcja(wezel<T> * w);
|
||||
void wypisuj(wezel<T> * w, std::ostream & strum);
|
||||
void wypisujPre(wezel<T> * w, std::ostream & strum);
|
||||
public:
|
||||
wezel<T> * korzen;
|
||||
nodrze():ile(0) //najzwyczajniejszy w swiecie kosntruktor
|
||||
{
|
||||
NIL=new wezel<T>(CZARNY);
|
||||
korzen=NIL;
|
||||
ostatnio=NIL;
|
||||
ktory=0;
|
||||
};
|
||||
T * begin () {return minimumimum();};
|
||||
T * end () {return NIL;};
|
||||
void clear(); // czysci az do korzenia wlacznie
|
||||
void usun (T co); // usuwa element z drzewa
|
||||
bool sprawdz(); // sprawdza, czy drzewo jest poprawnym drzewem BST
|
||||
T * nast(T czego); // nastepnik zadenego elementu
|
||||
T * maksimumimum (); // najwiekszy element w drzewie
|
||||
bool czyJest(T co); // czy cos jest w drzewie
|
||||
T * minimumimum (); // najmniejszy element w drzewie
|
||||
void dodaj (T co); // dodaje element do drzewa
|
||||
void inorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku inorder
|
||||
void preorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku preorder
|
||||
void postorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku postorder
|
||||
void wypiszObficie(std::ostream & strum); //wypisuje dane o kazdym wezle -- wymaga operatora >> dla zawartosci
|
||||
T * znajdz (T co, bool iter = true); // wyszukuje zadany element
|
||||
int size(); //ilosc elementow
|
||||
T* operator()(int i) ; //n-ty element przez wskaxnik
|
||||
nodrze<T> & operator()(std::istream & potoczek) ; //zczytanie n elemntow z listy
|
||||
T& operator[](int i) ; //dostep do obiektu, ale przez wartosc
|
||||
bool operator+=(T * co);
|
||||
bool operator+=(T co);
|
||||
bool operator-=(T co);
|
||||
bool operator-=(T * co);
|
||||
T* operator%(T * co);
|
||||
bool operator&(T co);
|
||||
bool operator&(T * co);
|
||||
template <typename Y, class X> friend Y* operator%(nodrze<Y> & drzewko, X co);
|
||||
void push_back(T co){(*this)+=co;};
|
||||
};
|
||||
template <typename T> void nodrze<T>::wypisuj(wezel<T> * w, std::ostream & strum)
|
||||
{
|
||||
if (w==NIL) return;
|
||||
wypisuj(w->lewy, strum);
|
||||
|
||||
strum << "Informacje o wezle: "<<flush<<w<<flush;
|
||||
if (w->ojciec!=NIL)
|
||||
strum <<"\n\tOjciec: "<<(w->ojciec)<<" - "<<*(w->ojciec->zawart);
|
||||
else strum <<"\n\tOjciec: NIL";
|
||||
if (w->lewy!=NIL)
|
||||
strum<<"\n\tLewy syn: "<<(w->lewy)<<" - "<<*(w->lewy->zawart);
|
||||
else strum <<"\n\tLewy syn: NIL";
|
||||
if (w->prawy!=NIL)
|
||||
strum<<"\n\tPrawy syn: "<<(w->prawy)<<" - "<<*(w->prawy->zawart);
|
||||
else strum <<"\n\tPrawy syn: NIL";
|
||||
strum<<"\n\tZawartosc: "<<*w->zawart;
|
||||
strum<<"\n\tKolor: "<<((w->kolor)?(std::string("Czerwony")):(std::string("Czarny")))<<std::endl<<std::endl;
|
||||
|
||||
wypisuj(w->prawy, strum);
|
||||
}
|
||||
template <typename T> void nodrze<T>::wypisujPre(wezel<T> * w, std::ostream & strum)
|
||||
{
|
||||
if (w==NIL) return;
|
||||
|
||||
strum << "Informacje o wezle: "<<flush<<w<<flush;
|
||||
if (w->ojciec!=NIL)
|
||||
strum <<"\n\tOjciec: "<<(w->ojciec)<<" - "<<*(w->ojciec->zawart);
|
||||
else strum <<"\n\tOjciec: NIL";
|
||||
if (w->lewy!=NIL)
|
||||
strum<<"\n\tLewy syn: "<<(w->lewy)<<" - "<<*(w->lewy->zawart);
|
||||
else strum <<"\n\tLewy syn: NIL";
|
||||
if (w->prawy!=NIL)
|
||||
strum<<"\n\tPrawy syn: "<<(w->prawy)<<" - "<<*(w->prawy->zawart);
|
||||
else strum <<"\n\tPrawy syn: NIL";
|
||||
strum<<"\n\tZawartosc: "<<*w->zawart;
|
||||
strum<<"\n\tKolor: "<<((w->kolor)?(std::string("Czerwony")):(std::string("Czarny")))<<std::endl<<std::endl;
|
||||
|
||||
wypisujPre(w->lewy, strum);
|
||||
wypisujPre(w->prawy, strum);
|
||||
}
|
||||
template <typename T> void nodrze<T>::wypiszObficie(std::ostream & strum)
|
||||
{
|
||||
strum << "Nodrze " <<this<<" ma " << ile << " elementów."<<std::endl;
|
||||
strum << "NIL to " << NIL <<std::endl;
|
||||
strum << "Ostatnio bralismy "<<ktory<<flush<<" element, czyli "<<" ("<<ostatnio<<")"<<flush<<*ostatnio<<flush<<std::endl;
|
||||
strum << "Nasze wezly in-order"<<std::endl;
|
||||
wypisujPre(korzen,strum);
|
||||
};
|
||||
template <typename T, class X> T* operator%(nodrze<T> & drzewko, X co)
|
||||
{
|
||||
CLOG ("Szukam " <<co <<std::endl);
|
||||
drzewko.wypiszObficie(*C->gl->loguj);
|
||||
wezel<T> * w = drzewko.korzen;
|
||||
while (w!=drzewko.NIL && (*w->zawart)!=co)
|
||||
{
|
||||
if ((*w->zawart) > co)
|
||||
w=w->lewy;
|
||||
else w=w->prawy;
|
||||
}
|
||||
return w->zawart;
|
||||
};
|
||||
template <typename T> int nodrze<T>::size()
|
||||
{
|
||||
return ile;
|
||||
}
|
||||
template <typename T> void nodrze<T>::clear()
|
||||
{
|
||||
destrukcja(korzen);
|
||||
korzen=NIL;
|
||||
ostatnio=NIL;
|
||||
ktory=0;
|
||||
}
|
||||
template <typename T> void nodrze<T>::destrukcja(wezel<T> * w)
|
||||
{
|
||||
if (w==NIL) return;
|
||||
destrukcja(w->lewy);
|
||||
destrukcja(w->prawy);
|
||||
//delete w->zawart;
|
||||
delete w;
|
||||
};
|
||||
template <typename T> nodrze<T> & nodrze<T>::operator()(std::istream & potoczek)
|
||||
{
|
||||
int temp;
|
||||
potoczek >> temp;
|
||||
for (int i=0;i<temp;++i)
|
||||
potoczek >> (*this);
|
||||
return (*this);
|
||||
}
|
||||
template <typename T> T* nodrze<T>::operator()(int i)
|
||||
{
|
||||
int j;
|
||||
wezel<T> * nasz;
|
||||
if (ostatnio!=NIL)
|
||||
{
|
||||
j=i-ktory;
|
||||
if (j>0)
|
||||
{
|
||||
if (j > (ile-i))
|
||||
{
|
||||
ktory = i;
|
||||
i=ile-i-1;
|
||||
nasz = maksimum(korzen);
|
||||
for (j=0;j<i;j++)
|
||||
{
|
||||
nasz = poprzednik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return (nasz->zawart);
|
||||
}
|
||||
else
|
||||
{
|
||||
ktory = i;
|
||||
nasz = ostatnio;
|
||||
for (i=0;i<j;i++)
|
||||
{
|
||||
nasz = nastepnik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return (nasz->zawart);
|
||||
}
|
||||
}
|
||||
if (j==0)
|
||||
{
|
||||
return (ostatnio->zawart);
|
||||
}
|
||||
else
|
||||
{
|
||||
ktory = i;
|
||||
if ((-j)>i)
|
||||
{
|
||||
nasz = minimum(korzen);
|
||||
for (j=0;j<i;j++)
|
||||
{
|
||||
nasz = nastepnik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return (nasz->zawart);
|
||||
}
|
||||
else
|
||||
{
|
||||
nasz = ostatnio;
|
||||
for (i=0;i>j;i--)
|
||||
{
|
||||
nasz = poprzednik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return (nasz->zawart);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ktory = i;
|
||||
nasz = minimum(korzen);
|
||||
for (j=0;j<i;j++)
|
||||
{
|
||||
nasz = nastepnik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return (nasz->zawart);
|
||||
}
|
||||
}
|
||||
template <typename T> T& nodrze<T>::operator[](int i)
|
||||
{
|
||||
int j;
|
||||
wezel<T> * nasz;
|
||||
if (ostatnio!=NIL)
|
||||
{
|
||||
j=i-ktory;
|
||||
if (j>0)
|
||||
{
|
||||
if (j > (ile-i))
|
||||
{
|
||||
ktory = i;
|
||||
i=ile-i-1;
|
||||
nasz = maksimum(korzen);
|
||||
for (j=0;j<i;j++)
|
||||
{
|
||||
nasz = poprzednik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return *(nasz->zawart);
|
||||
}
|
||||
else
|
||||
{
|
||||
ktory = i;
|
||||
nasz = ostatnio;
|
||||
for (i=0;i<j;i++)
|
||||
{
|
||||
nasz = nastepnik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return *(nasz->zawart);
|
||||
}
|
||||
}
|
||||
if (j==0)
|
||||
{
|
||||
return *(ostatnio->zawart);
|
||||
}
|
||||
else
|
||||
{
|
||||
ktory = i;
|
||||
if ((-j)>i)
|
||||
{
|
||||
nasz = minimum(korzen);
|
||||
for (j=0;j<i;j++)
|
||||
{
|
||||
nasz = nastepnik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return *(nasz->zawart);
|
||||
}
|
||||
else
|
||||
{
|
||||
nasz = ostatnio;
|
||||
for (i=0;i>j;i--)
|
||||
{
|
||||
nasz = poprzednik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return *(nasz->zawart);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ktory = i;
|
||||
nasz = minimum(korzen);
|
||||
for (j=0;j<i;j++)
|
||||
{
|
||||
nasz = nastepnik(nasz);
|
||||
}
|
||||
ostatnio=nasz;
|
||||
return *(nasz->zawart);
|
||||
}
|
||||
}
|
||||
template <typename T> bool nodrze<T>::operator+=(T * co)
|
||||
{
|
||||
wezel<T> * w = new wezel<T>(NIL);
|
||||
w->kolor=CZERWONY;
|
||||
w->zawart = co;
|
||||
dodajRBT(w);
|
||||
return true;
|
||||
}
|
||||
template <typename T> bool nodrze<T>::operator+=(T co)
|
||||
{
|
||||
dodaj(co);
|
||||
return true;
|
||||
}
|
||||
template <typename T> bool nodrze<T>::operator-=(T co)
|
||||
{
|
||||
usun(co);
|
||||
return true;
|
||||
}
|
||||
template <typename T> bool nodrze<T>::operator-=(T * co)
|
||||
{
|
||||
usun(*co);
|
||||
return true;
|
||||
}
|
||||
template <typename T> T* nodrze<T>::operator%(T * co)
|
||||
{
|
||||
wezel<T> * w = szukajIter(korzen,*co);
|
||||
if (w != NIL)
|
||||
return w;
|
||||
else return NULL;
|
||||
}
|
||||
template <typename T> bool nodrze<T>::operator&(T co)
|
||||
{
|
||||
return czyJest(co);
|
||||
}
|
||||
template <typename T> bool nodrze<T>::operator&(T * co)
|
||||
{
|
||||
return czyJest(*co);
|
||||
}
|
||||
template <typename T> class iterator
|
||||
{
|
||||
/*nodrze<T> * dd;
|
||||
wezel<T> * akt;
|
||||
public:
|
||||
T * operator->()
|
||||
{
|
||||
return akt->zawart;
|
||||
}
|
||||
iterator& operator++()
|
||||
{
|
||||
akt = dd->nastepnik(akt);
|
||||
return this;
|
||||
}
|
||||
iterator& operator--()
|
||||
{
|
||||
akt = dd->poprzednik(akt);
|
||||
return this;
|
||||
}
|
||||
T * operator=(T*)
|
||||
{
|
||||
akt->zawart = T;
|
||||
return akt->zawart;
|
||||
}*/
|
||||
/*void start()
|
||||
{
|
||||
akt = maksimum(korzen);
|
||||
}*/
|
||||
};
|
||||
template <typename T> void nodrze<T>::inIt(std::ostream & strum, wezel<T> * wsk)
|
||||
{
|
||||
if (wsk == NIL)
|
||||
return;
|
||||
|
||||
// Start from the minimumimum wsk
|
||||
while (wsk->lewy != NIL)
|
||||
wsk=wsk->lewy;
|
||||
do
|
||||
{
|
||||
visit(wsk);
|
||||
// Next in order will be our right child's leftmost child (if NIL, our right child)
|
||||
if (wsk->prawy != NIL)
|
||||
{
|
||||
wsk = wsk->prawy;
|
||||
while (wsk->lewy != NIL)
|
||||
wsk = wsk->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (wsk->ojciec == NIL)
|
||||
{
|
||||
wsk = NIL;
|
||||
break;
|
||||
}
|
||||
wsk = wsk->ojciec;
|
||||
// If wsk is its parents left child, then its parent hasn't been visited yet
|
||||
if (wsk->ojciec->lewy == wsk)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (wsk != NIL);
|
||||
|
||||
};
|
||||
template <typename T> bool nodrze<T>::sprawdz()
|
||||
{
|
||||
return (sprawdzW(korzen));
|
||||
};
|
||||
template <typename T> T * nodrze<T>::znajdz (T co, bool iter)
|
||||
{
|
||||
return ((iter)?(szukajIter(korzen,co)->zawart):(szukajRek(korzen,co)->zawart));
|
||||
};
|
||||
template <typename T> void nodrze<T>::usun (T co)
|
||||
{
|
||||
wezel<T> * w = szukajIter(korzen, co);
|
||||
usunRBT(w);
|
||||
delete w;
|
||||
}
|
||||
template <typename T> void nodrze<T>::naprawUsun (wezel<T> * x)
|
||||
{
|
||||
wezel<T> *w;
|
||||
while ( (x != korzen) && (x->kolor == CZARNY) )
|
||||
{
|
||||
CLOG("6... "<<flush);
|
||||
if (x == x->ojciec->lewy)
|
||||
{
|
||||
CLOG("7... "<<flush);
|
||||
w = x->ojciec->prawy;
|
||||
if (w->kolor == CZERWONY)
|
||||
{
|
||||
w->kolor = CZARNY;
|
||||
x->ojciec->kolor = CZERWONY;
|
||||
rotacjaLewa(x->ojciec);
|
||||
w = x->ojciec->prawy;
|
||||
}
|
||||
CLOG("8... "<<flush);
|
||||
if ( (w->lewy->kolor == CZARNY) && (w->prawy->kolor == CZARNY) )
|
||||
{
|
||||
CLOG("8,1... "<<flush);
|
||||
w->kolor = CZERWONY;
|
||||
x = x->ojciec;
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOG("9... "<<flush);
|
||||
if (w->prawy->kolor == CZARNY)
|
||||
{
|
||||
CLOG("9,1... "<<flush);
|
||||
w->lewy->kolor = CZARNY;
|
||||
w->kolor = CZERWONY;
|
||||
rotacjaPrawa(w);
|
||||
w = x->ojciec->prawy;
|
||||
CLOG("9,2... "<<flush);
|
||||
}
|
||||
CLOG("9,3... "<<flush);
|
||||
w->kolor = x->ojciec->kolor;
|
||||
x->ojciec->kolor = CZARNY;
|
||||
w->prawy->kolor = CZARNY;
|
||||
rotacjaLewa(x->ojciec);
|
||||
x=korzen;
|
||||
CLOG("9,4... "<<flush);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOG("10... "<<flush);
|
||||
w = x->ojciec->lewy;
|
||||
if (w->kolor == CZERWONY)
|
||||
{
|
||||
w->kolor = CZARNY;
|
||||
x->ojciec->kolor = CZERWONY;
|
||||
rotacjaPrawa(x->ojciec);
|
||||
w = x->ojciec->lewy;
|
||||
}
|
||||
CLOG("11... "<<flush);
|
||||
if ( (w->lewy->kolor == CZARNY) && (w->prawy->kolor == CZARNY) )
|
||||
{
|
||||
w->kolor = CZERWONY;
|
||||
x = x->ojciec;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (w->lewy->kolor == CZARNY)
|
||||
{
|
||||
w->prawy->kolor = CZARNY;
|
||||
w->kolor = CZERWONY;
|
||||
rotacjaLewa(w);
|
||||
w = x->ojciec->lewy;
|
||||
}
|
||||
w->kolor = x->ojciec->kolor;
|
||||
x->ojciec->kolor = CZARNY;
|
||||
w->lewy->kolor = CZARNY;
|
||||
rotacjaPrawa(x->ojciec);
|
||||
x=korzen;
|
||||
CLOG("12... "<<flush);
|
||||
}
|
||||
}
|
||||
}
|
||||
x->kolor = CZARNY;
|
||||
CLOG("13... "<<flush);
|
||||
};
|
||||
template <typename T> wezel<T> * nodrze<T>::usunRBT (wezel<T> * nowy)
|
||||
{
|
||||
CLOG ("Usuwam "<<*nowy->zawart<<std::endl);
|
||||
ile--;
|
||||
if ((*nowy->zawart) < (*ostatnio->zawart))
|
||||
{
|
||||
ktory--;
|
||||
CLOG("Ostatnio to "<<(*ostatnio->zawart)<<", czyli teraz "<<(ktory)<<" (mniej) element."<<std::endl);
|
||||
}
|
||||
else if (nowy == ostatnio)
|
||||
{
|
||||
CLOG ("To był ostatnio oglšdany element. Elementem o numerze "<<ktory<<" bedzie teraz ");
|
||||
if (ktory < ile)
|
||||
{
|
||||
ostatnio = nastepnik(ostatnio);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOG ("Ojej, koniec. Cofamy się. "<<std::endl);
|
||||
ostatnio = poprzednik(ostatnio);
|
||||
ktory--;
|
||||
}
|
||||
CLOG(*ostatnio->zawart<<std::endl);
|
||||
}
|
||||
CLOG("1... "<<flush);
|
||||
wezel<T> *y, *x;
|
||||
if ( (nowy->lewy == NIL) || (nowy->prawy == NIL) )
|
||||
y=nowy;
|
||||
else y = nastepnik(nowy);
|
||||
CLOG("2... "<<flush);
|
||||
if (y->lewy != NIL)
|
||||
x = y->lewy;
|
||||
else x = y->prawy;
|
||||
x->ojciec = y->ojciec;
|
||||
CLOG("3... "<<flush);
|
||||
if (y->ojciec == NIL)
|
||||
korzen = x;
|
||||
else if (y == y->ojciec->lewy)
|
||||
y->ojciec->lewy = x;
|
||||
else
|
||||
y->ojciec->prawy = x;
|
||||
CLOG("4... "<<flush);
|
||||
if (y != nowy)
|
||||
(*nowy) = (*y); // skopiowanie
|
||||
CLOG("5... "<<flush);
|
||||
if (y->kolor == CZARNY)
|
||||
naprawUsun(x);
|
||||
CLOG ("koniec usuwania"<<std::endl);
|
||||
return y;
|
||||
};
|
||||
template <typename T> void nodrze<T>::naprawWstaw (wezel<T> * nowy)
|
||||
{
|
||||
CLOG ("Naprawiam po wstawieniu"<<std::endl);
|
||||
while (nowy->ojciec->kolor==CZERWONY)
|
||||
{
|
||||
if (nowy->ojciec == nowy->ojciec->ojciec->lewy) // ojciec nowego lest lewy
|
||||
{
|
||||
wezel<T> * y = nowy->ojciec->ojciec->prawy;
|
||||
if (y->kolor == CZERWONY) // a stryj jest czerwony
|
||||
{
|
||||
nowy->ojciec->kolor = CZARNY;
|
||||
y->kolor = CZARNY;
|
||||
nowy->ojciec->ojciec->kolor = CZERWONY;
|
||||
nowy = nowy->ojciec->ojciec;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nowy->ojciec->prawy == nowy) // nowy jest prawym synem
|
||||
{
|
||||
nowy = nowy->ojciec;
|
||||
rotacjaLewa(nowy);
|
||||
}
|
||||
nowy->ojciec->kolor=CZARNY;
|
||||
nowy->ojciec->ojciec->kolor=CZERWONY;
|
||||
rotacjaPrawa(nowy->ojciec->ojciec);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wezel<T> * y = nowy->ojciec->ojciec->lewy;
|
||||
if (y->kolor == CZERWONY) // a stryj jest czerwony
|
||||
{
|
||||
nowy->ojciec->kolor = CZARNY;
|
||||
y->kolor = CZARNY;
|
||||
nowy->ojciec->ojciec->kolor = CZERWONY;
|
||||
nowy = nowy->ojciec->ojciec;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nowy->ojciec->lewy == nowy)
|
||||
{
|
||||
nowy = nowy->ojciec;
|
||||
rotacjaPrawa(nowy);
|
||||
}
|
||||
nowy->ojciec->kolor=CZARNY;
|
||||
nowy->ojciec->ojciec->kolor=CZERWONY;
|
||||
rotacjaLewa(nowy->ojciec->ojciec);
|
||||
}
|
||||
}
|
||||
}
|
||||
korzen->kolor = CZARNY;
|
||||
}
|
||||
template <typename T> void nodrze<T>::dodajRBT (wezel<T> * nowy)
|
||||
{
|
||||
CLOG("Dodaje do drzewa "<<nowy->zawart<<std::endl);
|
||||
ile++;
|
||||
if ((*nowy->zawart) < (*ostatnio->zawart))
|
||||
{
|
||||
ktory++;
|
||||
}
|
||||
wezel<T> * y =NIL, * x = korzen;
|
||||
while (x != NIL)
|
||||
{
|
||||
y=x;
|
||||
if ((*nowy->zawart) < (*x->zawart))
|
||||
x=x->lewy;
|
||||
else x = x->prawy;
|
||||
}
|
||||
nowy->ojciec = y;
|
||||
if (y == NIL)
|
||||
{
|
||||
korzen=nowy;
|
||||
ostatnio=korzen;
|
||||
ktory=0;
|
||||
}
|
||||
else if ((*nowy->zawart) < (*y->zawart))
|
||||
y->lewy = nowy;
|
||||
else y->prawy = nowy;
|
||||
nowy->kolor = CZERWONY;
|
||||
naprawWstaw(nowy);
|
||||
};
|
||||
template <typename T> void nodrze<T>::dodaj (T co)
|
||||
{
|
||||
wezel<T> * w = new wezel<T>(NIL);
|
||||
w->lewy=w->prawy=w->ojciec=NIL;
|
||||
w->zawart = new T(co);
|
||||
dodajRBT(w);
|
||||
}
|
||||
template <typename T> void nodrze<T>::zepsuj()
|
||||
{
|
||||
int pom;
|
||||
pom = *korzen->zawart;
|
||||
*korzen->zawart = *korzen->prawy->zawart;
|
||||
*korzen->prawy->zawart = pom;
|
||||
}
|
||||
template <typename T> bool nodrze<T>::czyBST (wezel<T> * w)
|
||||
{
|
||||
if (w->prawy != NIL)
|
||||
{
|
||||
if ((*w->prawy->zawart) < (*w->zawart))
|
||||
return false;
|
||||
}
|
||||
if (w->lewy != NIL)
|
||||
{
|
||||
if((*w->lewy->zawart) > (*w->zawart))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <typename T> bool nodrze<T>::sprawdzW(wezel<T> * w)
|
||||
{
|
||||
bool ret = czyBST(w);
|
||||
if (w->prawy != NIL)
|
||||
ret&=sprawdzW(w->prawy);
|
||||
if (w->lewy != NIL)
|
||||
ret&=sprawdzW(w->lewy);
|
||||
return ret;
|
||||
}
|
||||
template <typename T> void nodrze<T>::rotacjaLewa (wezel<T> * x)
|
||||
{
|
||||
CLOG("Wykonuje lewš rotację na "<<x->zawart<<std::endl);
|
||||
wezel<T> * y = x->prawy;
|
||||
x->prawy = y->lewy; // zamiana lewego poddrzewa y na prawe poddrzewo x
|
||||
if (y->lewy != NIL) y->lewy->ojciec = x; // i przypisanie ojcostwa temu poddrzewu
|
||||
y->ojciec = x->ojciec; // ojcem y bedzie ojciec x
|
||||
if (x->ojciec == NIL)
|
||||
korzen = y;
|
||||
else if ((x->ojciec->lewy) == x)
|
||||
x->ojciec->lewy = y;
|
||||
else
|
||||
x->ojciec->prawy = y;
|
||||
y->lewy = x; // a x bedzie lewym synem y
|
||||
x->ojciec = y;
|
||||
};
|
||||
template <typename T> void nodrze<T>::rotacjaPrawa (wezel<T> * y)
|
||||
{
|
||||
CLOG("Wykonuje prawa rotację na "<<y->zawart<<std::endl);
|
||||
wezel<T> * x = y->lewy;
|
||||
y->lewy = x->prawy; // zamiana prawe poddrzewa x na lewe poddrzewo y
|
||||
if (x->prawy != NIL) x->prawy->ojciec = y; // i przypisanie ojcostwa temu poddrzewu
|
||||
x->ojciec = y->ojciec; // ojcem x bedzie ojciec y
|
||||
if (x->ojciec == NIL)
|
||||
korzen = x;
|
||||
else if ((y->ojciec->lewy) == y)
|
||||
y->ojciec->lewy = x;
|
||||
else
|
||||
y->ojciec->prawy = x;
|
||||
x->prawy = y; // a y bedzie prawym synem x
|
||||
y->ojciec = x;
|
||||
};
|
||||
template <typename T> T * nodrze<T>::nast(T czego)
|
||||
{
|
||||
wezel<T> * w = szukajIter(korzen,czego);
|
||||
if (w != NIL)
|
||||
w = nastepnik(w);
|
||||
else throw std::exception("Nie znaleziono wartosci");
|
||||
if (w != NIL)
|
||||
return (w->zawart);
|
||||
else throw std::exception("Nie znaleziono nastepnika");
|
||||
};
|
||||
template <typename T> bool nodrze<T>::czyJest(T co)
|
||||
{
|
||||
if ( szukajIter(korzen,co) != NIL )
|
||||
return true;
|
||||
else return false;
|
||||
}
|
||||
template <typename T> wezel<T> * nodrze<T>::szukajRek(wezel<T> * w, T co)
|
||||
{
|
||||
if (w==NIL || (*w->zawart)==co)
|
||||
return w;
|
||||
if (co < (*w->zawart))
|
||||
return szukajRek(w->lewy,co);
|
||||
else return szukajRek(w->prawy,co);
|
||||
};
|
||||
template <typename T> wezel<T> * nodrze<T>::szukajIter(wezel<T> * w, T co)
|
||||
{
|
||||
while (w!=NIL && (*w->zawart)!=co)
|
||||
{
|
||||
if (co < (*w->zawart))
|
||||
w=w->lewy;
|
||||
else w=w->prawy;
|
||||
}
|
||||
return w;
|
||||
};
|
||||
template <typename T> wezel<T> * nodrze<T>::minimum(wezel<T> * w)
|
||||
{
|
||||
while (w->lewy != NIL)
|
||||
w=w->lewy;
|
||||
return w;
|
||||
};
|
||||
template <typename T> wezel<T> * nodrze<T>::maksimum(wezel<T> * w)
|
||||
{
|
||||
while (w->prawy != NIL)
|
||||
w=w->prawy;
|
||||
return w;
|
||||
};
|
||||
template <typename T> wezel<T> * nodrze<T>::nastepnik(wezel<T> * w)
|
||||
{
|
||||
if (w->prawy != NIL)
|
||||
return minimum(w->prawy);
|
||||
wezel<T> * y = w->ojciec;
|
||||
while (y!= NIL && w == y->prawy)
|
||||
{
|
||||
w=y;
|
||||
y=y->ojciec;
|
||||
}
|
||||
return y;
|
||||
};
|
||||
template <typename T> wezel<T> * nodrze<T>::poprzednik(wezel<T> * w)
|
||||
{
|
||||
if (w->lewy != NIL)
|
||||
return maksimum(w->lewy);
|
||||
wezel<T> * y = w->ojciec;
|
||||
while (y!= NIL && w == y->lewy)
|
||||
{
|
||||
w=y;
|
||||
y=y->ojciec;
|
||||
}
|
||||
return y;
|
||||
};
|
||||
template <typename T> T * nodrze<T>::maksimumimum ()
|
||||
{
|
||||
wezel<T> * ret = maksimum(korzen);
|
||||
if (ret != NIL)
|
||||
return (ret->zawart);
|
||||
else throw std::exception("Drzewo jest puste");
|
||||
};
|
||||
template <typename T> T * nodrze<T>::minimumimum ()
|
||||
{
|
||||
wezel<T> * ret = minimum(korzen);
|
||||
if (ret != NIL)
|
||||
return (ret->zawart);
|
||||
else throw std::exception("Drzewo jest puste");
|
||||
};
|
||||
template <typename T> void nodrze<T>::inorder(std::ostream & strum)
|
||||
{
|
||||
in(strum,korzen);
|
||||
}
|
||||
template <typename T> void nodrze<T>::preorder(std::ostream & strum)
|
||||
{
|
||||
pre(strum,korzen);
|
||||
}
|
||||
template <typename T> void nodrze<T>::postorder(std::ostream & strum)
|
||||
{
|
||||
post(strum,korzen);
|
||||
}
|
||||
template <typename T> void nodrze<T>::in(std::ostream & strum, wezel<T> * wsk)
|
||||
{
|
||||
if (wsk==NIL)
|
||||
return;
|
||||
if (wsk->lewy != NIL)
|
||||
in(strum,wsk->lewy);
|
||||
strum << *wsk->zawart<<"\t";
|
||||
if (wsk->prawy != NIL)
|
||||
in(strum,wsk->prawy);
|
||||
};
|
||||
template <typename T> void nodrze<T>::post(std::ostream & strum, wezel<T> * wsk)
|
||||
{
|
||||
if (wsk==NIL)
|
||||
return;
|
||||
if (wsk->lewy != NIL)
|
||||
post(strum,wsk->lewy);
|
||||
if (wsk->prawy != NIL)
|
||||
post(strum,wsk->prawy);
|
||||
strum << *wsk->zawart<<"\t";
|
||||
};
|
||||
template <typename T> void nodrze<T>::pre(std::ostream & strum, wezel<T> * wsk)
|
||||
{
|
||||
if (wsk == NIL)
|
||||
return;
|
||||
strum << *wsk->zawart<<"\t";
|
||||
if (wsk->lewy != NIL)
|
||||
pre(strum,wsk->lewy);
|
||||
if (wsk->prawy != NIL)
|
||||
pre(strum,wsk->prawy);
|
||||
};
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user