In C.
#include <stdlib.h>
#include <stdio.h>
struct Node;
typedef struct Node Node;
struct Node
{
int data;
Node* left;
Node* right;
};
/* Private Functions */
static int* encodeNode(Node* tree, int* store);
static Node* decodeNode(int** store);
/* Public Functions */
Node* newNode(int data,Node* left,Node* right);
void deleteTree(Node* tree);
int countNodesTree(Node* tree);
int* encode(Node *tree);
Node* decode(int* store);
void printTree(Node* tree);
Node* newNode(int data,Node* left,Node* right)
{
Node* result = (Node*)malloc(sizeof(Node));
result->data = data;
result->left = left;
result->right = right;
return result;
}
void deleteTree(Node* tree)
{
if (tree == NULL)
{ return;
}
deleteTree(tree->left);
deleteTree(tree->right);
free(tree);
}
int countNodesTree(Node* tree)
{
if (tree == NULL)
{ return 0;
}
return countNodesTree(tree->left)
+ countNodesTree(tree->right)
+ 1;
}
void printTree(Node* tree)
{
if (tree == NULL)
{
fprintf(stdout, "- ");
}
else
{
fprintf(stdout, "%d ", tree->data);
printTree(tree->left);
printTree(tree->right);
}
};
La codifica:
int* encode(Node *tree)
{
int nodeCount = countNodesTree(tree);
int* result = (int*)malloc(sizeof(int) * (nodeCount * 2 + 1));
// Put the node count in the first element.
// This makes it easy to also serialize this object for transport
// i.e. you can put it in a file or a stream (socket) and easily recover it.
result[0] = nodeCount;
encodeNode(tree, result + 1);
return result;
}
int* encodeNode(Node* tree, int* store)
{
if (tree != NULL)
{
store[0] = tree->data;
/*
* Slight overkill. for this question.
* But works and makes future enhancement easy
*/
store[1] = (tree->left == NULL ? 0 : 1)
+ (tree->right == NULL ? 0 : 2);
store += 2;
store = encodeNode(tree->left, store);
store = encodeNode(tree->right, store);
}
return store;
}
Il decodifica:
Node* decode(int* store)
{
if (store == NULL)
{ fprintf(stderr, "Bad Input terminating: encode() always return non NULL\n");
exit(1);
}
if (store[0] == 0)
{
return NULL;
}
store++;
return decodeNode(&store);
}
Node* decodeNode(int** store)
{
int value = (*store)[0];
int flag = (*store)[1];
(*store) += 2;
Node* left = flag & 1 ? decodeNode(store) : NULL;
Node* right = flag & 2 ? decodeNode(store) : NULL;
return newNode(value, left, right);
}
Principale:
int main()
{
Node* t = newNode(5,
newNode(3, NULL, NULL),
newNode(2,
newNode(2,
newNode(9, NULL, NULL),
newNode(9, NULL, NULL)
),
newNode(1, NULL, NULL)
)
);
printTree(t);
fprintf(stdout,"\n");
int* e = encode(t);
Node* d = decode(e);
printTree(d);
fprintf(stdout,"\n");
free(e);
deleteTree(d);
deleteTree(t);
}
Nota. Ogni nodo è codificato come due numeri interi (più uno int per il conteggio dei nodi).
Quindi l'albero fornito codifica in questo modo:
7, 5, 3, 3, 0, 2, 3, 2, 3, 9, 0, 9, 0 1, 0
^ ^
^ ^ Node 1
^
Count