实现树状结构的两种方法


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数组函数序列之prev() - 移动数组内部指针到上一个元素的位置,并返回该元素值
Oct 31 PHP
php删除页面记录 同时刷新页面 删除条件用GET方式获得
Jan 10 PHP
作为PHP程序员应该了解MongoDB的五件事
Jun 03 PHP
显示程序执行时间php函数代码
Aug 29 PHP
php中生成随机密码的自定义函数代码
Oct 21 PHP
PHP实现一维数组转二维数组的方法
Feb 25 PHP
PHP中把对象转换为关联数组代码分享
Apr 09 PHP
PHP实现发送邮件的方法(基于简单邮件发送类)
Dec 17 PHP
Yii2中datetime类的使用
Dec 17 PHP
PHP严重致命错误处理:php Fatal error: Cannot redeclare class or function
Feb 05 PHP
php生成图片缩略图功能示例
Feb 22 PHP
Laravel 简单实现Ajax滚动加载示例
Oct 22 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中DOMDocument简单用法示例代码(XML创建、添加、删除、修改)
2010/12/19 PHP
thinkPHP+mysql+ajax实现的仿百度一下即时搜索效果详解
2019/07/15 PHP
js中几种去掉字串左右空格的方法
2006/12/25 Javascript
Javascript 类与静态类的实现(续)
2010/04/02 Javascript
JavaScript几种形式的树结构菜单
2010/05/10 Javascript
js实现图片和链接文字同步切换特效的方法
2015/02/20 Javascript
JQuery使用$.ajax和checkbox实现下次不在通知功能
2015/04/16 Javascript
js实现图片上传并正常显示
2015/12/19 Javascript
详解Angular中$cacheFactory缓存的使用
2016/08/19 Javascript
js获取元素的标签名实现方法
2016/10/08 Javascript
微信小程序 数组(增,删,改,查)等操作实例详解
2017/01/05 Javascript
基于jQuery代码实现圆形菜单展开收缩效果
2017/02/13 Javascript
JavaScript函数参数的传递方式详解
2017/03/06 Javascript
详解微信小程序 登录获取unionid
2017/06/27 Javascript
JavaScript实现无刷新上传预览图片功能
2017/08/02 Javascript
JavaScript 几种循环方式以及模块化的总结
2020/09/03 Javascript
微信小程序实现底部弹出框
2020/11/18 Javascript
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
2021/01/22 Vue.js
[43:48]Ti4正赛第一天 VG vs NEWBEE 2
2014/07/19 DOTA
python使用cookielib库示例分享
2014/03/03 Python
python之Socket网络编程详解
2016/09/29 Python
浅谈Python爬取网页的编码处理
2016/11/04 Python
python+opencv实现阈值分割
2018/12/26 Python
Python字典对象实现原理详解
2019/07/01 Python
Python实现平行坐标图的两种方法小结
2019/07/04 Python
Django框架视图介绍与使用详解
2019/07/18 Python
python安装本地whl的实例步骤
2019/10/12 Python
pytorch 利用lstm做mnist手写数字识别分类的实例
2020/01/10 Python
浅谈pytorch池化maxpool2D注意事项
2020/02/18 Python
屏蔽Django admin界面添加按钮的操作
2020/03/11 Python
python中如何设置代码自动提示
2020/07/15 Python
New Balance澳大利亚官网:运动鞋和健身服装
2019/02/23 全球购物
大学生最新职业生涯规划书范文
2014/01/12 职场文书
美术教师自我鉴定
2014/02/12 职场文书
2015年复活节活动总结
2015/02/27 职场文书
《和时间赛跑》读后感3篇
2019/12/16 职场文书