php通过前序遍历树实现无需递归的无限极分类


Posted in PHP onJuly 10, 2015

本文实例讲述了php通过前序遍历树实现无需递归的无限极分类。分享给大家供大家参考。具体如下:

大家通常都是使用递归实现无限极分类都知道递归效率很低,下面介绍一种改进的前序遍历树算法,不适用递归实现无限极分类,在大数据量实现树状层级结构的时候效率更高。

sql代码如下:

CREATE TABLE IF NOT EXISTS `category` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `title` varchar(50) NOT NULL,
 `lft` int(11) NOT NULL,
 `rgt` int(11) NOT NULL,
 `order` int(11) NOT NULL COMMENT '排序',
 `create_time` int(11) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=12 ;
--
-- 转存表中的数据 `category`
--
INSERT INTO `category` (`id`, `title`, `lft`, `rgt`, `order`, `create_time`) VALUES
(1, '顶级栏目', 1, 20, 1, 1261964806),
(2, '编辑后的分类', 16, 19, 50, 1264586212),
(4, '公司产品', 10, 15, 50, 1264586249),
(5, '荣誉资质', 8, 9, 50, 1264586270),
(6, '资料下载', 6, 7, 50, 1264586295),
(7, '人才招聘', 4, 5, 50, 1264586314),
(8, '留言板', 2, 3, 50, 1264586884),
(9, '总裁', 17, 18, 50, 1267771951),
(10, '新的分类的子分类', 11, 14, 0, 1400044841),
(11, 'PHP点点通-http://www.phpddt.com', 12, 13, 0, 1400044901);

php代码如下:

<?php
/**
 * 纯属测试
 * 
 * @author Mckee
 * @link http://www.phpddt.com
 */
class Category extends CI_Controller {
  public function __construct()
  {
    parent::__construct();
    $this->load->database();
  }
  public function view()
  {
    $lists = $this->db->order_by('lft', 'asc')->get('category')->result_array();
    //相邻的两条记录的右值第一条的右值比第二条的大那么就是他的父类
    //我们用一个数组来存储上一条记录的右值,再把它和本条记录的右值比较,如果前者比后者小,说明不是父子关系,就用array_pop弹出数组,否则就保留
    //两个循环而已,没有递归
    $parent = array();
    $arr_list = array();
    foreach($lists as $item){
      if(count($parent)){
        while (count($parent) -1 > 0 && $parent[count($parent) -1]['rgt'] < $item['rgt']){
          array_pop($parent);
        }  
      }
      $item['depath'] = count($parent);
      $parent[] = $item;
      $arr_list[]= $item;
    }
    //显示树状结构
    foreach($arr_list as $a)
    {
      echo str_repeat('--', $a['depath']) . $a['title'] . '<br />';
    }
  }
  /**
   * 
   * 插入操作很简单找到其父节点,之后把左值和右值大于父节点左值的节点的左右值加上2,之后再插入本节点,左右值分别为父节点左值加一和加二
   */
  public function add()
  {
    //获取到父级分类的id
    $parent_id = 10;
    $parent_category = $this->db->where('id', $parent_id)->get('category')->row_array();
    //1.左值和右值大于父节点左值的节点的左右值加上2
    $this->db->set('lft', 'lft + 2', FALSE)->where(array('lft >' => $parent_category['lft']))->update('category');
    $this->db->set('rgt', 'rgt + 2', FALSE)->where(array('rgt >' => $parent_category['lft']))->update('category');
    //2.插入新的节点
    $this->db->insert('category', array(
      'title' => '新的分类的子分类',
      'lft' => $parent_category['lft'] + 1,
      'rgt' => $parent_category['lft'] + 2,
      'order' => 0,
      'create_time' => time()
    ));
    echo 'add success';
  }
  /**
   * 删除
   * 
   * //1.得到删除的节点,将右值减去左值然后加1,得到值$width = $rgt - $lft + 1;
   * //2.删除左右值之间的所有节点
   * //3.修改条件为大于本节点右值的所有节点,操作为把他们的左右值都减去$width
   */
  public function delete()
  {
    //通过分类id获取分类
    $id = 3;
    $category = $this->db->where('id', $id)->get('category')->row_array();
    //计算$width
    $width = $category['rgt'] - $category['lft'] + 1;
    //1.删除该条分类
    $this->db->delete('category', array('id' => $id));
    //2.删除左右值之间的所有分类
    $this->db->delete('category', array('lft >' => $category['lft'], 'lft <' => $category['rgt']));
    //3.修改其它节点的值
    $this->db->set('lft', "lft - {$width}", FALSE)->where(array('lft >' => $category['rgt']))->update('category');
    $this->db->set('rgt', "rgt - {$width}", FALSE)->where(array('rgt >' => $category['rgt']))->update('category');
    echo 'delete success';
  }
  //编辑,
  public function edit()
  {
    //不用说了, 直接通过id编辑
    $id = 2;
    $this->db->update('category', array(
      'title' => '编辑后的分类'
    ), array(
      'id' => $id
    ));
    echo 'edit success';
  }
}

希望本文所述对大家的php程序设计有所帮助。

PHP 相关文章推荐
php批量删除数据
Jan 18 PHP
PHP用mysql数据库存储session的代码
Mar 05 PHP
php输出表格的实现代码(修正版)
Dec 29 PHP
FireFox浏览器使用Javascript上传大文件
Oct 30 PHP
PHP中feof()函数实例测试
Aug 23 PHP
浅析php创建者模式
Nov 25 PHP
php实现上传图片文件代码
Jul 19 PHP
开启PHP Static 关键字之旅模式
Nov 13 PHP
PHP连接MSSQL方法汇总
Feb 05 PHP
laravel框架邮箱认证实现方法详解
Nov 22 PHP
PHP程序员简单的开展服务治理架构操作详解(二)
May 14 PHP
PHP安全之register_globals的on和off的区别
Jul 23 PHP
php中array_multisort对多维数组排序的方法
Jun 21 #PHP
php获取文件类型和文件信息的方法
Jul 10 #PHP
php中实现用数组妩媚地生成要执行的sql语句
Jul 10 #PHP
PHP中把对象数组转换成普通数组的方法
Jul 10 #PHP
codeigniter实现get分页的方法
Jul 10 #PHP
PHP基于phpqrcode生成带LOGO图像的二维码实例
Jul 10 #PHP
php基于Snoopy解析网页html的方法
Jul 09 #PHP
You might like
php+js实现图片的上传、裁剪、预览、提交示例
2013/08/27 PHP
微信支付开发教程(一)微信支付URL配置
2014/05/28 PHP
js计算页面刷新的次数
2009/07/20 Javascript
jQuery 名称冲突的解决方法
2011/04/08 Javascript
使用jquery实现select添加实现后台权限添加的效果
2011/05/28 Javascript
Prototype源码浅析 Number部分
2012/01/16 Javascript
jquery简单的拖动效果实现原理及示例
2013/07/26 Javascript
JavaScript实现动态创建CSS样式规则方案
2014/09/06 Javascript
Bootstrap CSS布局之表格
2016/12/17 Javascript
详解webpack分离css单独打包
2017/06/21 Javascript
详解nodejs实现本地上传图片并预览功能(express4.0+)
2017/06/28 NodeJs
如何将HTML字符转换为DOM节点并动态添加到文档中详解
2018/08/19 Javascript
基于Angular中ng-controller父子级嵌套的相关属性详解
2018/10/08 Javascript
浅谈webpack devtool里的7种SourceMap模式
2019/01/14 Javascript
JS实现集合的交集、补集、差集、去重运算示例【ES5与ES6写法】
2019/02/18 Javascript
详解vuejs2.0 select 动态绑定下拉框支持多选
2019/04/25 Javascript
js实现随机点名程序
2020/09/17 Javascript
JavaScript原型式继承实现方法
2019/11/06 Javascript
详解JavaScript中的Object.is()与&quot;===&quot;运算符总结
2020/06/17 Javascript
vue.js实现双击放大预览功能
2020/06/23 Javascript
浅析Python中的序列化存储的方法
2015/04/28 Python
实例解析Python设计模式编程之桥接模式的运用
2016/03/02 Python
python3批量删除豆瓣分组下的好友的实现代码
2016/06/07 Python
python3实现域名查询和whois查询功能
2018/06/21 Python
pyttsx3实现中文文字转语音的方法
2018/12/24 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
2019/07/19 Python
python文字转语音实现过程解析
2019/11/12 Python
Python制作简易版小工具之计算天数的实现思路
2020/02/13 Python
Scrapy框架介绍之Puppeteer渲染的使用
2020/06/19 Python
python实现不同数据库间数据同步功能
2021/02/25 Python
有影响力的品牌之家:Our Social Collective
2019/06/08 全球购物
美国主要的特色咖啡和茶公司:Peet’s Coffee
2020/02/14 全球购物
领导班子四风问题对照检查材料
2014/09/27 职场文书
2014年终个人总结报告
2015/03/09 职场文书
宾馆客房管理制度
2015/08/06 职场文书
小学语文教学随笔
2015/08/14 职场文书