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 生成自动创建文件夹并上传文件的示例代码
Mar 07 PHP
PHP采用自定义函数实现遍历目录下所有文件的方法
Aug 19 PHP
php中常量DIRECTORY_SEPARATOR用法深入分析
Nov 14 PHP
php实现格式化多行文本为Js可用格式
Apr 15 PHP
php文件操作之小型留言本实例
Jun 20 PHP
php实现的简单美国商品税计算函数
Jul 13 PHP
是 WordPress 让 PHP 更流行了 而不是框架
Feb 03 PHP
php版微信公众账号第三方管理工具开发简明教程
Sep 23 PHP
PHP实现二维数组按某列进行排序的方法
Nov 18 PHP
PHP addslashes()函数讲解
Feb 03 PHP
laravel 配置路由 api和web定义的路由的区别详解
Sep 03 PHP
Laravel服务容器绑定的几种方法总结
Jun 14 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
Linux下ZendOptimizer的安装与配置方法
2007/04/12 PHP
php中将汉字转换成拼音的函数代码
2012/09/08 PHP
PHP 文件编程综合案例-文件上传的实现
2013/07/03 PHP
php实现检查文章是否被百度收录
2015/01/27 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
2016/10/18 PHP
php ajax数据传输和响应方法
2018/08/21 PHP
PHP使用redis位图bitMap 实现签到功能
2019/10/08 PHP
推荐:极酷右键菜单
2006/11/29 Javascript
JQuery 表单中textarea字数限制实现代码
2009/12/07 Javascript
js parsefloat parseint 转换函数
2010/01/21 Javascript
学习JavaScript的最佳方法分享
2011/10/21 Javascript
JS对HTML标签select的获取、添加、删除操作
2013/10/17 Javascript
javascript运行机制之this详细介绍
2014/02/07 Javascript
三种方式获取XMLHttpRequest对象
2014/04/21 Javascript
js实现网站最上边可关闭的浮动广告条代码
2015/09/04 Javascript
jquery.form.js框架实现文件上传功能案例解析(springmvc)
2016/05/26 Javascript
bootstrap选项卡使用方法解析
2017/01/11 Javascript
jQuery Validate插件ajax方式验证输入值的实例
2017/12/21 jQuery
nodejs实现的连接MySQL数据库功能示例
2018/01/25 NodeJs
在Vue中获取组件声明时的name属性方法
2018/09/12 Javascript
小程序Scroll-view上拉滚动刷新数据
2020/06/21 Javascript
three.js 利用uv和ThreeBSP制作一个快递柜功能
2020/08/18 Javascript
js实现随机点名功能
2020/12/23 Javascript
[01:59]DOTA2首部纪录片《Free to play》预告片
2014/03/12 DOTA
Python读写操作csv和excle文件代码实例
2020/03/16 Python
python打包生成so文件的实现
2020/10/30 Python
CSS3提交意见输入框样式代码
2014/10/30 HTML / CSS
ghd官网:英国ghd直发器品牌
2018/05/04 全球购物
DataList 能否分页,请问如何实现?
2015/05/03 面试题
红领巾广播站广播稿
2014/02/01 职场文书
党支部承诺书范文
2014/03/28 职场文书
家长对老师的评语
2014/04/18 职场文书
建筑工程技术专业求职信
2014/07/16 职场文书
2015年节能降耗工作总结
2015/05/22 职场文书
2016个人先进事迹材料范文
2016/03/01 职场文书
2019年图书室自查报告范本
2019/10/12 职场文书