方案分析:我們知道通過二叉樹的中序和任何一個前或者後續遍歷都可以反序列化一棵二叉樹,但是這樣做有一個缺點就是,序列化的數據不能有重複的數據,否則會出錯。另外,在反序列化時,需要知道中序和另外的任意一種序列纔行,如果兩課二叉樹在字符流裏讀出,且二叉樹的數據比較多,則會相當的耗時。所以,這裏我們採取前序遍歷來完成序列化和反序列化,因爲我們都知道用前序遍歷創建過二叉樹。只不過這裏如果一旦遇到NULL結點,我們需要用其他的字符來代替它。這樣在反序列化時纔不會出錯,時間複雜度爲O(N)。
具體序列化結果如下:
#include <iostream>
using namespace std;
struct BinaryTree
{
int data;
BinaryTree *pLeft;
BinaryTree *pRight;
};
int Data[15]={0};
static int count=0;
static int count1=-1;
BinaryTree *pRoot=NULL;
BinaryTree *pRoot1=NULL;
void CreateTree(BinaryTree * &root)
{
int data;
cin>>data;
if(0==data)
root=NULL;
else
{
root=new BinaryTree;
root->data=data;
CreateTree(root->pLeft);
CreateTree(root->pRight);
}
}
void Serialize(BinaryTree *root) //序列化;
{
if(root==NULL)
{
Data[count++]=0;
cout<<"0,";
return;
}
cout<<root->data<<",";
Data[count++]=root->data;
Serialize(root->pLeft);
Serialize(root->pRight);
}
void DeSerialize(BinaryTree *&root)
{
count1++;
if(!Data[count1])
root=NULL;
else
{
root=new BinaryTree;
root->data=Data[count1];
DeSerialize(root->pLeft);
DeSerialize(root->pRight);
}
}
void preorder(BinaryTree *root)
{
if(root)
{
cout<<root->data<<" ";
preorder(root->pLeft);
preorder(root->pRight);
}
}
int main()
{
CreateTree(pRoot);
cout<<"原始序列前序遍歷:";
preorder(pRoot);
cout<<endl<<"序列化後輸出:";
Serialize(pRoot);
cout<<endl;
DeSerialize(pRoot1);//反序列化;
cout<<"反序列化後的前序遍歷輸出:";
preorder(pRoot1);
cout<<endl;
system("pause");
return 0;
}
代碼中NULL值用0代替,序列化與反序列化的運行結果: