Solutionnaire de la série 7 : arbres généraux, B.arbres (basé sur Shaffer) Partie A :
1. L’algorithme suivant est linéaire en fonction des tailles des deux arbres.
// Retourne TRUE ssi t1 et t2 sont des racines d’arbres identiques template <class Elem>
bool Compare(GTNode<Elem>* t1, GTNode<Elem>* t2) { GTNode<Elem> *c1, *c2;
if (((t1 == NULL) && (t2 != NULL)) ||((t2 == NULL) && (t1 != NULL))) return false;
if ((t1 == NULL) && (t2 == NULL)) return true;
if (t1->val() != t2->val()) return false;
c1 = t1->leftmost_child();
c2 = t2->leftmost_child();
while(!((c1 == NULL) && (c2 == NULL))) { if (!Compare(c1, c2)) return false;
if (c1 != NULL) c1 = c1->right_sibling();
if (c2 != NULL) c2 = c2->right_sibling();
} }
2 L’algorithme suivant est en (n2).
// Retourne true ssi t1 et t2 sont des racines d’arbres binaires identiques template <class Elem>
bool Compare2(BinNode<Elem>* t1, BinNode<Elem* t2) { BinNode<Elem> *c1, *c2;
if (((t1 == NULL) && (t2 != NULL)) ||((t2 == NULL) && (t1 != NULL))) return false;
if ((t1 == NULL) && (t2 == NULL)) return true;
if (t1->val() != t2->val()) return false;
if (Compare2(t1->leftchild(), t2->leftchild()) if (Compare2(t1->rightchild(), t2->rightchild()) return true;
if (Compare2(t1->leftchild(), t2->rightchild()) if (Compare2(t1->rightchild(), t2->leftchild)) return true;
return false;
}
3.
template <class Elem> // Print, postorder traversal void postprint(GTNode<Elem>* subroot) {for (GTNode<Elem>* temp = subroot->leftmost_child();temp != NULL;
temp = temp->right_sibling()) postprint(temp);
if (subroot->isLeaf()) cout << "Leaf: ";
else cout << "Internal: ";
cout << subroot->value() << "\n";
}
4.
template <class Elem> // Compte le nombre de noeuds int gencount(GTNode<Elem>* subroot) {if (subroot == NULL) return 0 int count = 1;
GTNode<Elem>* temp = rt->leftmost_child();
while (temp != NULL) { count += gencount(temp);
temp = temp->right_sibling();
}
10. template <class Elem>
BinNode<Elem>* convert(GTNode<Elem>* genroot) { if (genroot == NULL) return NULL;
GTNode<Elem>* gtemp = genroot->leftmost_child();
btemp = new BinNode(genroot->val(), convert(gtemp),convert(genroot-
>right_sibling()));
14. (a) C A / B G /// F E D D /// H / I //
(b) C’ A ’/ B’ G / F’ E’ D / H’ / I
Partie B
9.
Pour la représentation “liste d’enfants”, chaque noeud stocke une valeur et un pointeur à la liste des enfants. De plus (tous les nœuds excepté la racine) possède un enregistrement contenant un index et un pointeur indiquant la taille de la valeur comme étant D, la taille du pointeur comme étant P et la taille de l’index comme étant I. La fraction de gaspillage mémoire (overhead) estPour la représentation “Enfant gauche / frère droit ”, chaque noeud stocke trois pointeurs et une valeur. La fraction de gaspillage (overhead) mémoire est
11.
Parent(r) = (r - 1)/k si 0 < r < n.
Ième child(r) = kr + I si kr +I < n.
Frère gauche(r) = r - 1 si r mod k_ 1 et 0 < r < n.
Frere droit(r) = r + 1 si r mod k 0 et r + 1 < n.
12.
a.) la fraction de gaspillage de mémoire est
b.) la fraction de gaspillage de mémoire est
c.) la fraction de gaspillage de mémoire est
13.
Le nombre de feuilles dans un arbre non-vide de 0 noeud interne est (K- 1)0 + 1 = 1. Par conséquent le théorème est vrai.Hypothèse d’induction: Supposons que le théorème est correcte quelque soit le K- abre plein contenant n nœuds internes.
Étape d’induction Ajouter K enfants à une feuille quelconque d’un arbre de n nœuds internes. Ce nouvel arbre a un nœud interne de plus, et K-1 feuilles de plus, donc le théorème est toujours valide. Par conséquent, le théorème est vrai par le principe d’induction.
Partie C
7.
L’arbre résultant devrait avoir la structure suivante:Noeud 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Parent 4 4 4 4 -1 4 4 0 0 4 9 9 9 12 9 -1
15
16.
(a) // Utiliser une fonction d’aide avec une transmission de variable par // référence pour indiquer la position courante dans la liste d’un noeud template <class Elem>
BinNode<Elem>* convert(char* inlist) { int curr = 0;
return converthelp(inlist, curr);
}
// Au fur et à mesure que converthelp exécute la liste du noeud, curr est // incrémenter d’une manière appropriée
template <class Elem>
BinNode<Elem>* converthelp(char* inlist,int& curr) { if (inlist[curr] == ’/’) {
curr++;
return NULL;
}
BinNode<Elem>* temp = new BinNode(inlist[curr++],NULL, NULL);
temp->left = converthelp(inlist, curr);
temp->right = converthelp(inlist, curr);
return temp;
} (b)
template <class Elem>
BinNode<Elem>* convert(char* inlist) { int curr = 0;
return converthelp(inlist, curr);
}
// Au fur et à mesure que converthelp exécute la liste du noeud, curr est // incrémentée d’une manière appropriée
template <class Elem>
BinNode<Elem>* converthelp(char* inlist,int& curr) { if (inlist[curr] == ’/’) {
curr++;
return NULL;
}
BinNode<Elem>* temp = new BinNode<Elem>(inlist[curr++], NULL, NULL);
if (inlist[curr] == ’\’’) return temp;
curr++ // Eat the internal node mark.
temp->left = converthelp(inlist, curr);
temp->right = converthelp(inlist, curr);
return temp;
}
c.
//Utiliser la fonction d’aide avec une transmission de variable par //référence pour indiquer la position courante dans la liste d’un noeud template <class Elem>GTNode<Elem>* convert(char* inlist) { int curr = 0;
return converthelp(inlist, curr);
}
// Au fur et à mesure que converthelp exécute la liste du noeud, curr est // incrémentée d’une manière appropriée
template <class Elem>
GTNode<Elem>* converthelp(char* inlist,int& curr) { if (inlist[curr] == ’)’) {
curr++;
return NULL;
}
GTNode<Elem>* temp = new GTNode<Elem>(inlist[curr++]);
if (curr == ’)’) {
temp->insert_first(NULL);
return temp;
}
temp->insert_first(converthelp(inlist, curr));
while (curr != ’)’)
temp->insert_next(converthelp(inlist, curr));
curr++;
return temp;
}