【アルゴリズム演習】二分木のシリアル化と復元方法

二分木のトラバーサルは比較的一般的です。トラバースすると、空のノードも識別されてシーケンスが形成されます。このシーケンスに基づいて、二分木の構造を復元することもできます。

次のプログラムは、例として事前順序でバイナリツリーをトラバースし、再帰的にシリアル化できます。

回復するときは、スタック構造を使用して処理し、スタック内の要素にマークを追加して、識別された子ノードの数を識別します。数が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;
}

 

おすすめ

転載: blog.csdn.net/aaajj/article/details/108159321