实现树状结构的两种方法


Posted in PHP onOctober 09, 2006

实现树状结构的两种方法 1。递归法
递归是指在函数中显式的调用它自身。
利用递归法实现树状结构的特点是写入数据速度较快,显示速度较慢(在树的分支/层次较多的情况下尤其明显)。适用与写入数据量大,树的结构复杂的情况下。
数据结构(以mysql为例)

代码:--------------------------------------------------------------------------------
CREATE TABLE `tree1` (
  `id` tinyint(3) unsigned NOT NULL auto_increment,
  `parentid` tinyint(3) unsigned NOT NULL default '0',
  `topic` varchar(50) default NULL,
  PRIMARY KEY  (`id`),
  KEY `parentid` (`parentid`)
) TYPE=MyISAM;

INSERT INTO `tree1` (`id`, `parentid`, `topic`) VALUES
  (1,0,'树1'),
  (2,0,'树2'),
  (3,0,'树3'),
  (4,2,'树2-1'),
  (5,4,'树2-1-1'),
  (6,2,'树2-2'),
  (7,1,'树1-1'),
  (8,1,'树1-2'),
  (9,1,'树1-3'),
  (10,8,'树1-2-1'),
  (11,7,'树1-1-1'),
  (12,11,'树1-1-1-1');
--------------------------------------------------------------------------------

字段说明
id,记录的id号
parentid,记录的父记录id(为0则为根记录)
topic,记录的显示标题

显示程序

顺序树:

PHP代码:--------------------------------------------------------------------------------

<?
/* 数据库连接 */
mysql_connect();
mysql_select_db('tree');

/* 树状显示的递归函数 */
function tree($parentid = 0) {
    /*执行sql查询,获取记录的标题和id*/
    $sql = "select topic,id from tree1 where parentid = $parentid order by id asc";
    $rs = mysql_query($sql);
    /* 缩进*/
    echo("<ul>");
    while($ra = mysql_fetch_row($rs)) {
        /* 显示记录标题 */
        echo('<li>'.$ra[0].'</li>');
        /* 递归调用 */
        tree($ra[1]);
    }
    echo("</ul>");
}
tree();
?>

--------------------------------------------------------------------------------

逆序树:

PHP代码:--------------------------------------------------------------------------------

<?
/* 数据库连接 */
mysql_connect();
mysql_select_db('tree');

/* 树状显示的递归函数 */
function tree($parentid = 0) {
    /*执行sql查询,获取记录的标题和id*/
    $sql = "select topic,id from tree1 where parentid = $parentid order by id desc";
    $rs = mysql_query($sql);
    /* 缩进*/
    echo("<ul>");
    while($ra = mysql_fetch_row($rs)) {
        /* 显示记录标题 */
        echo('<li>'.$ra[0].'</li>');
        /* 递归调用 */
        tree($ra[1]);
    }
    echo("</ul>");
}
tree();
?>

--------------------------------------------------------------------------------

插入数据程序

PHP代码:--------------------------------------------------------------------------------

<?
/* 数据库连接 */
mysql_connect();
mysql_select_db('tree');
$sql = "insert into tree (topic,parentid) values('树3-1',3);";
mysql_query($sql);
?>

--------------------------------------------------------------------------------

2。排序字段法
此方法是通过在数据结构中增加一个标志记录在整个树中的顺序位置的字段来实现的。特点是显示速度和效率高。但在单个树的结构复杂的情况下,数据写入效率有所不足。而且顺序排列时候,插入,删除记录的算法过于复杂,故通常用逆序排列。

数据结构(以mysql为例)

代码:--------------------------------------------------------------------------------
CREATE TABLE `tree2` (
  `id` tinyint(3) unsigned NOT NULL auto_increment,
  `parentid` tinyint(3) unsigned NOT NULL default '0',
  `rootid` tinyint(3) unsigned NOT NULL default '0',
  `layer` tinyint(3) unsigned NOT NULL default '0',
  `orders` tinyint(3) unsigned NOT NULL default '0',
  `topic` varchar(50) default NULL,
  PRIMARY KEY  (`id`),
  KEY `parentid` (`parentid`),
  KEY `rootid` (`rootid`)
) TYPE=MyISAM

INSERT INTO `tree2` (`id`, `parentid`, `rootid`, `layer`, `orders`, `topic`) VALUES
  (1,0,1,0,0,'树1'),
  (2,0,2,0,0,'树2'),
  (3,0,3,0,0,'树3'),
  (4,2,2,1,2,'树2-1'),
  (5,4,2,2,3,'树2-1-1'),
  (6,2,2,1,1,'树2-2'),
  (7,1,1,1,4,'树1-1'),
  (8,1,1,1,2,'树1-2'),
  (9,1,1,1,1,'树1-3'),
  (10,8,1,2,3,'树1-2-1'),
  (11,7,1,2,5,'树1-1-1'),
  (12,11,1,3,6,'树1-1-1-1');
--------------------------------------------------------------------------------

显示程序

PHP代码:--------------------------------------------------------------------------------

<?
/* 数据库连接 */
mysql_connect();
mysql_select_db('tree');

