PHP网站制作之php:树形布局的算法1
我假设你目前已经可以完成一个静态页面了,当然,做的好看难看是另外一说,皮皮我的第一个网页也没好看到哪去,但是“孩子”再丑,咱们做“爹妈”的也不能嫌弃不是?这毕竟是咱的成果。 从喜悦村上转载,之前也读过此文,讲述得仍是对照清晰的。产物分类,多级的树状布局的服装论坛,邮件列表等很多中央咱们城市碰到如许的成绩:若何存储多级布局的数据?
在PHP的使用中,供应后台数据存储的凡是是关系型数据库,它可以保留大批的数据,供应高效的数据检索和更新办事。但是关系型数据的根基模式是犬牙交错的表,是一个立体的布局,假如要将多级树状布局存储在关系型数据库里就需求停止公道的翻译任务。接上去我会将本人的所见所闻和一些适用的经历和人人切磋一下。
层级布局的数据保留在立体的数据库中根基上有两种经常使用设计办法:
毗连目次形式(adjacency list model)
预排序遍历树算法(modified preorder tree traversal algorithm)
我不是盘算机专业的,也没有学过甚么数据布局的器材,所以这两个名字都是我本人依照字面的意思翻的,假如说错了还请多多指教。
这两个器材听着仿佛很吓人,其实十分轻易了解。这里我用一个复杂食物目次作为咱们的示例数据。 咱们的数据布局是如许的:
Food
|
|---Fruit
| |
| |---Red
| | |
| | |--Cherry
| |
| |---Yellow
| |
| |--Banana
|
|---Meat
|
|--Beef
|
|--Pork
为了照料那些英文乌烟瘴气的PHP喜好者
Food:食品
Fruit:生果
Red:白色
Cherry:樱桃
Yellow:黄色
Banana:喷鼻蕉
Meat:肉类
Beef:牛肉
Pork:猪肉
毗连目次形式(adjacency list model)
这类形式咱们常常用到,良多的教程和书中也引见过。咱们经由过程给每一个节点增添一个属性 parent 来暗示这个节点的父节点从而将全部树状布局经由过程立体的表描写出来。依据这个准绳,例子中的数据可以转化成以下的表:
+-----------------------+
| parent | name |
+-----------------------+
| | Food |
| Food | Fruit |
| Fruit | Green |
| Green | Pear |
| Fruit | Red |
| Red | Cherry |
| Fruit | Yellow |
| Yellow | Banana |
| Food | Meat |
| Meat | Beef |
| Meat | Pork |
+-----------------------+
咱们看到 Pear 是Green的一个子节点,Green是Fruit的一个子节点。而根节点'Food'没有父节点。 为了复杂地描写这个成绩, 这个例子中只用了name来暗示一个纪录。 在实践的数据库中,你需求用数字的id来标示每一个节点,数据库的表布局也许应当像如许:id, parent_id, name, description。有了如许的表咱们就能够经由过程数据库保留全部多级树状布局了。
显示多级树
假如咱们需求显示如许的一个多级布局需求一个递归函数。
<?php
// $parent is the parent of the children we want to see
// $level is increased when we go deeper into the tree,
// used to display a nice indented tree
function display_children($parent, $level)
{
// 取得一个 父节点 $parent 的一切子节点
$result = mysql_query('SELECT name FROM tree '.
'WHERE parent="'.$parent.'";');
// 显示每一个子节点
while ($row = mysql_fetch_array($result))
{
// 缩进显示节点称号
echo str_repeat(' ',$level).$row['name']."n";
//再次挪用这个函数显示子节点的子节点
display_children($row['name'], $level+1);
}
}
?>
对全部布局的根节点(Food)利用这个函数就能够打印出全部多级树布局,因为Food是根节点它的父节点是空的,所以如许挪用: display_children('',0)。将显示全部树的内容:
Food
Fruit
Red
Cherry
Yellow
Banana
Meat
Beef
Pork
假如你只想显示全部布局中的一局部,好比说生果局部,就能够如许挪用:
display_children('Fruit',0);
几近利用一样的办法咱们可以晓得从根节点就任意节点的途径。好比 Cherry 的途径是 "Food > Fruit > Red"。 为了失掉如许的一个途径咱们需求从最深的一级"Cherry"入手下手, 查询失掉它的父节点"Red"把它添加到途径中, 然后咱们再查询Red的父节点并把它也添加到途径中,以此类推直到最高层的"Food"
<?php
// $node 是谁人最深的节点
function get_path($node)
{
// 查询这个节点的父节点
$result = mysql_query('SELECT parent FROM tree '.
'WHERE name="'.$node.'";');
$row = mysql_fetch_array($result);
// 用一个数组保留途径
$path = array();
// 假如不是根节点则持续向上查询
// (根节点没有父节点)
if ($row['parent']!='')
{
// the last part of the path to $node, is the name
// of the parent of $node
$path[] = $row['parent'];
// we should add the path to the parent of this node
// to the path
$path = array_merge(get_path($row['parent']), $path);
}
// return the path
return $path;
}
?>
假如对"Cherry"利用这个函数:print_r(get_path('Cherry')),就会失掉如许的一个数组了:
Array
(
=> Food
=> Fruit
=> Red
)
接上去若何把它打印成你但愿的格局,就是你的工作了。
弱点:这类办法很复杂,轻易了解,好上手。然而也有一些弱点。次要是由于运转速度很慢,因为失掉每一个节点都需求停止数据库查询,数据量大的时分要停止良多查询才干完成一个树。别的因为要停止递归运算,递归的每级都需求占用一些内存所以在空间使用上效力也对照低。
如今让咱们看一看别的一种不利用递归盘算,加倍疾速的办法,这就是预排序遍历树算法(modified preorder tree traversal algorithm) 这类办法人人能够接触的对照少,初度利用也不像下面的办法轻易了解,然而因为这类办法不利用递归查询算法,有更高的查询效力。
咱们起首将多级数据依照上面的体例画在纸上,在根节点Food的左边写上 1 然后沿着这个树持续向下 在 Fruit 的左边写上 2 然后持续行进,沿着全部树的边沿给每个节点都标上左边和右边的数字。最初一个数字是标在Food 右边的 18。 鄙人面的这张图中你可以看到全部标好了数字的多级布局。(没有看懂?用你的手指指着数字从1数到18就分明怎样回事了。还不分明,再数一遍,注重要挪动你的手指)。
这些数字标了然各个节点之间的关系,"Red"的号是3和6,它是 "Food" 1-18 的子孙节点。 一样,咱们可以看到 一切左值大于2和右值小于11的节点 都是"Fruit" 2-11 的子孙节点
一下弹出N多页面!很明显,你的留言本并没有做好安全防范,被人用JS代码小小的耍了一下,我很同情你这个时候的感受,但是没有别的办法了,继续努力吧! 对于初学者来说不推荐去拿钱买的。当然如果一个网站你经常去用,而且里面的资料也比较有用,最好还是买个会员比较好,毕竟那些也是别人的工作成果。 写的比较杂,因为我也是个新手,不当至于大家多多指正。 我还是强烈建议自己搭建php环境。因为在搭建的过程中你会遇到一些问题,通过搜索或是看php手册解决问题后,你会更加深刻的理解它们的工作原理,了解到php配置文件中的一些选项设置。 真正的方向了,如果将来要去开发团队,你一定要学好smarty ,phplib这样的模板引擎, 我还是推荐用firefox ,配上firebug 插件调试js能省下不受时间。谷歌的浏览器最好也不少用,因为谷歌的大侠们实在是太天才啦,把一些原来的js代码加了一些特效。 其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎 Ps:以上纯属原创,如有雷同,纯属巧合 最后介绍一个代码出错,但是老找不到错误方法,就是 go to wc (囧),出去换换气没准回来就找到错误啦。 找到的的资料很多都是在论坛里的,需要注册,所以我一般没到一个论坛都注册一个id,所有的id都注册成一样的,这样下次再进来的时候就不用重复注册啦。当然有些论坛的某些资料是需要的付费的。 我学习了一段时间后,我发现效果并不好(估计是我自身的问题)。因为一个人的精力总是有限的,同时学习这么多,会导致每个的学习时间都得不到保证。 没接触过框架的人,也不用害怕,其实框架就是一种命名规范及插件,学会一个框架其余的框架都很好上手的。 建数据库表的时候,int型要输入长度的,其实是个摆设的输入几位都没影响的,只要大于4就行,囧。 写的比较杂,因为我也是个新手,不当至于大家多多指正。 兴趣是最好的老师,百度是最好的词典。 最后祝愿,php会给你带来快乐的同时 你也会给他带来快乐。 对于懒惰的朋友,我推荐php的集成环境xampp或者是wamp。这两个软件安装方便,使用简单。但是我还是强烈建议自己动手搭建开发环境。 对于懒惰的朋友,我推荐php的集成环境xampp或者是wamp。这两个软件安装方便,使用简单。但是我还是强烈建议自己动手搭建开发环境。 最后介绍一个代码出错,但是老找不到错误方法,就是 go to wc (囧),出去换换气没准回来就找到错误啦。 爱上php,他也会爱上你。
页:
[1]