VC、C++保存二叉树在文件中然后读出来

只要给每个节点按照它在二叉树中的位置给与其一个唯一的编号,那么只要记录每个节点的编号和相关信息,就能够记录一整棵二叉树
编号方式:
用n(x)表示节点x的编号
1、如果x是根节点,那么n(x)=1
2、如果x不是根节点,那么x有亲节点p;如果x是p的左子节点,那么n(x)=n(p)*2,否则n(x)=n(p)*2+1


在文件中记录格式:
节点总数
节点1编号 节点1信息
节点2编号 节点2信息
...
节点n编号 节点n信息


比如


3
3 100
1 200
2 1


这样就记录了一个有3个节点的二叉树,其中根节点信息为200,左子节点信息为1,右子节点信息为100


读取时,对于每一个编号i,从i的二进制次高位开始,逐位判断,就可以得到i所表示的节点的位置
比如i=5,它的二进制是101,除掉最高位是01
那么它就是根节点的左子节点(0)的右子节点(1)


C++代码如下

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Binary_Tree
{
private:
 struct Node
 {
 int data;
 Node *parent,*left,*right;
 Node()
 {
 parent=left=right=0;
 data=-1;
 }
 };
 Node *root;
 int size;
 void Clear(Node*);
 void Clear();//清空原先二叉树的信息 
 void Save(Node*,int,ofstream&);
public:
 Binary_Tree();
 bool Load(string);//从指定文件中读取二叉树 
 bool Save(string);//将二叉树保存于指定文件
};


void Menu_Display();


Binary_Tree T;


int main()
{
 int i;
 do
 {
 Menu_Display();
 cin>>i;
 if (i==1)
 {
 string s;
 cout<<"请输入文件名"<<endl;
 cin>>s;
 if (T.Load(s)) cout<<"读取成功"<<endl;
 else cout<<"读取失败,文件不存在或格式错误"<<endl;
 }
 else if (i==2)
 {
 string s;
 cout<<"请输入文件名"<<endl;
 cin>>s;
 if (T.Save(s)) cout<<"保存成功"<<endl;
 else cout<<"保存失败"<<endl;
 }
 cout<<endl;
 }while (i);
 return 0;
}


Binary_Tree::Binary_Tree()
{
 root=0;
 size=0;
}


bool Binary_Tree::Load(string filename)
{
 ifstream fin(filename.c_str());
 int n;
 Node *p;
 int i,j;
 int count;
 Clear();
 if (fin.fail()) return false;
 if (!(fin>>n)) return false;
 count=0;
 size=n;
 for (i=0;i<n;i++)
 {
 int id,data;
 if (!(fin>>id>>data) || id<=0)
 {
 Clear();
 fin.close();
 return false;
 }
 if (root==0)
 {
 root=new Node;
 count++;
 }
 p=root;
 for (j=30;j>=0;j--)
 if (id & (1<<j)) break;
 while (j--)
 {
 if (!(id & (1<<j)))
 {
 if (p->left==0)
 {
 p->left=new Node;
 p->left->parent=p;
 count++;
 }
 p=p->left;
 }
 else
 {
 if (p->right==0)
 {
 p->right=new Node;
 p->right->parent=p;
 count++;
 }
 p=p->right;
 }
 }
 p->data=data;
 p=0;
 }
 fin.close();
 if (count>n)
 {
 Clear();
 return false;
 }
 return true;
}


bool Binary_Tree::Save(string filename)
{
 ofstream fout(filename.c_str());
 if (fout.fail()) return false;
 fout<<size<<endl;
 if (root) Save(root,1,fout);
 fout.close();
 return true;
}


void Binary_Tree::Save(Node *p,int id,ofstream &fout)
{
 fout<<id<<' '<<p->data<<endl;
 if (p->left) Save(p->left,id*2,fout);
 if (p->right) Save(p->right,id*2+1,fout);
}


void Binary_Tree::Clear()
{
 if (root!=0) Clear(root);
 root=0;
 size=0;
}


void Binary_Tree::Clear(Node *p)
{
 if (p->left) Clear(p->left);
 if (p->right) Clear(p->right);
 delete p;
}


void Menu_Display()
{
 cout<<"----------------------------------------------------"<<endl;
 cout<<"请输入指令"<<endl;
 cout<<"输入1 从指定文件读读二叉树"<<endl;
 cout<<"输入2 将二叉树存入指定文件"<<endl;
 cout<<"输入0 退出程序"<<endl;
}



  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值