真情大放送:一个兼容STL的tree容器

freefalcon 2004-11-16 07:27:33
经过这几天的奋战,beta版终于出来了,我下面将贴出所有代码。希望朋友能在各种平台下试用测试,并将意见反馈给我,以尽快修正。

代码较长,CSDN也不太贴代码,估计比较费劲。

先贴一段说明文字:

关于tree的说明(freefalcon 2004.11.14)
1. STL没有提供树(tree)容器,尽管map等内部是用红黑树(rb_tree)实现的,但rb_tree未被开放出来,而且rb_tree是平衡二叉搜索树,它会自动对元素排序,不能满足一般意义上的树操作。鉴于我自己以及很多朋友有这个需求,我便利用空余时间写了这个tree容器。
2. 这是一个符合STL规范的通用容器,符合数据结构中树的概念,能够满足一般的关于树的操作。目前发布的是beta版,我只在VC6.0和GCC上做过测试,欢迎各位朋友试用该容器,如果您发现任何问题(比如代码有bug或者在某个编译器下不能正常使用)以及有任何建议(比如某个算法可以改进或者需要增加某种方法),请发email到freefalcon@gmail.com,我很乐意接受您的意见和建议。
3. 我自己将tree的代码放在名为tree.hpp的文件中,我建议您也这样做。tree被封装在plux名字空间中,plux意为Portable Lightweight Utility Library(X是为了便于发音),这是我正在开发的一个开源C++库,tree只是其中的一部分,我公布的tree代码实际上包含了其它内容,比如其中的pre_upper_bound是一个独立的STL扩充算法。
4. tree要求只有一个唯一的根节点,但所提供的方法(insert_sibling)不能阻止你为根节点添加一个兄弟节点(这就叫做森林forest了),没有阻止的缘由是允许按从下至上(即从叶结点到根节点)的方式建立一棵树。但树的逻辑是只有一个唯一的根,我提供的方法也是基于此种假设,因此当root有sibling时调用某些方法会出错或者得不到预期的效果。不过我还是在拷贝构造、赋值运算以及clear方法中考虑了这种情况,以符合这三者的语义。
5. tree中提供的depth静态方法用来获得一个节点相对于根节点的深度,关于深度depth有两种不同的定义(至少我看过的数据结构书如此),差别就是根节点的深度是为0还是为1,我采用的是前者。tree的高度height则为树的最大深度加1。
6. tree的allocator被设计成这样,主要是为了搭载GCC的内部内存配置器(高效安全),而在其它编译器下则简单的使用::operator new和::operator delete进行内存的分配与释放。但GCC对内部配置器做过一次更名,我发现GCC3.0.4以前为alloc,GCC3.1以后为__alloc,因此我对此作了自动判断,但我尚不能完全确定就是在GCC3.1开始做的更改,也不能确定是否还有其它编译器使用了这样高效的内存配置策略,也许我可以搭载它,:)
7. tree采用的是child-sibling的动态存储结构,每个节点含有三个指针m_parent、m_child和m_sibling,这决定了其迭代器的--操作很低效,除非再增加一个指向前一个sibling的指针,但空间的增加会带来多大的好处?个人认为operator--操作在树中用得不是很多,因此tree的iterator的类型为ForwardIterator
8. tree的iterator长成这幅德性主要是为了支持对子树(sub tree)进行遍历,你最好使用其中的begin和end方法来确定遍历操作的起点和终点。同时,我提供了各种遍历方式的迭代器,这些迭代器可以互相转换,tree的第二个模板参数用于指定树默认的迭代器类型,但你也可以通过tree的内部定义随时使用其它遍历方式的迭代器。整个traversal iterator架构的设计还有待完善,因为目前我尚未开始二叉树(binary tree)以及其它非线性容器的编写。
9. tree提供了insert、erase、sort、unique等方法,其中insert类方法占的分量较大,以方便用户使用。我的疑问:这些方法是否都必要,或者,还有没有需要增加的方法,比如find,remove(按值删除)等,这里要考虑两个原则:一是完备性,即所有的功能都能够直接或者间接实现,二是接口最小化,尽量无冗余,但又要考虑用户的易用度,这有时就让人难以权衡,比如是否有必要让tree提供内置的find,还是让用户自己通过find范型算法实现?
10. 我还为tree提供了专门的遍历操作方法如tree_preorder_traverse等,这些方法都具有两个版本,版本一采用普通函数或者仿函数来访问节点,版本二要求用户的数据结构要采用Visitor模式。应该还存在其它形式,但我现在接触到的不是很多,因此无法进行一般性的总结。
11. ......
...全文
685 60 打赏 收藏 转发到动态 举报
写回复
用AI写文章
60 条回复
切换为时间正序
请发表友善的回复…
发表回复
freefalcon 2004-11-18
  • 打赏
  • 举报
