Advertisement
xSiRON

Alberi - PostOrder Iterativo

May 11th, 2016
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.29 KB | None | 0 0
  1. // IMPLEMENTARE UNA PILA CON I METODI DELLO STACK
  2.  
  3. #include <iostream>
  4. using namespace std;
  5.  
  6.  
  7. template <class T> class Nodo{
  8.     T* key;
  9.     Nodo<T> *left, *right, *parent;
  10.     int leftw, rightw; // peso dei sotto alberi
  11.  
  12. public:
  13.     Nodo(T* key){
  14.         this->key = new T(*key); // copia difensiva
  15.         left = right = parent = NULL;
  16.         leftw = rightw = 0;
  17.     }
  18.  
  19.     Nodo<T>* getLeft(){ return left; }
  20.     Nodo<T>* getRight(){ return right; }
  21.     Nodo<T>* getParent(){ return parent; }
  22.  
  23.     int getLeftw(){ return leftw; }
  24.     int getRightw(){ return rightw; }
  25.     T* getKey(){ return new T(*key); } // restituisco la copia della chiave
  26.  
  27.     void incRightw(){ rightw++; }
  28.     void incLeftw(){ leftw++; }
  29.  
  30.     void setLeft(Nodo<T>* left){ this->left = left; }
  31.     void setRight(Nodo<T>* right){ this->right = right; }
  32.     void setParent(Nodo<T>* parent){ this->parent = parent; }
  33.     void setKey(T* key){
  34.         if(key) this->key = new T(*key);
  35.         else this->key = NULL;
  36.     }
  37. };
  38.  
  39. template < class T > class ArrayStack{
  40.     T* q; // array
  41.     int top, length; // top: testa dello stack - length: dimensione dell'array
  42.  
  43. public:
  44.     ArrayStack(int length){
  45.         q = new T[length];
  46.         this->length = length;
  47.         top = 0;
  48.     }
  49.  
  50.     int isFull(){ return top == length; }
  51.     int isEmpty(){ return top == 0; }
  52.     int getSize(){ return top; }
  53.  
  54.     ArrayStack<T>* push(T x){
  55.         if(!isFull())
  56.             q[top++] = x;
  57.         return this;
  58.     }
  59.  
  60.     T* topItem(){
  61.         return &q[top-1];
  62.     }
  63.  
  64.     T* pop(){
  65.         if(!isEmpty())
  66.             return &q[--top];
  67.         return NULL;
  68.     }
  69.  
  70.     void print(){
  71.         for(int i = top-1; i >= 0; i--)
  72.             cout << q[i] << " ";
  73.         cout << endl;
  74.     }
  75. };
  76.  
  77.  
  78. template<class H> class SBinaryTree{
  79.     int n;
  80.     Nodo<H>* root; // radice dell'albero
  81.  
  82.     // stampo prima padri poi figli
  83.     void _preOrder(Nodo<H>* x){
  84.         if(x != NULL){
  85.             cout << *(x->getKey()) << " ";
  86.             _preOrder(x->getLeft());
  87.             _preOrder(x->getRight());
  88.         }
  89.     }
  90.  
  91.     // stampo prima figli poi padri
  92.     void _postOrder(Nodo<H>* x){
  93.         if(x != NULL){
  94.             _postOrder(x->getLeft());
  95.             _postOrder(x->getRight());
  96.             cout << *(x->getKey()) << " ";
  97.         }
  98.     }
  99.  
  100.     // stampa in ordine crescente (invertendo getLeft e getRight ordine dec)
  101.     void _inOrder(Nodo<H>* x){
  102.         if(x != NULL){
  103.             _inOrder(x->getLeft());
  104.             cout << *(x->getKey()) << " ";
  105.             _inOrder(x->getRight());
  106.         }
  107.     }
  108.  
  109.     // questa funzione calcola ricorsivamente l'altezza dell'albero
  110.     int _altezza(Nodo<H>* x, int h){
  111.         if(!x) return h-1;
  112.         int h1 = _altezza(x->getLeft(), h+1);
  113.         int h2 = _altezza(x->getRight(), h+1);
  114.         return h1 > h2 ? h1 : h2;
  115.     }
  116.  
  117.     // ricerca ricorsiva di un valore nell'albero
  118.     int _search(Nodo<H>* x, H e){
  119.         if(!x) return 0;
  120.         if(*x->getKey() == e) return 1;
  121.         if(*x->getKey() > e) return _search(x->getLeft(), e);
  122.         else return _search(x->getRight(), e);
  123.     }
  124.  
  125.     /*// ricerca ricorsiva di un nodo nell'albero - aggiunta
  126.     Nodo<H>* _search2(Nodo<H>* x, H e){
  127.         if(!x) return NULL;
  128.         if(*x->getKey() == e) return x;
  129.         if(*x->getKey() > e) return _search2(x->getLeft(), e);
  130.         else return _search2(x->getRight(), e);
  131.     }*/
  132.  
  133.     Nodo<H>* _search2(H e){
  134.         if(!root) return NULL;
  135.         Nodo<H>* x = root;
  136.         while(x && *x->getKey() != e){
  137.             if(*x->getKey() > e) x = x->getLeft();
  138.             else x = x->getRight();
  139.         }
  140.         return x;
  141.     }
  142.  
  143.     // ricerca iterativa di un valore nell'albero
  144.     int _searchIt(H e){
  145.         if(!root) return e;
  146.         Nodo<H>* x = root;
  147.         while(x && *x->getKey() != e){
  148.             if(*x->getKey() > e) x = x->getLeft();
  149.             else x = x->getRight();
  150.         }
  151.         if(x) return 1;
  152.         return 0;
  153.     }
  154.  
  155.     // questa funzione calcola ricorsivamente la profondità di un elemento (se esiste) nell'albero
  156.     int _prof(Nodo<H> *x, H e, int h){
  157.         if(!x) return -1;
  158.         if(*x->getKey() == e) return h;
  159.        
  160.         int h1 = _prof(x->getLeft(), e, h+1);
  161.         int h2 = _prof(x->getRight(), e, h+1);
  162.  
  163.         return h1 > h2 ? h1 : h2;
  164.     }
  165.  
  166.     // questa funzione restituisce il nodo contentente il valore più piccolo dell'albero
  167.     Nodo<H>* _minimum(Nodo<H> *tmp){
  168.         if(!tmp) return NULL;
  169.         Nodo<H> *x = tmp;
  170.         while(x->getLeft()) x = x->getLeft();
  171.         return x;
  172.     }
  173.  
  174.     // questa funzione restituisce il nodo contenente il valore più grande dell'albero
  175.     Nodo<H>* _maximum(Nodo<H> *tmp){
  176.         if(!tmp) return NULL;
  177.         Nodo<H> *x = tmp;
  178.         while(x->getRight()) x = x->getRight();
  179.         return x;
  180.     }
  181.  
  182.     // questa funzione restituisce il successore di un nodo
  183.     Nodo<H>* _succ(Nodo<H> *tmp){
  184.         if(!tmp) return NULL;
  185.         if(*tmp->getKey() == *maximum()) return NULL;
  186.        
  187.  
  188.         // se il nodo ha figli destri il successore è il figlio sinistro più profondo del primo figlio destro
  189.         if(tmp->getRight()) return _minimum(tmp->getRight());
  190.  
  191.         // se non ha figli destri il successore è il padre del primo figlio sinistro
  192.         Nodo<H> *x = tmp, *y = tmp->getParent();
  193.         while(y && y->getRight() == x){
  194.             x = y;
  195.             y = y->getParent();
  196.         }
  197.         return y;
  198.     }
  199.  
  200.     // qusta funzione restituisce il predecessore di un nodo
  201.     Nodo<H>* _pred(Nodo<H> *tmp){
  202.         if(!tmp) return NULL;
  203.         if(*tmp->getKey() == *minimum()) return NULL;
  204.        
  205.         // se il nodo ha figli sinistri il predecessore è il figlio destro più profondo del primo figlio sinistro
  206.         if(tmp->getLeft()) return _maximum(tmp->getLeft());
  207.  
  208.         // se non ha figli sinistri il predecessore è il padre del primo figlio destro
  209.         Nodo<H> *x = tmp, *y = tmp->getParent();
  210.         while(y && y->getLeft() == x){
  211.             x = y;
  212.             y = y->getParent();
  213.         }
  214.         return y;
  215.     }
  216.  
  217.     SBinaryTree<H>* _del(H x, Nodo<H>* r){
  218.         Nodo<H>* tmp = _search2(x);
  219.         if(!tmp) return this;
  220.  
  221.         // primo caso - 0 figli
  222.         if(!tmp->getLeft() && !tmp->getRight()){
  223.             Nodo<H> *y = tmp->getParent();
  224.             if(!y) root = NULL;
  225.             else if(y->getLeft() == tmp) y->setLeft(NULL);
  226.             else y->setRight(NULL);
  227.             return this;
  228.         }
  229.  
  230.         // terzo caso - 2 figli
  231.         if(tmp->getLeft() && tmp->getRight()){
  232.             H* s = succ(x);
  233.             _del(*s, tmp->getRight());
  234.             tmp->setKey(s);
  235.             return this;
  236.         }
  237.  
  238.         // secondo caso - 1 figlio
  239.         Nodo<H> *y = tmp->getParent(),
  240.                 *z = tmp->getLeft();
  241.  
  242.         if(!z) z = tmp->getRight();
  243.         if(!y) root = z;
  244.         else{
  245.             if(y->getLeft() == tmp) y->setLeft(z);
  246.             else y->setRight(z);
  247.         }
  248.         z->setParent(y);
  249.         return this;
  250.     }
  251.  
  252.    
  253. public:
  254.     SBinaryTree() : root(NULL), n(0) {}
  255.  
  256.     void print_inOrder(){
  257.         _inOrder(root);
  258.         cout << endl;
  259.     }
  260.  
  261.     void print_postOrder(){
  262.         _postOrder(root);
  263.         cout << endl;
  264.     }
  265.  
  266.     void print_preOrder(){
  267.         _preOrder(root);
  268.         cout << endl;
  269.     }
  270.    
  271.     // questa funzione inserisce un nodo nell'albero
  272.     SBinaryTree<H>* ins(H x){
  273.         Nodo<H> *nd = new Nodo<H>(&x);
  274.  
  275.         if(!root){
  276.             root = nd;
  277.             n++;
  278.             return this;
  279.         }
  280.  
  281.         Nodo<H> *tmp = root, *par = NULL;
  282.  
  283.         while(tmp){
  284.             par = tmp;
  285.             if(*tmp->getKey() >= x) tmp = tmp->getLeft();
  286.             else tmp = tmp->getRight();
  287.         }
  288.  
  289.         if(*par->getKey() >= x) par->setLeft(nd);
  290.         else par->setRight(nd);
  291.  
  292.         nd->setParent(par);
  293.         n++;
  294.         return this;
  295.     }
  296.    
  297.     int altezza(){
  298.         return _altezza(root, 0);
  299.     }
  300.  
  301.     int search(H e){
  302.         return _search(root, e);
  303.     }
  304.  
  305.     int searchIt(H e){
  306.         return _searchIt(e);
  307.     }
  308.  
  309.     int prof(H e){
  310.         return _prof(root, e, 0);
  311.     }
  312.  
  313.     H* minimum(){
  314.         Nodo<H> *tmp = _minimum(root);
  315.         if(tmp) return new H(*tmp->getKey());
  316.         return NULL;
  317.     }
  318.  
  319.     H* maximum(){
  320.         Nodo<H> *tmp = _maximum(root);
  321.         if(tmp) return new H(*tmp->getKey());
  322.         return NULL;
  323.     }
  324.  
  325.     H* succ(H x){
  326.         Nodo<H>* tmp = _search2(x);
  327.         if(tmp){
  328.             Nodo<H>* z = _succ(tmp);
  329.             if(z) return new H(*z->getKey());
  330.             return NULL;
  331.         }
  332.         return new H(-1);
  333.     }
  334.  
  335.     H* pred(H x){
  336.         Nodo<H>* tmp = _search2(x);
  337.         if(tmp){
  338.             Nodo<H>* z = _pred(tmp);
  339.             if(z) return new H(*z->getKey());
  340.             return NULL;
  341.         }
  342.         return new H(-1);
  343.     }
  344.  
  345.  
  346.     void printInOrderIt(){
  347.         H* tmp = minimum();
  348.         while(tmp){
  349.             cout << *tmp << " ";
  350.             tmp = succ(*tmp);
  351.         }
  352.         cout << endl;
  353.     }
  354.  
  355.     SBinaryTree<H>* del(H x){
  356.         return _del(x, root);
  357.     }
  358.  
  359.     void printPreOrderIt(){
  360.         ArrayStack<Nodo<H>*> *S = new ArrayStack<Nodo<H>*>(100);
  361.         S->push(root);
  362.         while( !S->isEmpty() ){
  363.             Nodo<H> *tmp = (*(S->pop()));
  364.             cout << *(tmp->getKey()) << " ";
  365.             if(tmp->getRight()) S->push(tmp->getRight());
  366.             if(tmp->getLeft()) S->push(tmp->getLeft());
  367.         }
  368.         cout << endl;
  369.     }
  370.  
  371.     void printPostOrderIt(){
  372.         ArrayStack< Nodo<H>* > *S = new ArrayStack< Nodo<H>* >(100);
  373.        
  374.         Nodo<H>* tmp = root;
  375.         do{
  376.             while(tmp){
  377.                 if(tmp->getRight()) S->push(tmp->getRight());
  378.                 S->push(tmp);
  379.                 tmp = tmp->getLeft();
  380.             }
  381.  
  382.             tmp = (*(S->pop()));
  383.  
  384.             if(tmp->getRight() && tmp->getRight() == (*(S->topItem()))){
  385.                 S->pop();
  386.                 S->push(tmp);
  387.                 tmp = tmp->getRight();
  388.             }
  389.  
  390.             else{
  391.                 cout << *tmp->getKey() << " ";
  392.                 tmp = NULL;
  393.             }
  394.            
  395.         }while(!S->isEmpty());
  396.         cout << endl;
  397.     }
  398. };
  399.  
  400. int main(){
  401.     SBinaryTree<int>* BT = new SBinaryTree<int>();
  402.     BT->ins(9)->ins(14)->ins(7)->ins(5)->ins(8)->ins(13)->ins(18);
  403.  
  404.     BT->print_postOrder();
  405.     //BT->print_inOrder();
  406.     //BT->printPreOrderIt();
  407.     //BT->print_preOrder();
  408.     BT->printPostOrderIt();
  409.     BT->print_inOrder();
  410.  
  411.     /*
  412.     cout << *BT->succ(9) << endl;
  413.     cout << *BT->succ(10) << endl;
  414.     cout << *BT->pred(1) << endl;
  415.     cout << *BT->pred(8) << endl;
  416.    
  417.     BT->ins(8);
  418.  
  419.     cout << *BT->succ(7) << endl;
  420.     cout << *BT->pred(8) << endl;
  421.  
  422.     /*BT->print_preOrder();
  423.     BT->print_postOrder();
  424.     BT->print_inOrder();
  425.  
  426.     cout << BT->search(5) << endl;
  427.     cout << BT->search(2) << endl;
  428.     cout << BT->searchIt(5) << endl;
  429.     cout << BT->searchIt(2) << endl;
  430.  
  431.     cout << *BT->minimum() << endl;
  432.     cout << *BT->maximum() << endl;*/
  433. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement