Hier ist mein Versuch. Der Baum wird in einem Array der Größe 2 ** Tiefe + 1 gespeichert. Es wird verwendet a[0]
, um die Größe und zu haltena[size]
den Index des ersten "leeren Knotens" zu speichern, auf den es bei einer Tiefendurchquerung stößt. (Ein leerer Knoten ist der Ort, an dem ein Kind gespeichert würde, wenn das Elternteil eines hätte). Jeder leere Knoten enthält den Index des nächsten leeren Knotens, der angetroffen wird.
Bei diesem Schema wird vermieden, dass Bits reserviert werden, um die vorhandenen untergeordneten Elemente zu markieren, sodass jeder Knoten den gesamten ganzzahligen Bereich verwenden kann. Es erlaubt auch unausgeglichene Bäume - ein Elternteil kann nur ein Kind haben.
Ausgabe:
empty tree: [0]
head node only: [2,5,0]
example tree: [16,5,3,2,5,14,2,1,0,0, 0,0,9,9,15,0,4];
Der Encoder:
//utility
int findDepth(Node* n) {
int l = 0 ,r = 0;
if (n) {
l = 1 + findDepth(n->left);
r = 1 + findDepth(n->right);
}
return ( l > r ) ? l : r;
}
//Encode Function
int* encodeTree(Node* head) {
int* out;
int depth = findDepth(head);
int size = depth>0;
while (depth--) size*=2;
out = calloc(size+1,sizeof(int));
out[0]=size;
encodeNode(head, out,1, out+size);
return out;
}
void encodeNode(Node* n, int* a, int idx, int* pEmpty) {
if (n) {
a[idx]=n->data;
encodeNode(n->left,a,idx*2,pEmpty);
encodeNode(n->right,a,idx*2+1,pEmpty);
}
else if (idx<a[0]) {
*pEmpty = idx;
pEmpty = a+idx;
}
}
Der Decoder:
//Decode Function
Node* decodeArray(int* a) {
return (a[0]) ? decodeNode(a,1,a+a[0]) : NULL;
}
Node* decodeNode(int* a, int idx, int* pEmpty) {
Node* n = NULL;
if (idx== *pEmpty)
*pEmpty=a[idx];
else {
n = calloc(1,sizeof(Node));
n->data = a[idx];
if (idx*2<a[0]) {
n->left = decodeNode(a, idx*2, pEmpty);
n->right = decodeNode(a, idx*2+1, pEmpty);
}
}
return n;
}
(danke @daniel sobral für die Korrektur der Formatierung)