|
@@ -1,912 +1,912 @@
|
|
-#ifndef __NODRZE_H__
|
|
|
|
-#define __NODRZE_H__
|
|
|
|
-
|
|
|
|
-//don't look here, it's a horrible, partially working implementation of RB trees
|
|
|
|
-
|
|
|
|
-//ignore comment above, it is simply TowDragon's envy. Everything (without removing) is working fine
|
|
|
|
-
|
|
|
|
-#include <iostream>
|
|
|
|
-#include <fstream>
|
|
|
|
-#include <string>
|
|
|
|
-#include <vector>
|
|
|
|
-
|
|
|
|
-#define CLOG(x)
|
|
|
|
-
|
|
|
|
-const bool CZERWONY=true, CZARNY=false;
|
|
|
|
-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; //root
|
|
|
|
- nodrze():ile(0) //najzwyczajniejszy w swiecie kosntruktor // c-tor
|
|
|
|
- {
|
|
|
|
- NIL=new wezel<T>(CZARNY);
|
|
|
|
- NIL->zawart=NULL;
|
|
|
|
- korzen=NIL;
|
|
|
|
- ostatnio=NIL;
|
|
|
|
- ktory=0;
|
|
|
|
- };
|
|
|
|
- T * begin () {return minimumimum();}; //first element (=minimum)
|
|
|
|
- T * end () {return NIL;}; //
|
|
|
|
- void clear(); // czysci az do korzenia wlacznie
|
|
|
|
- // removes all elements, including root
|
|
|
|
- void usun (T co); // usuwa element z drzewa
|
|
|
|
- // remove element (value)
|
|
|
|
- bool sprawdz(); // sprawdza, czy drzewo jest poprawnym drzewem BST
|
|
|
|
- //checks if tree is correct (rather useful only for debugging)
|
|
|
|
- T * nast(T czego); // nastepnik zadanego elementu
|
|
|
|
- // successor of that element
|
|
|
|
- T * maksimumimum (); // najwiekszy element w drzewie
|
|
|
|
- //biggest element (and last)
|
|
|
|
- bool czyJest(T co); // czy cos jest w drzewie
|
|
|
|
- //check if given element is in tree
|
|
|
|
- T * minimumimum (); // najmniejszy element w drzewie
|
|
|
|
- //smallest element (first)
|
|
|
|
- void dodaj (T co); // dodaje element do drzewa
|
|
|
|
- // adds (copies)
|
|
|
|
- void inorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku inorder
|
|
|
|
- //print all elements inorder
|
|
|
|
- void preorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku preorder
|
|
|
|
- //print all elements preorder
|
|
|
|
- void postorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku postorder
|
|
|
|
- //print all elements postorder
|
|
|
|
- void wypiszObficie(std::ostream & strum); //wypisuje dane o kazdym wezle -- wymaga operatora >> dla zawartosci
|
|
|
|
- //prints info about all nodes - >> operator for T needed
|
|
|
|
- std::vector<T> vectorize(); //returns vector with all nodrze elements
|
|
|
|
- T * znajdz (T co, bool iter = true); // wyszukuje zadany element
|
|
|
|
- //search for T
|
|
|
|
- int size(); //ilosc elementow
|
|
|
|
- //returns size of tree
|
|
|
|
- T* operator()(int i) ; //n-ty element przez wskaxnik
|
|
|
|
- //returns pointer to element with index i
|
|
|
|
- nodrze<T> & operator()(std::istream & potoczek) ; //zczytanie n elemntow z listy
|
|
|
|
- //read elements from istream (first must be given amount of elements)
|
|
|
|
- T& operator[](int i) ; //dostep do obiektu, ale przez wartosc
|
|
|
|
- //returns value of object with index i
|
|
|
|
- bool operator+=(T * co); //add
|
|
|
|
- bool operator+=(T co); //add
|
|
|
|
- bool operator-=(T co); //remove
|
|
|
|
- bool operator-=(T * co); //remove
|
|
|
|
- T* operator%(T * co); // search and return pointer
|
|
|
|
- bool operator&(T co); // check if exist
|
|
|
|
- bool operator&(T * co); // check if exist
|
|
|
|
- template <typename Y, class X> friend Y* operator%(nodrze<Y> & drzewko, X co); // search and return pointer
|
|
|
|
- void push_back(T co){(*this)+=co;}; // add
|
|
|
|
-};
|
|
|
|
-template <typename T> std::vector<T> nodrze<T>::vectorize()
|
|
|
|
-{
|
|
|
|
- std::vector<T> ret;
|
|
|
|
- for (int i=0; i<ile; i++)
|
|
|
|
- ret.push_back((*this)[i]);
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-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: "<<std::flush<<w<<std::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: "<<std::flush<<w<<std::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<<std::flush<<" element, czyli "<<" ("<<ostatnio<<")"<<std::flush<<*ostatnio<<std::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);
|
|
|
|
-#ifdef _MSC_VER
|
|
|
|
- drzewko.wypiszObficie(*C->gl->loguj);
|
|
|
|
-#endif
|
|
|
|
- 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... "<<std::flush);
|
|
|
|
- if (x == x->ojciec->lewy)
|
|
|
|
- {
|
|
|
|
- CLOG("7... "<<std::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... "<<std::flush);
|
|
|
|
- if ( (w->lewy->kolor == CZARNY) && (w->prawy->kolor == CZARNY) )
|
|
|
|
- {
|
|
|
|
- CLOG("8,1... "<<std::flush);
|
|
|
|
- w->kolor = CZERWONY;
|
|
|
|
- x = x->ojciec;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- CLOG("9... "<<std::flush);
|
|
|
|
- if (w->prawy->kolor == CZARNY)
|
|
|
|
- {
|
|
|
|
- CLOG("9,1... "<<std::flush);
|
|
|
|
- w->lewy->kolor = CZARNY;
|
|
|
|
- w->kolor = CZERWONY;
|
|
|
|
- rotacjaPrawa(w);
|
|
|
|
- w = x->ojciec->prawy;
|
|
|
|
- CLOG("9,2... "<<std::flush);
|
|
|
|
- }
|
|
|
|
- CLOG("9,3... "<<std::flush);
|
|
|
|
- w->kolor = x->ojciec->kolor;
|
|
|
|
- x->ojciec->kolor = CZARNY;
|
|
|
|
- w->prawy->kolor = CZARNY;
|
|
|
|
- rotacjaLewa(x->ojciec);
|
|
|
|
- x=korzen;
|
|
|
|
- CLOG("9,4... "<<std::flush);
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- CLOG("10... "<<std::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... "<<std::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... "<<std::flush);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- x->kolor = CZARNY;
|
|
|
|
- CLOG("13... "<<std::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... "<<std::flush);
|
|
|
|
- wezel<T> *y, *x;
|
|
|
|
- if ( (nowy->lewy == NIL) || (nowy->prawy == NIL) )
|
|
|
|
- y=nowy;
|
|
|
|
- else y = nastepnik(nowy);
|
|
|
|
- CLOG("2... "<<std::flush);
|
|
|
|
- if (y->lewy != NIL)
|
|
|
|
- x = y->lewy;
|
|
|
|
- else x = y->prawy;
|
|
|
|
- x->ojciec = y->ojciec;
|
|
|
|
- CLOG("3... "<<std::flush);
|
|
|
|
- if (y->ojciec == NIL)
|
|
|
|
- korzen = x;
|
|
|
|
- else if (y == y->ojciec->lewy)
|
|
|
|
- y->ojciec->lewy = x;
|
|
|
|
- else
|
|
|
|
- y->ojciec->prawy = x;
|
|
|
|
- CLOG("4... "<<std::flush);
|
|
|
|
- if (y != nowy)
|
|
|
|
- (*nowy) = (*y); // skopiowanie
|
|
|
|
- CLOG("5... "<<std::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(ostatnio==NIL)
|
|
|
|
- {
|
|
|
|
- ostatnio = nowy;
|
|
|
|
- ktory=0;
|
|
|
|
- }
|
|
|
|
- else 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)||(co<(*w->zawart)))))
|
|
|
|
- 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)||(co<(*w->zawart))) )
|
|
|
|
- {
|
|
|
|
- if (co < (*w->zawart))
|
|
|
|
- w=w->lewy;
|
|
|
|
- else w=w->prawy;
|
|
|
|
- }
|
|
|
|
- return (w)?w:NULL;
|
|
|
|
-};
|
|
|
|
-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 // __NODRZE_H__
|
|
|
|
|
|
+#ifndef _NODRZE_H
|
|
|
|
+#define _NODRZE_H
|
|
|
|
+
|
|
|
|
+//don't look here, it's a horrible, partially working implementation of RB trees
|
|
|
|
+
|
|
|
|
+//ignore comment above, it is simply TowDragon's envy. Everything (without removing) is working fine
|
|
|
|
+
|
|
|
|
+#include <iostream>
|
|
|
|
+#include <fstream>
|
|
|
|
+#include <string>
|
|
|
|
+#include <vector>
|
|
|
|
+
|
|
|
|
+#define CLOG(x)
|
|
|
|
+
|
|
|
|
+const bool CZERWONY=true, CZARNY=false;
|
|
|
|
+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; //root
|
|
|
|
+ nodrze():ile(0) //najzwyczajniejszy w swiecie kosntruktor // c-tor
|
|
|
|
+ {
|
|
|
|
+ NIL=new wezel<T>(CZARNY);
|
|
|
|
+ NIL->zawart=NULL;
|
|
|
|
+ korzen=NIL;
|
|
|
|
+ ostatnio=NIL;
|
|
|
|
+ ktory=0;
|
|
|
|
+ };
|
|
|
|
+ T * begin () {return minimumimum();}; //first element (=minimum)
|
|
|
|
+ T * end () {return NIL;}; //
|
|
|
|
+ void clear(); // czysci az do korzenia wlacznie
|
|
|
|
+ // removes all elements, including root
|
|
|
|
+ void usun (T co); // usuwa element z drzewa
|
|
|
|
+ // remove element (value)
|
|
|
|
+ bool sprawdz(); // sprawdza, czy drzewo jest poprawnym drzewem BST
|
|
|
|
+ //checks if tree is correct (rather useful only for debugging)
|
|
|
|
+ T * nast(T czego); // nastepnik zadanego elementu
|
|
|
|
+ // successor of that element
|
|
|
|
+ T * maksimumimum (); // najwiekszy element w drzewie
|
|
|
|
+ //biggest element (and last)
|
|
|
|
+ bool czyJest(T co); // czy cos jest w drzewie
|
|
|
|
+ //check if given element is in tree
|
|
|
|
+ T * minimumimum (); // najmniejszy element w drzewie
|
|
|
|
+ //smallest element (first)
|
|
|
|
+ void dodaj (T co); // dodaje element do drzewa
|
|
|
|
+ // adds (copies)
|
|
|
|
+ void inorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku inorder
|
|
|
|
+ //print all elements inorder
|
|
|
|
+ void preorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku preorder
|
|
|
|
+ //print all elements preorder
|
|
|
|
+ void postorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku postorder
|
|
|
|
+ //print all elements postorder
|
|
|
|
+ void wypiszObficie(std::ostream & strum); //wypisuje dane o kazdym wezle -- wymaga operatora >> dla zawartosci
|
|
|
|
+ //prints info about all nodes - >> operator for T needed
|
|
|
|
+ std::vector<T> vectorize(); //returns vector with all nodrze elements
|
|
|
|
+ T * znajdz (T co, bool iter = true); // wyszukuje zadany element
|
|
|
|
+ //search for T
|
|
|
|
+ int size(); //ilosc elementow
|
|
|
|
+ //returns size of tree
|
|
|
|
+ T* operator()(int i) ; //n-ty element przez wskaxnik
|
|
|
|
+ //returns pointer to element with index i
|
|
|
|
+ nodrze<T> & operator()(std::istream & potoczek) ; //zczytanie n elemntow z listy
|
|
|
|
+ //read elements from istream (first must be given amount of elements)
|
|
|
|
+ T& operator[](int i) ; //dostep do obiektu, ale przez wartosc
|
|
|
|
+ //returns value of object with index i
|
|
|
|
+ bool operator+=(T * co); //add
|
|
|
|
+ bool operator+=(T co); //add
|
|
|
|
+ bool operator-=(T co); //remove
|
|
|
|
+ bool operator-=(T * co); //remove
|
|
|
|
+ T* operator%(T * co); // search and return pointer
|
|
|
|
+ bool operator&(T co); // check if exist
|
|
|
|
+ bool operator&(T * co); // check if exist
|
|
|
|
+ template <typename Y, class X> friend Y* operator%(nodrze<Y> & drzewko, X co); // search and return pointer
|
|
|
|
+ void push_back(T co){(*this)+=co;}; // add
|
|
|
|
+};
|
|
|
|
+template <typename T> std::vector<T> nodrze<T>::vectorize()
|
|
|
|
+{
|
|
|
|
+ std::vector<T> ret;
|
|
|
|
+ for (int i=0; i<ile; i++)
|
|
|
|
+ ret.push_back((*this)[i]);
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+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: "<<std::flush<<w<<std::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: "<<std::flush<<w<<std::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<<std::flush<<" element, czyli "<<" ("<<ostatnio<<")"<<std::flush<<*ostatnio<<std::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);
|
|
|
|
+#ifdef _MSC_VER
|
|
|
|
+ drzewko.wypiszObficie(*C->gl->loguj);
|
|
|
|
+#endif
|
|
|
|
+ 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... "<<std::flush);
|
|
|
|
+ if (x == x->ojciec->lewy)
|
|
|
|
+ {
|
|
|
|
+ CLOG("7... "<<std::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... "<<std::flush);
|
|
|
|
+ if ( (w->lewy->kolor == CZARNY) && (w->prawy->kolor == CZARNY) )
|
|
|
|
+ {
|
|
|
|
+ CLOG("8,1... "<<std::flush);
|
|
|
|
+ w->kolor = CZERWONY;
|
|
|
|
+ x = x->ojciec;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ CLOG("9... "<<std::flush);
|
|
|
|
+ if (w->prawy->kolor == CZARNY)
|
|
|
|
+ {
|
|
|
|
+ CLOG("9,1... "<<std::flush);
|
|
|
|
+ w->lewy->kolor = CZARNY;
|
|
|
|
+ w->kolor = CZERWONY;
|
|
|
|
+ rotacjaPrawa(w);
|
|
|
|
+ w = x->ojciec->prawy;
|
|
|
|
+ CLOG("9,2... "<<std::flush);
|
|
|
|
+ }
|
|
|
|
+ CLOG("9,3... "<<std::flush);
|
|
|
|
+ w->kolor = x->ojciec->kolor;
|
|
|
|
+ x->ojciec->kolor = CZARNY;
|
|
|
|
+ w->prawy->kolor = CZARNY;
|
|
|
|
+ rotacjaLewa(x->ojciec);
|
|
|
|
+ x=korzen;
|
|
|
|
+ CLOG("9,4... "<<std::flush);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ CLOG("10... "<<std::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... "<<std::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... "<<std::flush);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ x->kolor = CZARNY;
|
|
|
|
+ CLOG("13... "<<std::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... "<<std::flush);
|
|
|
|
+ wezel<T> *y, *x;
|
|
|
|
+ if ( (nowy->lewy == NIL) || (nowy->prawy == NIL) )
|
|
|
|
+ y=nowy;
|
|
|
|
+ else y = nastepnik(nowy);
|
|
|
|
+ CLOG("2... "<<std::flush);
|
|
|
|
+ if (y->lewy != NIL)
|
|
|
|
+ x = y->lewy;
|
|
|
|
+ else x = y->prawy;
|
|
|
|
+ x->ojciec = y->ojciec;
|
|
|
|
+ CLOG("3... "<<std::flush);
|
|
|
|
+ if (y->ojciec == NIL)
|
|
|
|
+ korzen = x;
|
|
|
|
+ else if (y == y->ojciec->lewy)
|
|
|
|
+ y->ojciec->lewy = x;
|
|
|
|
+ else
|
|
|
|
+ y->ojciec->prawy = x;
|
|
|
|
+ CLOG("4... "<<std::flush);
|
|
|
|
+ if (y != nowy)
|
|
|
|
+ (*nowy) = (*y); // skopiowanie
|
|
|
|
+ CLOG("5... "<<std::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(ostatnio==NIL)
|
|
|
|
+ {
|
|
|
|
+ ostatnio = nowy;
|
|
|
|
+ ktory=0;
|
|
|
|
+ }
|
|
|
|
+ else 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)||(co<(*w->zawart)))))
|
|
|
|
+ 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)||(co<(*w->zawart))) )
|
|
|
|
+ {
|
|
|
|
+ if (co < (*w->zawart))
|
|
|
|
+ w=w->lewy;
|
|
|
|
+ else w=w->prawy;
|
|
|
|
+ }
|
|
|
|
+ return (w)?w:NULL;
|
|
|
|
+};
|
|
|
|
+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 //_NODRZE_H
|