/* 选出所有根记录id */
$sql = "select id from tree2 where parentid = 0 order by id desc";
$rs = mysql_query($sql);
echo("<ul>");
$lay = 0;
while($ra = mysql_fetch_row($rs)) {
    echo("<ul>");
    /* 选出此树所有记录,并按orders字段排序 */
    $sql = "select topic,layer from tree2 where rootid = $ra[0] order by orders";
    $rs1 = mysql_query($sql);
    while($ra1 = mysql_fetch_row($rs1)) {
        /* 缩进显示 */
        if($ra1[1]>$lay) {
            echo(str_repeat("<ul>",$ra1[1]-$lay));
        }elseif($ra1[1]<$lay) {
            echo(str_repeat("</ul>",$lay-$ra1[1]));
        }
        /* 记录显示 */
        //echo("$ra1[1]>$lay");
        echo("<li>$ra1[0]</li>");
        $lay = $ra1[1];
    }
    echo("</ul>");
}
echo("</ul>");
?>

--------------------------------------------------------------------------------

插入数据程序

PHP代码:--------------------------------------------------------------------------------

<?
/* 数据库连接 */
mysql_connect();
mysql_select_db('tree');

/* 插入根记录 */
$sql = "insert into tree2 (topic) values ('树5')";
mysql_query($sql);
$sql = "update tree2 set rootid = id where id = ".mysql_insert_id();
mysql_query($sql);

/* 插入子记录 */
$parentid = 5;//父记录id
/* 取出 根记录id,父记录缩进层次,父记录顺序位置 */
$sql = "select rootid,layer,orders from tree2 where id = $parentid";
list($rootid,$layer,$orders) = mysql_fetch_row(mysql_query($sql));
/* 更新插入位置后记录的orders值 */
$sql = "update tree2 set orders = orders + 1 where orders > $orders";
mysql_query($sql);
/* 插入记录 */
$sql = "insert into tree2 (rootid,parentid,orders,layer,topic) values ($rootid,$parentid,".($orders+1).",".($layer+1).",'树2-1-1-2')";
mysql_query($sql);?>

PHP 相关文章推荐
一个用于mysql的数据库抽象层函数库
Oct 09 PHP
其他功能
Oct 09 PHP
escape unescape的php下的实现方法
Apr 27 PHP
PHP mail 通过Windows的SMTP发送邮件失败的解决方案
May 27 PHP
php短域名转换为实际域名函数
Jan 17 PHP
php 伪造本地文件包含漏洞的代码
Nov 03 PHP
神盾加密解密教程(三)PHP 神盾解密工具
Jun 08 PHP
PHP实现多图片上传类实例
Jul 26 PHP
PHP strtotime函数用法、实现原理和源码分析
Feb 04 PHP
PHP手机短信验证码实现流程详解
May 17 PHP
php json转换相关知识(小结)
Dec 21 PHP
php实例化对象的实例方法
Nov 17 PHP
PHP邮件专题
Oct 09 #PHP
Content-type 的说明
Oct 09 #PHP
高亮度显示php源代码
Oct 09 #PHP
PHP4 与 MySQL 数据库操作函数详解
Oct 09 #PHP
开发大型PHP项目的方法
Oct 09 #PHP
怎么使 Mysql 数据同步
Oct 09 #PHP
PHP 中的类
Oct 09 #PHP
You might like
探讨PHP中OO之静态关键字以及类常量的详解
2013/06/07 PHP
PHP开发框架kohana3 自定义路由设置示例
2014/07/14 PHP
PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
2018/05/31 PHP
轻轻松松学习JavaScript
2007/02/25 Javascript
jQuery 注意事项 与原因分析
2009/04/24 Javascript
javascript showModalDialog 多层模态窗口实现页面提交及刷新的代码
2009/11/28 Javascript
JavaScript 面向对象之命名空间
2010/05/04 Javascript
调试Node.JS的辅助工具(NodeWatcher)
2012/01/04 Javascript
深入理解JavaScript系列(10) JavaScript核心(晋级高手必读篇)
2012/01/15 Javascript
jQueryUI写一个调整分类的拖放效果实现代码
2012/05/10 Javascript
JS+CSS设置img在DIV中只显示Img垂直居中的部分
2013/10/24 Javascript
基于jquery扩展漂亮的下拉框可以二次修改
2013/11/19 Javascript
jquery禁用右键示例
2014/04/28 Javascript
jQuery ajax时间差导致的变量赋值问题分析
2016/01/22 Javascript
Angular.JS学习之依赖注入$injector详析
2016/10/20 Javascript
jQuery代码实现实时获取时间
2017/01/29 Javascript
Vue下的国际化处理方法
2017/12/18 Javascript
angularjs获取到My97DatePicker选中的值方法
2018/10/02 Javascript
webstorm+vue初始化项目的方法
2018/10/18 Javascript
Vue中遍历数组的新方法实例详解
2019/07/21 Javascript
Angular6项目打包优化的实现方法
2019/12/15 Javascript
利用python实现数据分析
2017/01/11 Python
python 3.7.0 下pillow安装方法
2018/08/27 Python
pycharm重置设置,恢复默认设置的方法
2018/10/22 Python
django认证系统 Authentication使用详解
2019/07/22 Python
python 弧度与角度互转实例
2020/04/15 Python
Django+RestFramework API接口及接口文档并返回json数据操作
2020/07/12 Python
美国伴娘礼服商店:Evening Collective
2019/10/07 全球购物
房地产广告策划方案
2014/05/15 职场文书
三问三解心得体会
2014/09/05 职场文书
五年级上册复习计划
2015/01/19 职场文书
科技活动总结范文
2015/05/11 职场文书
读完《骆驼祥子》的观后感!
2019/07/05 职场文书
竞聘开场白方式有哪些?
2019/08/28 职场文书
opencv深入浅出了解机器学习和深度学习
2022/03/17 Python
项目中Nginx多级代理是如何获取客户端的真实IP地址
2022/05/30 Servers