Fusion de 2 tas en O(log n)

Fusion de 2 tas en O(log n) - Algo - Programmation

Marsh Posté le 02-09-2004 à 20:08:56    

Salut,
 
Voila j'ai un souci de realisation d'un algo abstrait qui est sensé fusionner deux tas (representé par des arbres binaires) le tout en O(log n)
 
Les étapes pourrait être :
 
1) On séléctione la racine de l'arbre a et on l'inserer dans l'arbre b
 
2) on avance recursivement dans l'arbre a ...
 
Sachant que l'insertion se fait en O(log n) j'ai du mal. Plz help  :??:  
 
Sinon passer d'un TAS a un ABR en O(n) ? :pt1cable:  

Reply

Marsh Posté le 02-09-2004 à 20:08:56   

Reply

Marsh Posté le 02-09-2004 à 20:31:04    

Reply

Marsh Posté le 02-09-2004 à 20:39:51    

Excellent merci !
 

Reply

Marsh Posté le 03-09-2004 à 19:47:08    

C'est sympa, je ne connaissais même pas l'existence des leftist trees !  
 
Mais dans ce genre je préfére les AVLs  :)
 
Il y aurait il un autre moyen de le faire ? rien qu'avec des arbres binaires tout cons ?

Reply

Marsh Posté le 03-09-2004 à 20:56:37    

J'ai peut être pas compris ton problème, mais tu parle bien de fusionner deux tas ?
 
Parce que fusionner deux arbres binaires tout cons, c'est une opération en temps constant O(1). Il suffit de rattacher la racine d'un arbre à une feuille de l'autre arbre. Il n'est certes pas équilibré mais sans précision supplémentaire c'est l'algo optimal :D.
 
De plus, si tu veux fusionner deux tas, non gauchers (ou droitier), alors je crois que la complexité de l'opération est supérieure à O(log n1 + log n2).
 
En fait, je pense bien qu'il y a ce qu'il te faut dans le lien que je t'ai indiqué :)


Message édité par pains-aux-raisins le 03-09-2004 à 21:48:10
Reply

Marsh Posté le 03-09-2004 à 21:37:22    

Ceci peut être plus parlant pour fusionner deux tas "gauchers" :
 

Code :
  1. Merge(Node *h1, Node *h2):
  2. If h1 is null then return h2; // Fini.
  3. If h2 is null then return h1; // Fini.
  4. Else
  5. // Garantie l'ordonnancement
  6. If key(h1) > key(h2)
  7. then swap(tree(h1),  tree(h2));
  8. h1->rchild := Merge(h1->rchild, h2);
  9. // Si le tas n'est plus gaucher, on corrige.
  10. If rank(h1->lchild) < rank(h1->rchild)
  11. then swap(h1->lchild, h1->rchild);
  12. return h1;


 
Complexité : O(log n1 + log n2)


Message édité par pains-aux-raisins le 03-09-2004 à 21:46:41
Reply

Marsh Posté le 03-09-2004 à 21:51:51    

Si j'ai bien compris le "leftist" est une sorte d'AVL, chaque noeud de l'arbre comporte un champs supplementaire "nullPathLength" qui donne la longueur du plus court chemin entre le dit noeud et un noeud externe (donc vide), l'AVL a des noeuds avec un champs "déséquilibre" (au maximum 1). Donc ce champs "d" est rempli a chaque création d'un noeud dont on  
pourras supposer la complexité en O(1). C'est sympas ça quand même. :D
 
Mon probleme est bien de fusionner 2 tas (stockés sous forme d'arbres binaires donc pas de champs suppl), exemple (cas utopique :ange: ) :
 
     T1            T2     (Fusion T1 T2)=>    T3
 
      1             6                          1    
   2     3       7                        2       3
 4   5                                  4   5   6   7
                                         
 
Donc à priori T3 doit garder la propriété d'un TAS binaire (donc le déséquilibre n'est pas toléré). Sachant que T1 et T2 sont de même cardinalité (nb noeud) cad n = 2^(k+1) avec k>=0.


Message édité par Chronoklazm le 03-09-2004 à 22:58:08
Reply

Marsh Posté le 03-09-2004 à 21:59:05    

- Dans ton post precedant tu oublie volontairement de mettre a jour ce champs ??
 
- Justement le truc c'est que je ne pense pas avoir le droit a ce "rank" :(

Reply

Marsh Posté le 03-09-2004 à 22:07:33    

Dans mon exemple ils ont pas la même cardinalité zut :)
 
     T1            T2     (Fusion T1 T2)=>    T3
 
      1            3                          1    
   2           4                       2            3
 
                                  4    
 
Voila.

Reply

Marsh Posté le 03-09-2004 à 22:22:28    

Je pense que on O(log n) c'est impossible car si l'insertion, rien qu'a elle seul pompe O(log n) alors l'insertion de n éléments prendra O (n * log n).
Il y a peut etre un truc avec cette histoire de "même cardinalité" ...

Reply

Marsh Posté le 03-09-2004 à 22:22:28   

Reply

Marsh Posté le 03-09-2004 à 23:02:25    

Les "SKEW HEAPS", t'en a entendu parler ?
 
J'ai trouvé un cours en anglais sur ça, ils en parlent à la fin et ils disent que ça "amortis" la complexité a O(M*log n) ou M est le nombres d'opérations ... j'ai pas tout pigé :/
 
http://students.washington.edu/muk [...] -Heaps.ppt

Reply

Marsh Posté le 03-09-2004 à 23:31:03    

Je pense qu'il faut juste que tu trouve un "petit" moyen de mémoriser la hauteur du sous-arbre gauche et celle du sous-arbre droit soit en attribut, soit en paramètre à ta fonction de fusion.
 
A partir de là le calcul de la hauteur (rank) n'en n'est plus un et on a une complexité O(log n1 + log n2)
si n1 = n2 = n, alors complexité de O(2 * log n) = O(log n) CQFD.
 
Skew heaps : entendu parlé mais juste de nom.
 
Bon, je dois préparer mes affaires pour mes vacances...
 
Bon courage

Reply

Marsh Posté le 03-09-2004 à 23:41:43    

J'ai lu le lien. Très bon.
 
Les skew heaps seraient une amélioration algorithmique des leftist heaps. L'inconvénient de ces derniers est effectivement le stockage supplémentaire de la hauteur (ils appellent ca NullPathLength ou NPL). De plus lors de la fusion, on a tendance à alourdir d'office le sous-arbre droit alors qu'on sait pertinemment qu'on veut un arbre gaucher à la fin.
 
Donc, lors du merge, de l'arbre de plus petite racine on échange le sous-arbre gauche du sous-arbre droit, et on merge sur la gauche de cet arbre l'autre arbre de racine supérieure.
 
Ca à l'air plus simple et plus élégant que les arbres gauchers. ;)


Message édité par pains-aux-raisins le 03-09-2004 à 23:49:28
Reply

Marsh Posté le 04-09-2004 à 00:00:33    

Tout ça sans le NPL :)  
 
Bonne vacances et merci ;)


Message édité par Chronoklazm le 04-09-2004 à 00:02:01
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed