实现树状结构的两种方法


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的论坛(4)
Oct 09 PHP
php学习 函数 课件
Jun 15 PHP
PHP中=赋值操作符对不同数据类型的不同行为
Jan 02 PHP
PHP的构造方法,析构方法和this关键字详细介绍
Oct 22 PHP
PHP中ini_set和ini_get函数的用法小结
Feb 18 PHP
php遍历树的常用方法汇总
Jun 18 PHP
如何解决PHP无法实现多线程的问题
Sep 25 PHP
PHP书写格式详解(必看)
May 23 PHP
替换php字符串中的单引号为双引号的方法
Feb 16 PHP
PHP中Laravel 关联查询返回错误id的解决方法
Apr 01 PHP
Laravle eloquent 多对多模型关联实例详解
Nov 22 PHP
PHP实现websocket通信的方法示例
Aug 28 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
ThinkPHP3.2.2的插件控制器功能简述
2014/07/09 PHP
总结一些PHP中好用但又容易忽略的小知识
2017/06/02 PHP
php7函数,声明,返回值等新特性介绍
2018/05/25 PHP
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
jquery lazyload延迟加载技术的实现原理分析
2011/01/24 Javascript
JavaScript高级程序设计 XML、Ajax 学习笔记
2011/09/10 Javascript
js带按钮的提示框可供选择示例代码
2013/09/17 Javascript
在父页面调用子页面的JS方法
2013/09/29 Javascript
javascript:void(0)的问题使用探讨
2014/04/10 Javascript
JavaScript的jQuery库插件的简要开发指南
2015/08/12 Javascript
jquery+ajax实现注册实时验证实例详解
2015/12/08 Javascript
js点击文本框弹出可选择的checkbox复选框
2016/02/03 Javascript
快速掌握Node.js之Window下配置NodeJs环境
2016/03/21 NodeJs
简单实现JS倒计时效果
2016/12/23 Javascript
JavaScript面向对象精要(下部)
2017/09/12 Javascript
详解如何在vue-cli中使用vuex
2018/08/07 Javascript
vue 使用插槽分发内容操作示例【单个插槽、具名插槽、作用域插槽】
2020/03/06 Javascript
Linux系统上Nginx+Python的web.py与Django框架环境
2015/12/25 Python
Python 逐行分割大txt文件的方法
2017/10/10 Python
python 找出list中最大或者最小几个数的索引方法
2018/10/30 Python
浅谈Pandas:Series和DataFrame间的算术元素
2018/12/22 Python
Python3实现监控新型冠状病毒肺炎疫情的示例代码
2020/02/13 Python
html5 localStorage本地存储_动力节点Java学院整理
2017/07/06 HTML / CSS
html5画布旋转效果示例
2014/01/27 HTML / CSS
Pretty Little Thing美国:时尚女性服饰
2018/08/27 全球购物
Pureology官网:为染色头发打造最好的产品
2019/09/13 全球购物
工作会议欢迎词
2014/01/16 职场文书
师德个人剖析材料
2014/02/02 职场文书
幼儿园社区活动总结
2014/07/07 职场文书
2015年党员创先争优公开承诺书
2015/04/27 职场文书
会计专业2019暑假实习报告
2019/06/21 职场文书
读《茶花女》有感:山茶花的盛开与凋零
2020/01/17 职场文书
Python djanjo之csrf防跨站攻击实验过程
2021/05/14 Python
MySQL 全文索引使用指南
2021/05/25 MySQL
python实现剪贴板的操作
2021/07/01 Python
Java完整实现记事本代码
2022/06/16 Java/Android