Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sstream>
- #include <conio.h>
- #include <vector.h>
- using namespace std;
- int max(int a,int b){
- return (a>b) ? a : b;
- }
- class Node{
- public:
- int key;
- int h;
- char *key_char;
- Node *left;
- Node *right;
- Node(int key){
- h=1;
- key_char=new char[10];
- this->key=key;
- this->left=NULL;
- this->right=NULL;
- stringstream tmp;
- tmp<<key;
- tmp>>this->key_char;
- }
- ~Node(){
- delete [] this->key_char;
- }
- };
- class Tree_BST{
- public:
- Node *root;
- Tree_BST(){
- this->root=NULL;
- }
- bool Insert(int key){
- cout<<endl<<"Dodaje "<<key;
- if(!this->root){ //Drzewo puste
- this->root=new Node(key);
- return true;
- }
- else{ //Drzewo niepuste
- Node *it=this->root;
- Node *NewNode;
- while(true){
- if(key < it->key)
- if(it->left)
- it=it->left; //Juz istnieje it->left, idziemy w lewo
- else{
- NewNode=it->left=new Node(key); //Dodanie Node z key jako it->left
- break;
- }
- else if(key > it->key)
- if(it->right)
- it=it->right; //Juz istnieje it->right, idziemy w prawo
- else{
- NewNode=it->right=new Node(key); //Dodanie Node z key jako it->right
- break;
- }
- else{
- return false; //Klucz key juz istnieje
- }
- }
- //Scope tu = dodano jakis node, jazda z wywazaniem !!!
- vector < Node* > stack=this->Find(this->root,NewNode->key);
- for(int i=stack.size()-2 ; i >= 0 ; i--)
- stack[i]->h=Nmax(stack[i]->left,stack[i]->right)+1;
- int imb=-1;
- for(int i=stack.size()-2 ; i >= 0 ; i-- ){
- if( stack[i]->left && stack[i]->right ){
- if( abs( stack[i]->left->h - stack[i]->right->h ) > 1){
- imb=i;
- break;
- }
- }
- else if( stack[i]->left ){
- if( abs( stack[i]->left->h - 1 ) > 1){
- imb=i;
- break;
- }
- }
- else{
- if( abs( stack[i]->right->h - 1 ) > 1){
- imb=i;
- break;
- }
- }
- }
- if(stack[imb]==this->root){
- cout<<"\n*-------------------------------*\n\nRoot: (lewy,prawy) = "<<this->root->left<<"\t"<<this->root->right << "\n\t\t "<<this->root->left->key<<"\t"<<this->root->right->key<<"\n"<< "\n\t\t "<<this->root->left->h<<"\t"<<this->root->right->h<<"\n";
- cout<<endl<< (stack[imb]->left && stack[imb]->right);
- }
- if( imb != -1 ){
- if( stack[imb]->left == stack[imb+1] ){ //Lewo...
- if(stack[imb+1]->left==stack[imb+2]) //Lewo ... lewo
- this->LL(stack,imb);
- else //Lewo ... prawo
- this->LR(stack,imb);
- }
- else{ //Prawo...
- if(stack[imb+1]->left==stack[imb+2]) //Prawo ... lewo
- this->RL(stack,imb);
- else //Prawo ... prawo
- this->RR(stack,imb);
- }
- }
- stack.clear();
- return true;
- }
- }
- void Insert_multiple(int n){
- for(int i=0;i<n;i++)
- this->Insert( rand()%90001 + 9999 );
- }
- void DFS_preorder(){
- int n=0;
- this->DFS_preorder_rec(this->root,&n);
- cout<<"\nPrzeszukano "<<n<<" elementow.";
- return;
- }
- void DFS_inorder(){
- int n=0;
- this->DFS_inorder_rec(this->root,&n);
- cout<<"\nPrzeszukano "<<n<<" elementow.";
- return;
- }
- void DFS_postorder(){
- int n=0;
- this->DFS_postorder_rec(this->root,&n);
- cout<<"\nPrzeszukano "<<n<<" elementow.";
- return;
- }
- vector < Node* > Find(Node *root,int key){
- vector < Node* > stack;
- if(!root) //Drzewo puste, zwacam pusty stos
- return stack;
- if(root->key==key){ //Korzen - elementem szukanym, zwracam stos z 1 elementem
- stack.push_back(this->root);
- return stack;
- }
- Node *it=root;
- while(true){
- if(!it){ // Prawda <=> nie ma key w drzewie, zwracam pusty stos
- stack.clear();
- return stack;
- }
- stack.push_back(it);
- if(key < it->key) //Idziemy w lewo
- it=it->left;
- else if(key > it->key) //Idziemy w prawo
- it=it->right;
- else //It jest szukanym nodem - bedzie na wierzchu stosu
- return stack;
- }
- }
- bool Delete(int key){
- Node *x=NULL;
- vector < Node* > stack=Find(this->root,key); //Tak btw to o ile istnieje: stack[ stack.size()-1 ] , jest to node do usuniecia,
- Node *tmp; //a o ile istnieje: stack[ stack.size()-2 ] , jest to jego parent node!
- if( !stack.size() ) //W drzewie nie ma noda z takim kluczem
- return false;
- if( !stack[ stack.size()-1 ]->left && !stack[ stack.size()-1 ]->right ) //Node do usuniecia nie ma potomkow
- if( stack.size() == 1 ){ //Node do usuniecia jest rootem
- delete this->root;
- this->root=NULL;
- }
- else{ //Node do usuniecia nie jest rootem
- if( stack[ stack.size()-2 ]->left == stack[ stack.size()-1 ] ) //Node do usuniecia jest lewym potomkiem swojego parent noda
- stack[ stack.size()-2 ]->left=NULL;
- else //Node do usuniecia jest prawym potomkiem swojego parent noda
- stack[ stack.size()-2 ]->right=NULL;
- x=stack[ stack.size()-2 ];
- delete stack[ stack.size()-1 ];
- }
- else if( !stack[ stack.size()-1 ]->left || !stack[ stack.size()-1 ]->left ){ //Node do usuniecia ma dokladnie jednego potomka
- if( stack[ stack.size()-1 ]->left ) //Ten potomek jest lewym
- tmp=stack[ stack.size()-1 ]->left;
- else //Ten potomek jest prawym
- tmp=stack[ stack.size()-1 ]->right;
- if( stack.size() == 1 ){ //Node do usuniecia jest rootem
- this->root=tmp;
- delete stack[ stack.size()-1 ];
- }
- else{ //Node do usuniecia nie jest rootem
- if( stack[ stack.size()-2 ]->left == stack[ stack.size()-1 ] ) //Node do usuniecia jest lewym potomkiem swojego parent noda
- stack[ stack.size()-2 ]->left=tmp;
- else //Node do usuniecia jest prawym potomkiem swojego parent noda
- stack[ stack.size()-2 ]->right=tmp;
- delete stack[ stack.size()-1 ];
- x=stack[ stack.size()-2 ];
- }
- }
- else{ //Node do usuniecia ma 2 potomkow
- Node *tmp_up=stack[ stack.size()-1 ];
- Node *tmp=tmp_up->left;
- while(tmp->right){ //tmp - najwiekszy element lewego poddrzewa, zastapi usunietego noda
- tmp_up=tmp; //tmp_up - parent node tmp
- tmp=tmp->right;
- }
- x=tmp_up;
- if( stack.size() == 1 ){ //Node do usuniecia jest rootem
- if(tmp == tmp_up->left) //tmp jest lewym potomkiem tmp_up
- tmp_up->left=NULL;
- else //tmp jest prawym potomkiem tmp_up
- tmp_up->right=NULL;
- tmp->left=this->root->left;
- tmp->right=this->root->right;
- Node *tmp_root=this->root;
- this->root=tmp;
- delete tmp_root;
- }
- else{ //Node do usuniecia nie jest rootem
- if(tmp == tmp_up->left) //tmp jest lewym potomkiem tmp_up
- tmp_up->left=NULL;
- else //tmp jest prawym potomkiem tmp_up
- tmp_up->right=NULL;
- tmp->left=stack[ stack.size()-1 ]->left;
- tmp->right=stack[ stack.size()-1 ]->right;
- Node *tmp_root=stack[ stack.size()-1 ];
- if( stack[ stack.size()-1 ] == stack[ stack.size()-2 ]->left ) //Node do usuniecia jest lewym potomkiem swojego parent noda
- stack[ stack.size()-2 ]->left=tmp;
- else //Node do usuniecia jest prawym potomkiem swojego parent noda
- stack[ stack.size()-2 ]->right=tmp;
- stack[ stack.size()-1 ]=tmp;
- delete tmp_root;
- }
- }
- stack.clear();
- stack=this->Find(this->root,x->key);
- for(int i=stack.size()-2 ; i >= 0 ; i--)
- stack[i]->h=Nmax(stack[i]->left,stack[i]->right)+1;
- int imb=-1;
- cout<<"\nSzukam disbalancow:";
- for(int i=stack.size()-2 ; i >= 0 ; i-- ){
- cout<<" ; "<<stack[i]->key<<" "<<stack[i]->h;
- if( stack[i]->left && stack[i]->right ){
- if( abs( stack[i]->left->h - stack[i]->right->h ) > 1){
- cout<<"\nMam disballanca (l,r): "<<stack[i]->key<<" , "<<stack[i]->h<<" lewy: "<<stack[i]->left->key<<" , "<<stack[i]->left->h<<" prawy : "<<stack[i]->right->key<<" , "<<stack[i]->right->h;
- imb=i;
- break;
- }
- }
- else if( stack[i]->left ){
- if( abs( stack[i]->left->h - 1 ) > 1){
- cout<<"\nMam disballanca (l): "<<stack[i]->key<<" , "<<stack[i]->h<<" lewy: "<<stack[i]->left->key<<" , "<<stack[i]->left->h<<" prawy : "<<stack[i]->right;
- imb=i;
- break;
- }
- }
- else{
- if( abs( stack[i]->right->h - 1 ) > 1){
- cout<<"\nMam disballanca (r): "<<stack[i]->key<<" , "<<stack[i]->h<<" prawy : "<<stack[i]->right->key<<" , "<<stack[i]->right->h<<" lewy : "<<stack[i]->left;
- imb=i;
- break;
- }
- }
- }
- if(stack[imb]==this->root){
- cout<<"\n*-------------------------------*\n\nRoot: (lewy,prawy) = "<<this->root->left<<"\t"<<this->root->right << "\n\t\t "<<this->root->left->key<<"\t"<<this->root->right->key<<"\n"<< "\n\t\t "<<this->root->left->h<<"\t"<<this->root->right->h<<"\n";
- cout<<endl<< (stack[imb]->left && stack[imb]->right);
- }
- if( imb != -1 ){
- if( stack[imb]->left == stack[imb+1] ){ //Lewo...
- if(stack[imb+1]->left==stack[imb+2]) //Lewo ... lewo
- this->LL(stack,imb);
- else //Lewo ... prawo
- this->LR(stack,imb);
- }
- else{ //Prawo...
- if(stack[imb+1]->left==stack[imb+2]) //Prawo ... lewo
- this->RL(stack,imb);
- else //Prawo ... prawo
- this->RR(stack,imb);
- }
- }
- stack.clear();
- return true;
- }
- ~Tree_BST(){
- this->Delete_whole();
- }
- void Delete_whole(){
- this->Delete_whole_rec(this->root);
- this->root=NULL;
- }
- private:
- int Nmax(Node *a,Node *b){
- int arg1 = (a) ? a->h : 1;
- int arg2 = (b) ? b->h : 1;
- return max(arg1,arg2);
- }
- void LL(vector < Node* > stack,int imb){ //Rotacja lewo ... lewo
- Node *c=stack[imb];
- Node *b=c->left;
- Node *a=b->left;
- Node *T0=a->left;
- Node *T1=a->right;
- Node *T2=b->right;
- Node *T3=c->right;
- a->h=Nmax(T0,T1)+1; //Te wysokosci sie zmienia
- c->h=Nmax(T2,T3)+1;
- b->h=Nmax(a,c)+1;
- if(this->root==c) //c jest rootem, trzeba ustawic nowy
- this->root=b;
- else //c nie jest rootem
- if(stack[imb] == stack[imb-1]->left)
- stack[imb-1]->left=b;
- else
- stack[imb-1]->right=b;
- b->left=a; //Rotacja
- b->right=c;
- c->left=T2;
- cout<<"\nLL";
- return;
- }
- void LR(vector < Node* > stack,int imb){ //Rotacja lewo ... prawo
- Node *c=stack[imb];
- Node *a=c->left;
- Node *b=a->right;
- Node *T0=a->left;
- Node *T1=b->left;
- Node *T2=b->right;
- Node *T3=c->right;
- a->h=Nmax(T0,T1)+1;
- c->h=Nmax(T2,T3)+1; //Te wysokosci sie zmienia
- b->h=Nmax(a,c)+1;
- if(this->root==c) //c jest rootem, trzeba ustawic nowy
- this->root=b;
- else //c nie jest rootem
- if(stack[imb] == stack[imb-1]->left)
- stack[imb-1]->left=b;
- else
- stack[imb-1]->right=b;
- b->left=a; //Rotacja
- b->right=c;
- a->right=T1;
- c->left=T2;
- cout<<"\nLR";
- return;
- }
- void RL(vector < Node* > stack,int imb){ //Rotacja prawo ... lewo
- Node *a=stack[imb];
- Node *c=a->right;
- Node *b=c->left;
- Node *T0=a->left;
- Node *T1=b->left;
- Node *T2=b->right;
- Node *T3=c->right;
- a->h=Nmax(T0,T1)+1;
- c->h=Nmax(T2,T3)+1; //Te wysokosci sie zmienia
- b->h=Nmax(a,c)+1;
- if(this->root==a) //a jest rootem, trzeba ustawic nowy
- this->root=b;
- else //a nie jest rootem
- if(stack[imb] == stack[imb-1]->left)
- stack[imb-1]->left=b;
- else
- stack[imb-1]->right=b;
- b->left=a; //Rotacja
- b->right=c;
- a->right=T1;
- c->left=T2;
- cout<<"\nRL";
- return;
- }
- void RR(vector < Node* > stack,int imb){ //Rotacja prawo ... prawo
- Node *a=stack[imb];
- Node *b=a->right;
- Node *c=b->right;
- Node *T0=a->left;
- Node *T1=b->left;
- Node *T2=c->left;
- Node *T3=c->right;
- a->h=Nmax(T0,T1)+1;
- c->h=Nmax(T2,T3)+1; //Te wysokosci sie zmienia
- b->h=Nmax(a,c)+1;
- if(this->root==a) //a jest rootem, trzeba ustawic nowy
- this->root=b;
- else //a nie jest rootem
- if(stack[imb] == stack[imb-1]->left)
- stack[imb-1]->left=b;
- else
- stack[imb-1]->right=b;
- b->left=a; //Rotacja
- b->right=c;
- a->right=T1;
- cout<<"\nRR";
- return;
- }
- void Delete_whole_rec(Node *it){
- if(it){
- if(it->left)
- Delete_whole_rec(it->left);
- if(it->right)
- Delete_whole_rec(it->right);
- delete it;
- }
- return;
- }
- void DFS_preorder_rec(Node *it,int *n){
- if(it){
- *n+=1;
- cout<<endl<<it->key<<"\t"<<it->h;
- if(it->left){
- cout<<"\t<-";
- DFS_preorder_rec(it->left,n);
- }
- if(it->right){
- cout<<"\t->";
- DFS_preorder_rec(it->right,n);
- }
- }
- return;
- }
- void DFS_inorder_rec(Node *it,int *n){
- if(it){
- if(it->left)
- DFS_inorder_rec(it->left,n);
- *n+=1;
- cout<<endl<<it->key;
- if(it->right)
- DFS_inorder_rec(it->right,n);
- }
- }
- void DFS_postorder_rec(Node *it,int *n){
- if(it){
- if(it->left)
- DFS_inorder_rec(it->left,n);
- if(it->right)
- DFS_inorder_rec(it->right,n);
- *n+=1;
- cout<<endl<<it->key;
- }
- }
- };
- int main(){
- Tree_BST *Tree=new Tree_BST();
- Tree->Delete_whole();
- Tree->Insert(0);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(-10);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(5);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(4);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(-6);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(1);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(2);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(-13);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(13);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(-7);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(65);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(8);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(-12);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- Tree->Insert(6);
- cout<<"\nUsuwam cos...";
- Tree->Delete(0);
- cout<<endl<<endl<<"Drzewko preorder:";
- Tree->DFS_preorder();
- delete Tree;
- getche();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement