100分,求一个PHP的树形论坛代码或设计思想 也可以就查询一次,用php来构造树 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://www2.uuzone.com/blog/555080192/32744.htm 回:xuzuning(唠叨) 你说的http://www2.uuzone.com/blog/555080192/32744.htm这里的树是二叉树,但作为论坛,是N叉树啊。 回:pswdf(小邪) 把一篇帖子的回贴的ID都保存在 主题贴字段里,这样一次查询就够了你说的这个方法可以,但效率不是很高。发贴速度很慢。并且不好分页。 回:knifewolf(刀狼)N叉树可以用左儿子右兄弟的方式转换成二叉树 xuzuning(唠叨),本人数据结构学得不好哈,见笑了。 to 楼上的每次从数据库中取出有限个数的 topic 就可以了 请大家看一下面这个解决树形论坛的方法,是从网上找到的,我觉得非常好,速度非常快!:————————————————————————————————————————下面这种方法是white提出来的。BBS数据库结构的浮点数表示法BBS由一系列的文章组成,每篇文章有一些基本属性,比如作者,创建时间,文章编号等。其中最为重要的,用以表示树形结构的是层和序数。层表示位于文章树的第几层,最高层的帖子层等于0,其回复的层为1,回复的回复层为2,以此类推。所有层等于0的帖子依时间顺序其序数分别为1,2,3.....剩下的帖子的序数满足以下条件:当所有帖子按照树形显示的时候,其序数从大到小排列,没有例外。上述方法具体到BBS的实现时,各种操作如下进行:0、系统维护一个记数器,表示当前使用的整数序数。1、显示帖子列表:依序数值的大小倒序简单地显示即可,帖子的层可帮助决定退格的多少。2、新加帖子:如果是层0上的帖子,则取下一个整数序数作为该帖子序数;如果是层L1帖子,其序数为N1,则新帖子的层L=L1+1,然后到数据库中查找序数为N1的帖子的下一条帖子,取其序数,假设为N2,则新帖子的序数N=(N1+N2)/2。3、删除帖子:假设是删除层L1,序数为N1的帖子及其所有跟贴,则取层同为L1的下一个帖子的序数N2,然后删除所有序数为从N1到N2(不包括N2)的帖子。上述方法的最大优势在于显示帖子列表时不需要进行任何额外的操作,速度异常的快,根本不需要进行任何的递归操作。另外就是分页异常的方便,如果按照每页固定主题数,那么可以在SQL查询中仅仅返回当前页的记录,可以将对系统的资源利用降低到最小。即使按照每页固定帖子总数,也可以限制SQL查询仅仅返回一页所需的记录。下面是一个各种值的直观表示(为了容易理解,这里按照序数的升序排列,实际实现时将按降序,以让最后的帖子显示在最前面):1.topic1(层=0,序数=1) 5.Re:topic1(层=1,序数=1.125) 4.Re:topic1(层=1,序数=1.25) 3.Re:topic1(层=1,序数=1.5) 6.Re:Re:topic1(层=2,序数=1.75) 8.Re:Re:Re:topic1(层=3,序数=1.7875) 7.Re:Re:topic1(层=2,序数=1.825)2.topic2(层=0,序数=2) 10.Re:topic2(层=1,序数=2.5)9.topic3(层=0,序数=3) 11.Re:topic3(层=1,序数=3.5)从上面这个例子中可以看出,随着层的增加,以及跟帖的增多,其序数的尾数越来越多,因此,这种方法的一个可能的问题是,SQL SERVER中无法表示足够小的浮点数,以至于将两条帖子的序数认为是一样的了。经过实验知道,SQL SERVER的浮点数有8位,最多能支持一条帖子有1023条回贴。上述方法的另一个缺点是帖子列表时要做浮点的比较,插入帖子的时候要做浮点的加法和除法,不过除法因为刚好是除以2,所以在浮点运算时只需要较少的操作。但这属于机器指令级的开销增长,比起在脚本或VB程序里的递归导致WINDOWS系统调用的开销来要小得多,另外,对系统内存的要求降低到了最小,因此理论上认为是划算的。请您就这种方法的可行性进行分析论证,因为我想把它设计成能支持大容量用户访问的系统,所以务必经过周密的分析。 <?php$a = 1;$b = 2;$i =1;do { $a = ($a+$b)/2; printf("%d %.14f<br>", $i++,$a);}while($a != ($a+$b)/2);?>就这样在64位机上也才53层1 1.500000000000002 1.750000000000003 1.875000000000004 1.937500000000005 1.968750000000006 1.984375000000007 1.992187500000008 1.996093750000009 1.9980468750000010 1.9990234375000011 1.9995117187500012 1.9997558593750013 1.9998779296875014 1.9999389648437515 1.9999694824218816 1.9999847412109417 1.9999923706054718 1.9999961853027319 1.9999980926513720 1.9999990463256821 1.9999995231628422 1.9999997615814223 1.9999998807907124 1.9999999403953625 1.9999999701976826 1.9999999850988427 1.9999999925494228 1.9999999962747129 1.9999999981373530 1.9999999990686831 1.9999999995343432 1.9999999997671733 1.9999999998835834 1.9999999999417935 1.9999999999709036 1.9999999999854537 1.9999999999927238 1.9999999999963639 1.9999999999981840 1.9999999999990941 1.9999999999995542 1.9999999999997743 1.9999999999998944 1.9999999999999445 1.9999999999999746 1.9999999999999947 1.9999999999999948 2.0000000000000049 2.0000000000000050 2.0000000000000051 2.0000000000000052 2.0000000000000053 2.00000000000000而按照默认的计算精度得1 1.5000002 1.7500003 1.8750004 1.9375005 1.9687506 1.9843757 1.9921888 1.9960949 1.99804710 1.99902311 1.99951212 1.99975613 1.99987814 1.99993915 1.99996916 1.99998517 1.99999218 1.99999619 1.99999820 1.99999921 2.00000022 2.00000023 2.00000024 2.00000025 2.00000026 2.00000027 2.00000028 2.00000029 2.00000030 2.00000031 2.00000032 2.00000033 2.00000034 2.00000035 2.00000036 2.00000037 2.00000038 2.00000039 2.00000040 2.00000041 2.00000042 2.00000043 2.00000044 2.00000045 2.00000046 2.00000047 2.00000048 2.00000049 2.00000050 2.00000051 2.00000052 2.00000053 2.000000到22层就已经不能分辨了 如果用先序遍历同样会遇到递归吧?还有用mysql中的双精度型的话比float要好点 对树状论坛来说,有个几十层就能容纳不少回帖了,因为是多分支的,比如一个贴有2个回帖,每个再有2个,这样。。当然要避免比较极端的情况出现,比如两人互相盯着回www.rolia.net/forum看这个论坛,人气很旺,回帖也多,一般也就到20层左右。 http://www.jg1998.org/ioiforum/list.asp?boardid=4这里水大的时候达到20层还是挺正常的 我做了一个asp的,服务器能承受多少层就不知道啦从代码来看是无限层的你可以参考一下页面html和javascript代码http://www.gwnews.net/Article_Show.asp?ArticleID=22069 我的想当是这样的表结构:第一ID(serail) 第二ID(int4)第二ID=0,则是主题;第二ID=第一ID,则是第一ID的回复。递归开始:求出第二ID=0的主题,得到第一ID,搜索第二ID=第一ID的行。如果完毕,跳出!回到递归开始。这样做应该比穷举要好,效率要高点。呵呵,十五的基础太差,这个要考到十五的数据结构和算法了。 axolo(七月十五)你这种方法更慢啊。任何一个贴子都要去搜索一次它的回复,都要递归一次。 回复[axolo(七月十五)你这种方法更慢啊。任何一个贴子都要去搜索一次它的回复,都要递归一次。]不是的,递归的意思就是函数内调用函数本身,不是穷举,也不历遍。所以只要调用一个主题就可以得到全部的回复。要调用另一主题,就再递归一次。 回复[axolo(七月十五)你这种方法更慢啊。任何一个贴子都要去搜索一次它的回复,都要递归一次。]不是的,递归的意思就是函数内调用函数本身,不是穷举,也不历遍。所以只要调用一个主题就可以得到全部的回复。要调用另一主题,就再递归一次。不是吧?递归函数内部调用都是个循环啊 看看这里:http://www.dvhome.org/bbs/index.php?cid=1 php中的箭头是什么意思啊 php生成静态页面很复杂吗 php字节数转换 php url问题 请问apache下开启伪静态要改什么?我怎么总打不开这个功能呢? 如何关闭窗口 gzinflate()函数是如何操作的?是不是要用zlib函数库才能用这个函数呢? 如何用 php代码实现 ios 等多台设备的推送信息功能? php中如何识别汉字呢?得到汉字的字节数. 免费download上千部计算机录像教程 文件遍历操作疑问:怎样将所有符合条件的文件更名? 在线等!!php页面间值传递问题??
你说的这个方法可以,但效率不是很高。发贴速度很慢。并且不好分页。
每次从数据库中取出有限个数的 topic 就可以了
————————————————————————————————————————
下面这种方法是white提出来的。BBS数据库结构的浮点数表示法BBS由一系列的文章组成,每篇文章有一些基本属性,比如作者,创建时间,文章编号等。
其中最为重要的,用以表示树形结构的是层和序数。层表示位于文章树的第几层,最高
层的帖子层等于0,其回复的层为1,回复的回复层为2,以此类推。所有层等于0的帖子依
时间顺序其序数分别为1,2,3.....剩下的帖子的序数满足以下条件:当所有帖子按照树形
显示的时候,其序数从大到小排列,没有例外。上述方法具体到BBS的实现时,各种操作如下进行:
0、系统维护一个记数器,表示当前使用的整数序数。
1、显示帖子列表:依序数值的大小倒序简单地显示即可,帖子的层可帮助决定退格的多少。
2、新加帖子:如果是层0上的帖子,则取下一个整数序数作为该帖子序数;如果是层L1帖子,
其序数为N1,则新帖子的层L=L1+1,然后到数据库中查找序数为N1的帖子的下一条帖子,取
其序数,假设为N2,则新帖子的序数N=(N1+N2)/2。
3、删除帖子:假设是删除层L1,序数为N1的帖子及其所有跟贴,则取层同为L1的下一个帖子
的序数N2,然后删除所有序数为从N1到N2(不包括N2)的帖子。上述方法的最大优势在于显示帖子列表时不需要进行任何额外的操作,速度异常的快,根本不
需要进行任何的递归操作。另外就是分页异常的方便,如果按照每页固定主题数,那么可以
在SQL查询中仅仅返回当前页的记录,可以将对系统的资源利用降低到最小。即使按照每页固
定帖子总数,也可以限制SQL查询仅仅返回一页所需的记录。下面是一个各种值的直观表示(为了容易理解,这里按照序数的升序排列,实际实现时将按
降序,以让最后的帖子显示在最前面):1.topic1(层=0,序数=1)
5.Re:topic1(层=1,序数=1.125)
4.Re:topic1(层=1,序数=1.25)
3.Re:topic1(层=1,序数=1.5)
6.Re:Re:topic1(层=2,序数=1.75)
8.Re:Re:Re:topic1(层=3,序数=1.7875)
7.Re:Re:topic1(层=2,序数=1.825)
2.topic2(层=0,序数=2)
10.Re:topic2(层=1,序数=2.5)
9.topic3(层=0,序数=3)
11.Re:topic3(层=1,序数=3.5)从上面这个例子中可以看出,随着层的增加,以及跟帖的增多,其序数的尾数越来越多,因此,
这种方法的一个可能的问题是,SQL SERVER中无法表示足够小的浮点数,以至于将两条帖子的
序数认为是一样的了。经过实验知道,SQL SERVER的浮点数有8位,最多能支持一条帖子有1023
条回贴。上述方法的另一个缺点是帖子列表时要做浮点的比较,插入帖子的时候要做浮点的加法和除法,
不过除法因为刚好是除以2,所以在浮点运算时只需要较少的操作。但这属于机器指令级的开销
增长,比起在脚本或VB程序里的递归导致WINDOWS系统调用的开销来要小得多,另外,对系统内存
的要求降低到了最小,因此理论上认为是划算的。请您就这种方法的可行性进行分析论证,因为我想把它设计成能支持大容量用户访问的系统,所
以务必经过周密的分析。
$a = 1;
$b = 2;
$i =1;
do {
$a = ($a+$b)/2;
printf("%d %.14f<br>", $i++,$a);
}while($a != ($a+$b)/2);
?>
就这样在64位机上也才53层1 1.50000000000000
2 1.75000000000000
3 1.87500000000000
4 1.93750000000000
5 1.96875000000000
6 1.98437500000000
7 1.99218750000000
8 1.99609375000000
9 1.99804687500000
10 1.99902343750000
11 1.99951171875000
12 1.99975585937500
13 1.99987792968750
14 1.99993896484375
15 1.99996948242188
16 1.99998474121094
17 1.99999237060547
18 1.99999618530273
19 1.99999809265137
20 1.99999904632568
21 1.99999952316284
22 1.99999976158142
23 1.99999988079071
24 1.99999994039536
25 1.99999997019768
26 1.99999998509884
27 1.99999999254942
28 1.99999999627471
29 1.99999999813735
30 1.99999999906868
31 1.99999999953434
32 1.99999999976717
33 1.99999999988358
34 1.99999999994179
35 1.99999999997090
36 1.99999999998545
37 1.99999999999272
38 1.99999999999636
39 1.99999999999818
40 1.99999999999909
41 1.99999999999955
42 1.99999999999977
43 1.99999999999989
44 1.99999999999994
45 1.99999999999997
46 1.99999999999999
47 1.99999999999999
48 2.00000000000000
49 2.00000000000000
50 2.00000000000000
51 2.00000000000000
52 2.00000000000000
53 2.00000000000000而按照默认的计算精度得
1 1.500000
2 1.750000
3 1.875000
4 1.937500
5 1.968750
6 1.984375
7 1.992188
8 1.996094
9 1.998047
10 1.999023
11 1.999512
12 1.999756
13 1.999878
14 1.999939
15 1.999969
16 1.999985
17 1.999992
18 1.999996
19 1.999998
20 1.999999
21 2.000000
22 2.000000
23 2.000000
24 2.000000
25 2.000000
26 2.000000
27 2.000000
28 2.000000
29 2.000000
30 2.000000
31 2.000000
32 2.000000
33 2.000000
34 2.000000
35 2.000000
36 2.000000
37 2.000000
38 2.000000
39 2.000000
40 2.000000
41 2.000000
42 2.000000
43 2.000000
44 2.000000
45 2.000000
46 2.000000
47 2.000000
48 2.000000
49 2.000000
50 2.000000
51 2.000000
52 2.000000
53 2.000000
到22层就已经不能分辨了
还有用mysql中的双精度型的话比float要好点
因为是多分支的,
比如一个贴有2个回帖,每个再有2个,这样。。
当然要避免比较极端的情况出现,比如两人互相盯着回www.rolia.net/forum
看这个论坛,人气很旺,回帖也多,一般也就到20层左右。
这里水大的时候达到20层还是挺正常的
从代码来看是无限层的
你可以参考一下页面html和javascript代码
http://www.gwnews.net/Article_Show.asp?ArticleID=22069
第一ID(serail) 第二ID(int4)第二ID=0,则是主题;第二ID=第一ID,则是第一ID的回复。递归开始:求出第二ID=0的主题,得到第一ID,搜索第二ID=第一ID的行。
如果完毕,跳出!回到递归开始。这样做应该比穷举要好,效率要高点。
呵呵,十五的基础太差,这个要考到十五的数据结构和算法了。
[
axolo(七月十五)你这种方法更慢啊。
任何一个贴子都要去搜索一次它的回复,都要递归一次。
]不是的,递归的意思就是函数内调用函数本身,不是穷举,也不历遍。所以只要调用一个主题就可以得到全部的回复。要调用另一主题,就再递归一次。
[
axolo(七月十五)你这种方法更慢啊。
任何一个贴子都要去搜索一次它的回复,都要递归一次。
]不是的,递归的意思就是函数内调用函数本身,不是穷举,也不历遍。所以只要调用一个主题就可以得到全部的回复。要调用另一主题,就再递归一次。
不是吧?递归函数内部调用都是个循环啊