Advertisement
printesoi

Arbori AVL

May 13th, 2011
356
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.78 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4.  
  5. #define N 4
  6. #define max(a,b) ((a)>(b)?(a):(b))
  7. #define modul(a) ((a)>0?(a):-(a))
  8.  
  9. typedef struct tnod {
  10.     int val,h;
  11.     struct tnod *st,*dr;
  12. } tnod;
  13.  
  14. tnod * make(int );
  15.  
  16. tnod *findup(tnod *,tnod *);
  17.  
  18. int height(tnod *);
  19.  
  20. tnod *parent(tnod *,tnod *);
  21.  
  22. void add(tnod *&,tnod *);
  23.  
  24. int leaf(tnod *);
  25.  
  26. void prefix(tnod *,int );
  27.  
  28. void rotateL(tnod *&,tnod *);
  29.  
  30. void rotateR(tnod *&,tnod *);
  31.  
  32. void rotateRL(tnod *&,tnod *);
  33.  
  34. void rotateLR(tnod *&,tnod *);
  35.  
  36. void fixup (tnod* & , tnod* );
  37.  
  38. tnod* build();
  39.  
  40. tnod* build1();
  41.  
  42. tnod* build2();
  43.  
  44. tnod* build3();
  45.  
  46. tnod* build4();
  47.  
  48. int main()
  49. {
  50.     tnod *r = build();
  51.     prefix(r,0);
  52.     return 0;
  53. }
  54.  
  55. tnod *make(int x)
  56. {
  57.     // create nod nou cu adancime 1
  58.     tnod *nou = (tnod*)malloc(sizeof(tnod));
  59.     nou->val = x;
  60.     nou->h = 1;
  61.     nou->st = nou->dr = NULL;
  62.     return nou;
  63. }
  64.  
  65. int height(tnod *r)
  66. {
  67.     // inaltimea celui mai inalt subarbore din r
  68.     return (r==NULL?0:r->h);
  69. }
  70.  
  71. tnod *parent(tnod *r,tnod *p)
  72. {
  73.     // cauta parinte nod p in arbore cu radacina r
  74.     if (r==NULL || p==NULL || p==r)
  75.         return NULL;
  76.     if (p==r->st || p==r->dr)
  77.         return r;
  78.     if (p->val < r->val)
  79.         return parent(r->st,p);
  80.     return parent(r->dr,p);
  81. }
  82.  
  83. void add(tnod *&r,tnod *p)
  84. {
  85.     // adauga nod p in arbore cu radacina r
  86.     tnod *c;
  87.     if (r==NULL) {
  88.         // arbore vid, initializare radicina cu noul nod
  89.         r=p;
  90.         return;
  91.     }
  92.     c=r;
  93.     while ( c!=NULL ) {
  94.         if (p->val == c->val)
  95.             // daca e gasit in arbore, iesire din functie
  96.             return;
  97.  
  98.         if (p->val < c->val) {
  99.             // cauta in subarbore stang
  100.             if (c->st == NULL) {
  101.                 c->st = p;
  102.                 break;
  103.             } else
  104.                 c = c->st;
  105.         }
  106.         if (p->val > c->val) {
  107.             // cauta in subarbore drept
  108.             if (c->dr==NULL) {
  109.                 c->dr=p;
  110.                 break;
  111.             } else
  112.                 c=c->dr;
  113.         }
  114.     }
  115.  
  116.     // actualizarea inaltimilor tuturor nodurilor de deasupra celui adaugat
  117.     c=p;
  118.     while (c!=NULL) {
  119.         c->h = max(height(c->st),height(c->dr))+1;
  120.         c=parent(r,c);
  121.     }
  122. }
  123.  
  124. int leaf(tnod *r)
  125. {
  126.     // verifica daca e frunza
  127.     if (r==NULL)
  128.         return -1;
  129.     if (r->st || r->dr)
  130.         return 0;
  131.     return 1;
  132. }
  133.  
  134. void prefix(tnod *r, int sp)
  135. {
  136.     // afisare prefixata indentata
  137.     if (r==NULL)
  138.         return;
  139.     printf("%*c%d(%d)\n",sp,' ',r->val,r->h);
  140.     if (!leaf(r)) {
  141.         if (r->st)
  142.             prefix(r->st,sp+N);
  143.         else
  144.             printf("%*c-\n",sp+N,' ');
  145.         if (r->dr)
  146.             prefix(r->dr,sp+N);
  147.         else
  148.             printf("%*c-\n",sp+N,' ');
  149.     }
  150. }
  151.  
  152. void rotateL(tnod *&r,tnod *p)
  153. {
  154.     tnod *f,*c;
  155.     if (r==NULL || p==NULL)
  156.         return;
  157.     c=parent(r,p);
  158.     f = p->dr;
  159.     printf("L -> %d\n",p->val);
  160.     p->dr = f->st;
  161.     f->st = p;
  162.     if (c==NULL)
  163.         r = f;
  164.     else
  165.         c->dr=f;
  166.     c = p;
  167.     while (c!=NULL){
  168.         c->h = max(height(c->st),height(c->dr))+1;
  169.         //printf("--[%d - %d]--\n",c->val,c->h);
  170.         c = parent(r,c);
  171.     }
  172. }
  173.  
  174. void rotateR(tnod *&r,tnod *p)
  175. {
  176.     tnod *f,*c;
  177.     if (r==NULL || p==NULL)
  178.         return;
  179.     c=parent(r,p);
  180.     //printf("R -> %d\n",p->val);
  181.     f = p->st;
  182.     p->st = f->dr;
  183.     f->dr = p;
  184.    
  185.     if (c==NULL)
  186.         r = f;
  187.     else
  188.         c->st=f;
  189.     c = p;
  190.     while (c!=NULL){
  191.         c->h = max(height(c->st),height(c->dr))+1;
  192.         c = parent(r,c);
  193.     }
  194. }
  195.  
  196. void rotateRL(tnod *&r,tnod *p)
  197. {
  198.     if (r==NULL || leaf(r))
  199.         return;
  200.     rotateR(r,p->dr);
  201.     //r->h = max(height(r->st),height(r->dr))+1;
  202.     rotateL(r,p);
  203. }
  204.  
  205. void rotateLR(tnod *&r,tnod *p)
  206. {
  207.     if (r==NULL || leaf(r))
  208.         return;
  209.     rotateL(r,p->st);
  210.     //r->h = max(height(r->st),height(r->dr))+1;
  211.     rotateR(r,p);
  212. }
  213.  
  214. void fixup (tnod* & r, tnod* nou )
  215. {
  216.     // nou=ultimul nod adaugat
  217.     tnod *p,*f;
  218.     if (r==NULL || nou==NULL)
  219.         return;
  220.     p = findup(r,nou);
  221.     if (p==NULL)
  222.         return;
  223.     else
  224.         printf("-- %d --\n",p->val);
  225.     if (height(p->st) > height(p->dr)) {
  226.         //dezechilibrat stanga
  227.         f = p->st;
  228.         if (height(f->st) > height(f->dr))
  229.             rotateR(r,p);
  230.         else
  231.             rotateLR(r,p);
  232.     } else {
  233.         //dezechilibrat dreapta
  234.         f = p->dr;
  235.         if (height(f->dr) > height(f->st))
  236.             rotateL(r,p);
  237.         else
  238.             rotateRL(r,p);
  239.     }
  240. }  
  241.  
  242. tnod *findup(tnod *r,tnod *p)
  243. {
  244.     tnod *c = parent(r,p);
  245.     while ((c!=NULL && modul(height(c->st)-height(c->dr))<2))
  246.     {
  247.         c=parent(r,c);
  248.     }
  249.     return c;
  250. }
  251.  
  252. tnod* build()
  253. {
  254.     tnod *r=NULL,*c,*p;
  255.     //int v[]= {1,3,2,4,6,5,7},n=7,i;
  256.     int v[]= {5,4,1,7,8,6,0},n=6,i;
  257.     //int v[]={8,7,6,5,4,3,2,1},n=8,i;
  258.     //int i,n=33;
  259.     for (i=0;i<n;++i){
  260.         c=make(v[i]);
  261.         add(r,c);
  262.         fixup(r,c);
  263.         prefix(r,0);
  264.     }
  265.     return r;
  266. }
  267.  
  268. tnod *build1()
  269. {
  270.     tnod *r = make(1);
  271.     tnod *doi = make(2),*trei = make(3);
  272.     r->dr = doi;
  273.     r->h = 3;
  274.     doi->dr = trei;
  275.     doi->h = 2;
  276.     return r;
  277. }
  278.  
  279. tnod *build2()
  280. {
  281.     tnod *r = make(3);
  282.     tnod *doi = make(2),*unu = make(1);
  283.     r->st = doi;
  284.     r->h = 3;
  285.     doi ->st = unu;
  286.     doi -> h = 2;
  287.     return r;
  288. }
  289.  
  290. tnod *build4()
  291. {
  292.     tnod *r = make(3);
  293.     tnod *doi = make(2),*unu = make(1);
  294.     r->st = unu;
  295.     r->h = 3;
  296.     unu ->dr = doi;
  297.     unu -> h = 2;
  298.     return r;
  299. }
  300.  
  301. tnod* build3()
  302. {
  303.     tnod* r= make(1);
  304.     tnod *doi = make(2),*trei=make(3);
  305.     r->dr=trei;
  306.     r->h=3;
  307.     trei->st=doi;
  308.     trei->h=2;
  309.     return r;
  310. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement