Volendo etichettare i vertici dell'albero con elementi da un certo insieme T si può modificare la seconda clausola premettendo un argomento di tipo T nella definizione di ConsTree:
Nell'esempio l'albero è rappresentato da un puntatore ad un record che contine l'informazione sulla cardinalità, ed un puntatore al vettore che associa i figli ai padri. In questo vettore, ad esempio, il vertice con etichetta g è associato al vertice di indice 3 che ha etichetta d, perché questo vertice è il padre di g.
Si utilizzi la seguente dichiarazione di tipo:
typedef struct treevertex { T VLabel; // etichetta del vertice int Father; // indice del vertice padre } TreeVertex; // tipo degli elementi del vettore dei vertici typedef struct treevec { int Card; // cardinalita' dell'albero TreeVertex* VertexVec; // puntatore al vettore dei vertici } TreeVec; // tipo della coppia (cardinalita', vettore dei vertici) typedef TreeVec* TreeT; // tipo degli alberi finitiConcepire e realizzare un'implementazione degli alberi finiti con questa tecnica; per sperimentarla si scriva quindi il codice della coppia di funzioni:
TreeT ReadTree(String s); /* trasforma la rappresentazione parentesizzata s di un albero nel vettore dei padri */ void WriteTree(Tree t); /* stampa il vettore dei vertici in forma di una successione di coppie (etichetta, indice del padre) */dove la rappresentazione parentesizzata degli elementi di Tree(T) è definita:
() = EmptyTree (a t_1 ... t_k) = ConsTree(a,t_1, ... , t_k)Nota: il vantaggio di questa realizzazione è che in realtà possiamo utilizzarla per foreste (insiemi finiti di alberi) invece che per singoli alberi. Gli svantaggi sono una notevole rigidità (non si possono sempre aggiungere vertici ad alberi preesistenti) ed un'implementazione inefficiente delle routine di visita.
datatype Boolean, Nat, T, Tree(T); constructors: EmptyTree: Tree(T); ConsTree: T, Tree(T)* -> Tree(T); observations: IsEmptyTree: Tree(T) -> Boolean; Label: Tree(T) -> T; SubTree: Nat, Tree(T) -> Tree(T); equations: IsEmptyTree(EmptyTree) = True; IsEmptyTree(ConsTree(a,t_1, ... , t_k)) = False; Label(ConsTree(a,t_1, ... , t_k)) = a; i <= k ==> SubTree(i,ConsTree(a,t_1, ... , t_k)) = t_i; i > k ==> SubTree(i,ConsTree(a,t_1, ... , t_k)) = EmptyTree;dove A* rappresenta l'insieme delle sequenze finite di oggetti in A.
Esercizi
Quindi si riscriva il codice della coppia di funzioni (badando alla nuova forma di WriteTree):
TreeT ReadTree(String s); /* trasforma la rappresentazione parentesizzata s di un albero nell'albero binario che ne codifica la struttura */ void WriteTree(Tree t, String s); /* scrive in s la rappresentazione parentesizzata di t*/