回复
发现tree_postorder_iterator, tree_breadthfirst_iterator的begin、end方法少了重载版本,迭代器太多,忘记了,:(
并且tree_preorder_iterator、tree_postorder_iterator和tree_depthfirst_iterator在处理空树时存在问题。
已纠正。
看来一些特殊情况或者临界条件还未严格测试。

已经给上面各位朋友发送了修订版。
dudu妈 2004-11-18
  • 打赏
  • 举报
回复
给我发一份:zhaowanping2000@sina.com
redchina 2004-11-18
  • 打赏
  • 举报
回复
顶一下,你怎么不放到一个公用空间,让大家去下载呢?
freefalcon 2004-11-17
  • 打赏
  • 举报
回复
谢谢,已发出

to pacman:
主要感觉森林这种结构不是很常用,更重要的是在迭代器的设计上树和森林不太一致,因为这个迭代器既要能够对整个树进行遍历,又能够对树的某棵子树进行遍历,如果是森林的话,那么同样的算法就会在遍历子树时存在问题

而且森林也可以用树,只要为其加上一个无关紧要的根节点就行
pacman2000 2004-11-17
  • 打赏
  • 举报
回复
呵呵! 给我一份! pacman@163.com
对了,为什么不直接做成森林呢? 树也是森林的一个特例啊。
Andy84920 2004-11-17
  • 打赏
  • 举报
回复
请附上你的测试实例.
cai114 2004-11-17
  • 打赏
  • 举报
回复
amanluohan-csdn@yahoo.com.cn
谢谢。有机会我也好好看看。如果能运用自如,就更好了:)
Andy84920 2004-11-17
  • 打赏
  • 举报
回复
xiangqiuzhao@163.com

谢谢.一定研究.一定找BUG.:)
dudu妈 2004-11-17
  • 打赏
  • 举报
回复
哈哈版主好厉害,接分,并帮助版主测试哈哈
freefalcon 2004-11-17
  • 打赏
  • 举报
回复
已发出,做个标记
hunter606 2004-11-17
  • 打赏
  • 举报
回复
謝謝!
hunter606@126.com
healer_kx 2004-11-17
  • 打赏
  • 举报
回复
大侠,我在看MS的STL实现版本, xtree文件,晕死了, 你简直是天神下凡啊。

healer_kx@263.net 跪求代码:)!~
Willin 2004-11-17
  • 打赏
  • 举报
回复
用STL实现的树?有点意思
bigtree21cn 2004-11-17
  • 打赏
  • 举报
回复
bigtree21cn@21cn.com
谢谢你的劳动!
yanweiqi 2004-11-17
  • 打赏
  • 举报
回复
yanweiqi@szonetouch.com
dlyy 2004-11-17
  • 打赏
  • 举报
回复
surlover@163.com
我也想成仙呢~~
FireEmissary 2004-11-17
  • 打赏
  • 举报
回复
mark
wanlang 2004-11-17
  • 打赏
  • 举报
回复
路过,我还看不懂,帮你顶:)
alphakiller 2004-11-17
  • 打赏
  • 举报
回复
先顶再慢慢研究
hbsandy 2004-11-17
  • 打赏
  • 举报
回复
i want it hbsandy@163.com
加载更多回复(40)

64,654

社区成员

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

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