求教: 关于二叉树的永久问题

hxblvc 2004-06-14 02:16:15
大家好
我前一段时间帮朋友做比设时,程序的据是用二叉树时组织的

程序退出时要将这个二叉树保存, 程序起动时又将它读入内存, 且要和原的那个树的结构一样!

我用的办法是: 1.先对这个二叉树时很填充,将它填充成完全的,空白部分用空结点填充
(注:我的这棵树只有0.001的可能性是完全二叉树)
2.将填充后的二叉树保存(广度优先,也就是一层一层的将数据联续保存)
3.程序起动时将数据读进来(按须将数据读入),建成完全二叉树,再把其
中的空结点取了,就可以恢复成我原来的那个树了


我这个方法是可以实现对二叉树的永久化,但是,我的树一般不可能是一个完全二叉树,所以我现在想找一个更有效的办法,,然后写一个二叉树的类,以后用到时就可以直接用了

当时时间太急,我没有太多的去优化,这几天没事,就把这个问题想了一下,但也想不出个办法来,就想和大家一起讨论一下.
...全文
149 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
hxblvc 2004-06-18
  • 打赏
  • 举报
回复
谢谢各位!结了
rorot 2004-06-15
  • 打赏
  • 举报
回复
至于要保存么?
一颗红黑树的完成20万随机的long数据初始化大约花费600毫秒
一颗AVL树完成20万随机数的初始化大约得1500毫秒吧
如果你得数据不是几百几千万,没必要存储.
Leaveye 2004-06-14
  • 打赏
  • 举报
回复
我就有点不明白了。
就按照树的结构,找个先序遍历的顺序存不行么?

就把原来地址换成数值作为关系,之后读入还不行是么?
boxban 2004-06-14
  • 打赏
  • 举报
回复
我的想法是:
按照广度优先保存二叉树,在保存时,为每个节点增加3个关系标志字段:(节点编号,父节点编号, 左孩子)。
对于某个具体节点来说:节点编号就是自身节点指针,父节点编号就是该节点父节点的节点指针。对于根节点,其父节点编号为0。如果该节点是其父节点的左孩子,在“左孩子”字段为1,否则为0。

保存过程的伪代码如下:
typedef unsigned int NODE_INDEX_T;
typedef struct _tagRelationship{
NODE_INDEX_T me;
NODE_INDEX_T parent;
BOOL is_left;
}NODE_RELATION;

void saveNode(NODE* p, NODE* pParent)
{
保存p节点数据(不含左右孩子指针);
NODE_RELATION nr;
nr.me = p;
nr.parent = pParent;
nr.is_left = (pParent->left_child == me);
保存nr;
}

在读取文件时,可按下列步骤恢复二叉树:

std::map<NODE_INDEX_T, NODE*> m;

NODE_RELATION nr;
while(没有到达文件尾){
读取一个节点数据;
读取附加标志字段到nr;

NODE* p = new NODE;
初始化节点数据,包括左右孩子指针;

//添加节点编号--〉节点地址的映射
m[nr.me] = p;

if (nr.parent != 0){ //该节点的“父节点编号” != 0
NODE* pParent = map[nr.parent];
assert(pParent != NULL);
p->parent = pParent;
if (nr.is_left)//是“左孩子”吗?
pParent->left_child = p;
else pParent->right_child = p;
}
}

该方法的缺点是需要保存较多的附加数据以恢复各节点之间原有的关系。

如果有比较简便的方法判断一个节点是其父节点的左孩之还是右孩子,可以不保存“左孩子”标志,而是在恢复二叉树是通过比较子节点、父节点的数据来判定其是左孩子还是右孩子。
hxblvc 2004-06-14
  • 打赏
  • 举报
回复
等侍牛人ing..................
hxblvc 2004-06-14
  • 打赏
  • 举报
回复
太安静了一点

没有讨论的气份
hxblvc 2004-06-14
  • 打赏
  • 举报
回复
谢谢各位高手的指导,不过

sandrowjw(酒神节的萨提尔) 和 zchuer(番茄骑士)
方法主要问题就是如果树太大的话不太好用,可以用在小规模数据上

boxban(master-dreamer) 的方法在结点的数据域很大是是可取的,用起来还不错

不过数据域太小就有点奢侈了,

不知过有没有更好的方法.......

大家继续讨论啊


zchuer 2004-06-14
  • 打赏
  • 举报
回复
用两种遍历方式保存原来的二叉树序列,恢复时就没有问题,不必先扩充成完全二叉树
不过这样做时间效率和空间效率未必比原来的方法高……
sandrowjw 2004-06-14
  • 打赏
  • 举报
回复
有一个办法,不过存大树的方法不是很方便,而且Load的时候有点算法时间。
可以先把二叉树的所有节点编个号然后按顺序保存,再保存二叉树的前序和中序序列,Load的时候根据两个序列重新建树(数据结构题目,呵呵)。
hxblvc 2004-06-14
  • 打赏
  • 举报
回复
晕,指错好多字
先谢谢大家了

自己生顶

呵呵

64,644

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