KDTree树数据结构存盘和恢复的问题。
现在有一KDTree,有没有方法将其存储到磁盘,
或者说将一棵二叉树,实现存盘和读取的功能,要能保持原样。
如能给出实现代码,那更好了,这个问题困扰我很久了。
[解决办法]
采用层次遍历相类似的方法估计是可以的,用一个链式队列作为辅助
伪代码:pRoot:二叉树树根节点,Q 链式队列
(1)写文件
EnQueue(Q,pRoot); //树根进队列
fwrite(pRoot,outfile); //根节点写入文件
while( !EmptyQueue(Q))
{
DelQueue(Q,pTree);
if( pTree->lchild )
{
fwrite(pTree->lchild,outfile);
EnQueue(Q,pTree->lchild);
}
else
{
fwrite(空标记,outfile);
}
if( pTree->rchild )
{
fwrite(pTree->rchild,outfile);
EnQueue(Q,pTree->rchild);
}
else
{
fwrite(空标记,outfile);
}
}
读文件类似。
[解决办法]
baidu 搜到的代码,略微改了一下,希望对楼主有帮助。
1、存盘。
void WriteFile(char* fname,BTreeNode*BT)
//把由BT指针所指二叉树按照层次遍历的次序存储结点到文件fname中
{
ofstream ofs(fname,ios::binary);
//把由fname所指字符串作为文件名的文件定义为输出文件流ofs,并按二进制方
//式打开
LinkQueue HQ;
InitQueue(HQ);
//定义一个链接队列并进行初始化,该链接队列中结点值的类型应为二叉树结点
//的类型
BTreeNode* p;
if(BT!==NULL){
QInsert(HQ,BT)
//将树根指针插入到队列中
while(!QueueEmpty(HQ)){
p=QDelete(HQ);
//从队列中删除一个元素并赋给指针
ofs.write((char*)p,sizeof(*p));
//把p指针所指结点写入到文件中
if(p->left!=NULL)
QInsert(HQ,p->left);
//若p结点存在左孩子,则左孩子指计入队
if(p->right!=NULL)
QInsert(HQ,p->right);
//若p结点存在右孩子,则右孩子指计入队
}
}
ofs.closs();//关闭文件流对象所对应的文件
}
2、二叉树恢复:
void ReadFile(char* fname,BTreeNode*&BT)
//把fname文件中按层扫描存储的二叉树恢复到内存中,并由引用指针BT指向树根结点
{
ifstream ifs(fname,ios::in | ios::nocreate | ios::binary);
//把fname文件定义为输入文件流ifs,并按二进制方式打开
if(! ifs){
cout<<"File not open!"<<end1; exit(1);
}
LinkQueue HQ;
InitQueue(HQ);
//定义一个链接队列并进行初始化
BTreeNode *p1,*p2;
int b=sizeof(*p1);
//把二叉树结点的大小赋给b,作为读取文件的基本单位
ifs.seekg(0,ios::end);
//把文件指针移到结束位置
int n=ifs.tellg()/b;
//求出文件中所存二叉树的结点数并赋给n
ifs.seekg(0);
//将文件指针移到文件开始位置,以便从头开始读取每个结点
if(n==0){
ifs.close();
BT=NULL;
return;
}
//如果文件为空,则把BT置空后返回,用文件中的第一个结点构成树根结点并将
//该结点指针插入队列中
p1=new BTreeNode;
ifs.read((char*)p1,b);
BT=p1;
QInsert(HQ.p1);
n--;
//依次用文件中的每个结点构成新结点并把它插入到双亲结点的左孩子或右孩子位置
while(n){ //当读完文件中的结点后循环结束
p2=QDelete(HQ);//从队列中删除队首元素并赋给p2
if(p2->left!=0){//需要给p2结点添加左孩子,并使左孩子指针进队
p1=new BTreeNode;
ifs.read((char*)p1,b);
p2->left=p1;
Qinsert(HQ,p1);
n--;
}
if(p2->right!=0){//需要给p2结点添加右孩子,并使右孩子指针进队
p1=new BTreeNode;
ifs.read((char*)p1,b);
p2->right=p1;
QInsert(HQ,p1)
n--;
}
}
ifs.close();//关闭ifs对应的磁盘文件
}