实现树状结构的两种方法


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 相关文章推荐
在PHP中读取和写入WORD文档的代码
Apr 09 PHP
php中使用exec,system等函数调用系统命令的方法(不建议使用,可导致安全问题)
Sep 07 PHP
php数组相加 array(“a”)+array(“b”)结果还是array(“a”)
Sep 19 PHP
基于php上传图片重命名的6种解决方法的详细介绍
Apr 28 PHP
PHP取整函数:ceil,floor,round,intval的区别详细解析
Aug 31 PHP
destoon实现调用图文新闻的方法
Aug 21 PHP
php中file_get_contents与curl性能比较分析
Nov 08 PHP
PHP生成唯一订单号的方法汇总
Apr 16 PHP
Zend Framework实现Zend_View集成Smarty模板系统的方法
Mar 05 PHP
如何解决PHP使用mysql_query查询超大结果集超内存问题
Mar 14 PHP
php自定义时间转换函数示例
Dec 07 PHP
php 字符串中是否包含指定字符串的多种方法
Apr 12 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实现简单的语法高亮函数实例分析
2015/04/27 PHP
详解WordPress中的头像缓存和代理中的缓存更新方法
2016/03/01 PHP
PHP实现链式操作的三种方法详解
2017/11/16 PHP
javascript  Error 对象 错误处理
2008/05/18 Javascript
javascript prototype 原型链
2009/03/12 Javascript
浅谈Javascript鼠标和滚轮事件
2012/06/27 Javascript
jquery获取特定name所有选中的checkbox,支持IE9标准模式
2013/03/18 Javascript
js和jquery对dom节点的操作(创建/追加)
2013/04/21 Javascript
extjs表格文本启用选择复制功能具体实现
2013/10/11 Javascript
jQuery中replaceWith()方法用法实例
2014/12/25 Javascript
jQuery操作基本控件方法实例分析
2015/12/31 Javascript
BootStrap的JS插件之轮播效果案例详解
2016/05/16 Javascript
JS使用正则截取两个字符串之间的字符串实现方法详解
2017/01/06 Javascript
vue.js学习笔记:如何加载本地json文件
2017/01/17 Javascript
基于javascript中的typeof和类型判断(详解)
2017/10/27 Javascript
vue在手机中通过本机IP地址访问webApp的方法
2018/08/15 Javascript
layer弹出的iframe层在执行完毕后关闭当前弹出层的方法
2018/08/17 Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
2019/11/15 Javascript
小程序实现上传视频功能
2020/08/18 Javascript
Python Web服务器Tornado使用小结
2014/05/06 Python
Ubuntu16.04/树莓派Python3+opencv配置教程(分享)
2018/04/02 Python
Flask-Mail用法实例分析
2018/07/21 Python
windows下python 3.6.4安装配置图文教程
2018/08/21 Python
Python实现分段线性插值
2018/12/17 Python
python 写一个文件分发小程序
2020/12/05 Python
html5 localStorage本地存储_动力节点Java学院整理
2017/07/06 HTML / CSS
利用html5 canvas动态画饼状图的示例代码
2018/04/02 HTML / CSS
Feelunique德国官方网站:欧洲最大的在线美容零售商
2019/07/20 全球购物
ORACLE十问
2015/04/20 面试题
幼儿园门卫制度
2014/01/29 职场文书
实习生求职自荐信
2014/02/07 职场文书
高速铁道技术专业求职信
2014/08/09 职场文书
2014年政教处工作总结
2014/12/20 职场文书
20180830晚上第一届KSL半决赛 雨神vs解冻(二龙 三炮解说)
2022/04/01 星际争霸
如何通过简单的代码描述Angular父组件、子组件传值
2022/04/07 Javascript
Mysql数据库group by原理详解
2022/07/07 MySQL