实现树状结构的两种方法


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 相关文章推荐
我的论坛源代码(三)
Oct 09 PHP
PHP脚本数据库功能详解(下)
Oct 09 PHP
那些年一起学习的PHP(三)
Mar 22 PHP
PHP基础教程(php入门基础教程)一些code代码
Jan 06 PHP
php字符串分割函数explode的实例代码
Feb 07 PHP
php curl的深入解析
Jun 02 PHP
PHP+jQuery 注册模块的改进(一):验证码存入SESSION
Oct 14 PHP
php实现MySQL数据库备份与还原类实例
Dec 09 PHP
解决thinkPHP 5 nginx 部署时,只跳转首页的问题
Oct 16 PHP
php中加密解密DES类的简单使用方法示例
Mar 26 PHP
PHP接口类(interface)的定义、特点和应用示例
May 18 PHP
PHP7 弃用功能
Mar 09 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
COM in PHP (winows only)
2006/10/09 PHP
php获取post中的json数据的实现方法
2011/06/08 PHP
小谈php正则提取图片地址
2014/03/27 PHP
codeigniter框架The URI you submitted has disallowed characters错误解决方法
2014/05/06 PHP
PHP中round()函数对浮点数进行四舍五入的方法
2014/11/19 PHP
smarty简单应用实例
2015/11/03 PHP
php PDO判断连接是否可用的实现方法
2017/04/03 PHP
ThinkPHP实现静态缓存和动态缓存示例代码
2017/05/02 PHP
php实现基于pdo的事务处理方法示例
2017/07/21 PHP
window.event快达到全浏览器支持了,以后使用就方便了
2011/11/30 Javascript
纯JS实现动态时间显示代码
2014/02/08 Javascript
JavaScript异步回调的Promise模式封装实例
2014/06/07 Javascript
Nodejs全栈框架StrongLoop推荐
2014/11/09 NodeJs
超赞的jQuery图片滑块动画特效代码汇总
2016/01/25 Javascript
浅析AngularJS中的指令
2016/03/20 Javascript
Vuejs第十一篇组件之slot内容分发实例详解
2016/09/09 Javascript
微信开发 使用picker封装省市区三级联动模板
2016/10/28 Javascript
js实现抽奖效果
2017/03/27 Javascript
全面解析jQuery中的$(window)与$(document)的用法区别
2017/08/15 jQuery
利用pm2部署多个node.js项目的配置教程
2017/10/22 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
2017/12/05 Javascript
Node.js中DNS模块学习总结
2018/02/28 Javascript
深入了解Python数据类型之列表
2016/06/24 Python
用python处理图片实现图像中的像素访问
2018/05/04 Python
Python/ArcPy遍历指定目录中的MDB文件方法
2018/10/27 Python
Python处理mysql特殊字符的问题
2020/03/02 Python
Django实现将views.py中的数据传递到前端html页面,并展示
2020/03/16 Python
基于Python中random.sample()的替代方案
2020/05/23 Python
提供世界各地便宜的机票:Sky-tours
2016/07/21 全球购物
苹果台湾官网:Apple台湾
2019/01/05 全球购物
银行会计业务的个人自我评价
2013/11/02 职场文书
2014学校领导四风问题对照检查材料思想汇报
2014/09/22 职场文书
群众路线个人对照检查材料2014
2014/09/26 职场文书
督导岗位职责
2015/02/04 职场文书
干部培训简讯
2015/07/20 职场文书
我们认为中短波广播场强仪的最佳组合
2022/04/05 无线电