实现树状结构的两种方法


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与XML的PDF文档生成技术
Oct 09 PHP
php采集时被封ip的解决方法
Aug 29 PHP
destoon之一键登录设置
Jun 21 PHP
php使用COPY函数更新配置文件的方法
Jun 18 PHP
以文件形式缓存php变量的方法
Jun 26 PHP
PHP技术开发微信公众平台
Jul 22 PHP
linux下为php添加iconv模块的方法
Feb 28 PHP
Thinkphp和onethink实现微信支付插件
Apr 13 PHP
php实现文章置顶功能的方法
Oct 20 PHP
PHP的mysqli_select_db()函数讲解
Jan 23 PHP
PHP chunk_split()函数讲解
Feb 12 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
Apr 05 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 增加了对 .ZIP 文件的读取功能
2006/10/09 PHP
PHP cron中的批处理
2008/09/16 PHP
php获取用户IPv4或IPv6地址的代码
2012/11/15 PHP
php封装的连接Mysql类及用法分析
2015/12/10 PHP
php 判断字符串编码是utf-8 或gb2312实例
2016/11/01 PHP
Javascript打印网页部分内容的脚本
2008/11/17 Javascript
jquery判断至少有一个checkbox被选中的方法
2015/06/05 Javascript
animate 实现滑动切换效果【实例代码】
2016/05/05 Javascript
微信小程序教程系列之新建页面(4)
2017/04/17 Javascript
微信扫码支付零云插件版实例详解
2017/04/26 Javascript
JS ES6中setTimeout函数的执行上下文示例
2017/04/27 Javascript
JavaScript数据结构学习之数组、栈与队列
2017/05/02 Javascript
Angular表格神器ui-grid应用详解
2017/09/29 Javascript
Django中使用jquery的ajax进行数据交互的实例代码
2017/10/15 jQuery
浅谈es6 javascript的map数据结构
2017/12/14 Javascript
使用taro开发微信小程序遇到的坑总结
2019/04/08 Javascript
小程序如何定位所在城市及发起周边搜索
2020/02/11 Javascript
JavaScript进阶(一)变量声明提升实例分析
2020/05/09 Javascript
实例讲解python函数式编程
2014/06/09 Python
python中日期和时间格式化输出的方法小结
2015/03/19 Python
python简单实现刷新智联简历
2016/03/30 Python
Python单体模式的几种常见实现方法详解
2017/07/28 Python
django 多数据库及分库实现方式
2020/04/01 Python
django跳转页面传参的实现
2020/09/17 Python
python实现人工蜂群算法
2020/09/18 Python
详解selenium + chromedriver 被反爬的解决方法
2020/10/28 Python
python requests库的使用
2021/01/06 Python
纯HTML5+CSS3制作生日蛋糕(代码易懂)
2016/11/16 HTML / CSS
俄罗斯天然和有机产品、健康生活网上商店:Fitomarket.ru
2020/10/09 全球购物
详解如何解决使用JSON.stringify时遇到的循环引用问题
2021/03/23 Javascript
找工作最新求职信
2013/12/22 职场文书
机关作风整顿个人整改措施思想汇报
2014/09/29 职场文书
营业员岗位职责范本
2015/04/14 职场文书
环保证明
2015/06/23 职场文书
创业计划书之酒吧
2019/12/02 职场文书
GTX1650super好不好 gtx1650super显卡属于什么级别
2022/04/08 数码科技