From 92a82b7e46403bb3777f4d2924e0e9eeb91d17b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Sat, 16 Jun 2007 13:40:46 +0000 Subject: [PATCH] Nodrze --- nodrze.h | 876 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 876 insertions(+) create mode 100644 nodrze.h diff --git a/nodrze.h b/nodrze.h new file mode 100644 index 000000000..a7f8e3f47 --- /dev/null +++ b/nodrze.h @@ -0,0 +1,876 @@ +#ifndef NODRZE +#define NODRZE +#include +#include +#ifndef LOGUJ +#define LOGUJ(a) (std::cout< 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 std::ostream & piszAdresy(std::ostream & strum, wezel & 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::ostream & operator<<(std::ostream & strum, wezel & 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")))< wezel::wezel(wezel * NIL) +{ + ojciec=NIL; lewy=NIL; prawy=NIL; kolor=CZERWONY; zawart = NULL; +} +template class nodrze +{ +private: + wezel * NIL, *ostatnio; + int ile, ktory; + void zepsuj(); + void dodajBSTC (wezel * nowy); + void dodajBST (T co); + void dodajRBT (wezel * nowy); + wezel * usunRBT (wezel * nowy); + void naprawWstaw (wezel * nowy); + void naprawUsun (wezel * x); + wezel * minimum(wezel * w); + wezel * maksimum(wezel * w); + wezel * nastepnik(wezel * w); + wezel * poprzednik(wezel * w); + wezel * szukajRek(wezel * w, T co); + wezel * szukajIter(wezel * w, T co); + void in(std::ostream & strum, wezel * wsk); + void inIt(std::ostream & strum, wezel * wsk); + void pre(std::ostream & strum, wezel * wsk); + void post(std::ostream & strum, wezel * wsk); + void rotacjaLewa (wezel * x); + void rotacjaPrawa (wezel * y); + bool czyBST (wezel * w); + bool sprawdzW(wezel * w); + void destrukcja(wezel * w); + void wypisuj(wezel * w, std::ostream & strum); + void wypisujPre(wezel * w, std::ostream & strum); +public: + wezel * korzen; + nodrze():ile(0) //najzwyczajniejszy w swiecie kosntruktor + { + NIL=new wezel(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 & 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 friend Y* operator%(nodrze & drzewko, X co); + void push_back(T co){(*this)+=co;}; +}; +template void nodrze::wypisuj(wezel * w, std::ostream & strum) +{ + if (w==NIL) return; + wypisuj(w->lewy, strum); + + strum << "Informacje o wezle: "<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")))<prawy, strum); +} +template void nodrze::wypisujPre(wezel * w, std::ostream & strum) +{ + if (w==NIL) return; + + strum << "Informacje o wezle: "<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")))<lewy, strum); + wypisujPre(w->prawy, strum); +} +template void nodrze::wypiszObficie(std::ostream & strum) +{ + strum << "Nodrze " < T* operator%(nodrze & drzewko, X co) +{ + CLOG ("Szukam " <gl->loguj); + wezel * 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 int nodrze::size() +{ + return ile; +} +template void nodrze::clear() +{ + destrukcja(korzen); + korzen=NIL; + ostatnio=NIL; + ktory=0; +} +template void nodrze::destrukcja(wezel * w) +{ + if (w==NIL) return; + destrukcja(w->lewy); + destrukcja(w->prawy); + //delete w->zawart; + delete w; +}; +template nodrze & nodrze::operator()(std::istream & potoczek) +{ + int temp; + potoczek >> temp; + for (int i=0;i> (*this); + return (*this); +} +template T* nodrze::operator()(int i) +{ + int j; + wezel * 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;jzawart); + } + else + { + ktory = i; + nasz = ostatnio; + for (i=0;izawart); + } + } + if (j==0) + { + return (ostatnio->zawart); + } + else + { + ktory = i; + if ((-j)>i) + { + nasz = minimum(korzen); + for (j=0;jzawart); + } + 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;jzawart); + } +} +template T& nodrze::operator[](int i) +{ + int j; + wezel * 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;jzawart); + } + else + { + ktory = i; + nasz = ostatnio; + for (i=0;izawart); + } + } + if (j==0) + { + return *(ostatnio->zawart); + } + else + { + ktory = i; + if ((-j)>i) + { + nasz = minimum(korzen); + for (j=0;jzawart); + } + 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;jzawart); + } +} +template bool nodrze::operator+=(T * co) +{ + wezel * w = new wezel(NIL); + w->kolor=CZERWONY; + w->zawart = co; + dodajRBT(w); + return true; +} +template bool nodrze::operator+=(T co) +{ + dodaj(co); + return true; +} +template bool nodrze::operator-=(T co) +{ + usun(co); + return true; +} +template bool nodrze::operator-=(T * co) +{ + usun(*co); + return true; +} +template T* nodrze::operator%(T * co) +{ + wezel * w = szukajIter(korzen,*co); + if (w != NIL) + return w; + else return NULL; +} +template bool nodrze::operator&(T co) +{ + return czyJest(co); +} +template bool nodrze::operator&(T * co) +{ + return czyJest(*co); +} +template class iterator +{ + /*nodrze * dd; + wezel * 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 void nodrze::inIt(std::ostream & strum, wezel * 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 bool nodrze::sprawdz() +{ + return (sprawdzW(korzen)); +}; +template T * nodrze::znajdz (T co, bool iter) +{ + return ((iter)?(szukajIter(korzen,co)->zawart):(szukajRek(korzen,co)->zawart)); +}; +template void nodrze::usun (T co) +{ + wezel * w = szukajIter(korzen, co); + usunRBT(w); + delete w; +} +template void nodrze::naprawUsun (wezel * x) +{ + wezel *w; + while ( (x != korzen) && (x->kolor == CZARNY) ) + { + CLOG("6... "<ojciec->lewy) + { + CLOG("7... "<ojciec->prawy; + if (w->kolor == CZERWONY) + { + w->kolor = CZARNY; + x->ojciec->kolor = CZERWONY; + rotacjaLewa(x->ojciec); + w = x->ojciec->prawy; + } + CLOG("8... "<lewy->kolor == CZARNY) && (w->prawy->kolor == CZARNY) ) + { + CLOG("8,1... "<kolor = CZERWONY; + x = x->ojciec; + } + else + { + CLOG("9... "<prawy->kolor == CZARNY) + { + CLOG("9,1... "<lewy->kolor = CZARNY; + w->kolor = CZERWONY; + rotacjaPrawa(w); + w = x->ojciec->prawy; + CLOG("9,2... "<kolor = x->ojciec->kolor; + x->ojciec->kolor = CZARNY; + w->prawy->kolor = CZARNY; + rotacjaLewa(x->ojciec); + x=korzen; + CLOG("9,4... "<ojciec->lewy; + if (w->kolor == CZERWONY) + { + w->kolor = CZARNY; + x->ojciec->kolor = CZERWONY; + rotacjaPrawa(x->ojciec); + w = x->ojciec->lewy; + } + CLOG("11... "<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... "<kolor = CZARNY; + CLOG("13... "< wezel * nodrze::usunRBT (wezel * nowy) +{ + CLOG ("Usuwam "<<*nowy->zawart<zawart) < (*ostatnio->zawart)) + { + ktory--; + CLOG("Ostatnio to "<<(*ostatnio->zawart)<<", czyli teraz "<<(ktory)<<" (mniej) element."<zawart< *y, *x; + if ( (nowy->lewy == NIL) || (nowy->prawy == NIL) ) + y=nowy; + else y = nastepnik(nowy); + CLOG("2... "<lewy != NIL) + x = y->lewy; + else x = y->prawy; + x->ojciec = y->ojciec; + CLOG("3... "<ojciec == NIL) + korzen = x; + else if (y == y->ojciec->lewy) + y->ojciec->lewy = x; + else + y->ojciec->prawy = x; + CLOG("4... "<kolor == CZARNY) + naprawUsun(x); + CLOG ("koniec usuwania"< void nodrze::naprawWstaw (wezel * nowy) +{ + CLOG ("Naprawiam po wstawieniu"<ojciec->kolor==CZERWONY) + { + if (nowy->ojciec == nowy->ojciec->ojciec->lewy) // ojciec nowego lest lewy + { + wezel * 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 * 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 void nodrze::dodajRBT (wezel * nowy) +{ + CLOG("Dodaje do drzewa "<zawart<zawart) < (*ostatnio->zawart)) + { + ktory++; + } + wezel * 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 void nodrze::dodaj (T co) +{ + wezel * w = new wezel(NIL); + w->lewy=w->prawy=w->ojciec=NIL; + w->zawart = new T(co); + dodajRBT(w); +} +template void nodrze::zepsuj() +{ + int pom; + pom = *korzen->zawart; + *korzen->zawart = *korzen->prawy->zawart; + *korzen->prawy->zawart = pom; +} +template bool nodrze::czyBST (wezel * 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 bool nodrze::sprawdzW(wezel * w) +{ + bool ret = czyBST(w); + if (w->prawy != NIL) + ret&=sprawdzW(w->prawy); + if (w->lewy != NIL) + ret&=sprawdzW(w->lewy); + return ret; +} +template void nodrze::rotacjaLewa (wezel * x) +{ + CLOG("Wykonuje lewą rotację na "<zawart< * 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 void nodrze::rotacjaPrawa (wezel * y) +{ + CLOG("Wykonuje prawa rotację na "<zawart< * 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 T * nodrze::nast(T czego) +{ + wezel * 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 bool nodrze::czyJest(T co) +{ + if ( szukajIter(korzen,co) != NIL ) + return true; + else return false; +} +template wezel * nodrze::szukajRek(wezel * 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 wezel * nodrze::szukajIter(wezel * w, T co) +{ + while (w!=NIL && (*w->zawart)!=co) + { + if (co < (*w->zawart)) + w=w->lewy; + else w=w->prawy; + } + return w; +}; +template wezel * nodrze::minimum(wezel * w) +{ + while (w->lewy != NIL) + w=w->lewy; + return w; +}; +template wezel * nodrze::maksimum(wezel * w) +{ + while (w->prawy != NIL) + w=w->prawy; + return w; +}; +template wezel * nodrze::nastepnik(wezel * w) +{ + if (w->prawy != NIL) + return minimum(w->prawy); + wezel * y = w->ojciec; + while (y!= NIL && w == y->prawy) + { + w=y; + y=y->ojciec; + } + return y; +}; +template wezel * nodrze::poprzednik(wezel * w) +{ + if (w->lewy != NIL) + return maksimum(w->lewy); + wezel * y = w->ojciec; + while (y!= NIL && w == y->lewy) + { + w=y; + y=y->ojciec; + } + return y; +}; +template T * nodrze::maksimumimum () +{ + wezel * ret = maksimum(korzen); + if (ret != NIL) + return (ret->zawart); + else throw std::exception("Drzewo jest puste"); +}; +template T * nodrze::minimumimum () +{ + wezel * ret = minimum(korzen); + if (ret != NIL) + return (ret->zawart); + else throw std::exception("Drzewo jest puste"); +}; +template void nodrze::inorder(std::ostream & strum) +{ + in(strum,korzen); +} +template void nodrze::preorder(std::ostream & strum) +{ + pre(strum,korzen); +} +template void nodrze::postorder(std::ostream & strum) +{ + post(strum,korzen); +} +template void nodrze::in(std::ostream & strum, wezel * 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 void nodrze::post(std::ostream & strum, wezel * 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 void nodrze::pre(std::ostream & strum, wezel * 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 \ No newline at end of file