mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			913 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			913 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #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
 |