二分木のトラバーサルは比較的一般的です。トラバースすると、空のノードも識別されてシーケンスが形成されます。このシーケンスに基づいて、二分木の構造を復元することもできます。
次のプログラムは、例として事前順序でバイナリツリーをトラバースし、再帰的にシリアル化できます。
回復するときは、スタック構造を使用して処理し、スタック内の要素にマークを追加して、識別された子ノードの数を識別します。数が0の場合、新しく追加されたノードが左側に追加されます。
数値が1の場合、スタックに追加された新しいノードが右側に追加され、フラグが2の場合、スタックの最上位要素がポップされ、新しいノードがスタックにプッシュされ、ツリー構造を復元できます。このようにループすることによって。
#include <stdio.h>
#include <stdlib.h>
struct Tree{
int val;
Tree* left;
Tree* right;
};
Tree list[300];
struct stack{
Tree* t;
int tag;
};
stack sk[300];
int slen = 0;
int num = 0;
void printTree(Tree* root)
{
if (root == 0)
{
printf("%d ", 50);
return;
}
printf("%d ", root->val);
printTree(root->left);
printTree(root->right);
}
void push(char c)
{
//50 means null node
if (c != 50)
{
list[num].val = c;
list[num].left = 0;
list[num].right = 0;
if (slen == 0)
{
sk[slen].t = &list[num];
sk[slen].tag = 0;
slen++;
num++;
return;
}
if (sk[slen-1].tag == 0)
{
sk[slen-1].t->left = &list[num];
}
else if (sk[slen-1].tag == 1)
{
sk[slen-1].t->right = &list[num];
}
sk[slen-1].tag++;
if (sk[slen-1].tag == 2)
{
slen--;
}
//add
sk[slen].t = &list[num];
sk[slen].tag = 0;
slen++;
num++;
}
else
{
if (sk[slen-1].tag == 0)
{
sk[slen-1].t->left = 0;
}
else if (sk[slen-1].tag == 1)
{
sk[slen-1].t->right = 0;
}
sk[slen-1].tag++;
if (sk[slen-1].tag == 2)
{
slen--;
}
}
}
Tree* deseq(char* buff)
{
num = 0;
int len = 0;
char c = buff[len];
while (c != 0)
{
push(c);
len++;
c = buff[len];
}
return &list[0];
}
int main()
{
// char buff[30] = {1, 50, 2, 50, 3, 50, 50, 0, 0};
char buff[30] = {1, 2, 3, 50, 2, 50, 3, 50, 50, 50, 50, 0, 0};
deseq(buff);
printTree(&list[0]);
return 0;
}