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学习笔记 PHP面向对象的程序设计
Jun 13 PHP
php中关于codeigniter的xmlrpc的类在进行数据交换时的类型问题
Jul 03 PHP
PHP+Mysql+jQuery实现发布微博程序 jQuery篇
Oct 08 PHP
优化PHP代码技巧的小结
Jun 02 PHP
PHP调试的强悍利器之PHPDBG
Feb 22 PHP
php类的自动加载操作实例详解
Sep 28 PHP
PHP对象链式操作实现原理分析
Oct 09 PHP
浅谈php中的循环while、do...while、for、foreach四种循环
Nov 05 PHP
thinkphp下MySQL数据库读写分离代码剖析
Apr 18 PHP
自制PHP框架之模型与数据库
May 07 PHP
PHP微信H5支付开发实例
Jul 25 PHP
laravel excel 上传文件保存到本地服务器功能
Nov 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
正则表达式语法
2006/10/09 Javascript
一些常用的php函数
2006/12/06 PHP
PHP版 汉字转码的实现详解
2013/06/09 PHP
解决file_get_contents无法请求https连接的方法
2013/12/17 PHP
php中filter函数验证、过滤用户输入的数据
2014/01/13 PHP
PHP图片裁剪函数(保持图像不变形)
2014/05/04 PHP
PHP实现的英文名字全拼随机排号脚本
2014/07/04 PHP
Android App中DrawerLayout抽屉效果的菜单编写实例
2016/03/21 PHP
jquery实现类似淘宝星星评分功能实例
2014/09/12 Javascript
JavaScript面向对象之私有静态变量实例分析
2016/01/14 Javascript
js实现上一页下一页的效果【附代码】
2016/03/10 Javascript
深入学习js瀑布流布局
2016/10/14 Javascript
Javascript 动态改变imput type属性
2016/11/01 Javascript
JS 插件dropload下拉刷新、上拉加载使用小结
2017/04/13 Javascript
vux uploader 图片上传组件的安装使用方法
2018/05/15 Javascript
超好用的jQuery分页插件jpaginate用法示例【附源码下载】
2018/12/06 jQuery
如何实现双向绑定mvvm的原理实现
2019/05/28 Javascript
AI小程序之语音听写来了,十分钟掌握百度大脑语音听写全攻略
2020/03/13 Javascript
jquery实现鼠标悬浮弹出气泡提示框
2020/12/23 jQuery
[04:32]DOTA2著名解说配音敌法师 现场专访海涛怒切假腿
2013/12/20 DOTA
浅谈Python类里的__init__方法函数,Python类的构造函数
2016/12/10 Python
Python图像处理之直线和曲线的拟合与绘制【curve_fit()应用】
2018/12/26 Python
树莓派实现移动拍照
2019/06/22 Python
浅析python表达式4+0.5值的数据类型
2020/02/26 Python
Python实现一个简单的毕业生信息管理系统的示例代码
2020/06/08 Python
Python 为什么推荐蛇形命名法原因浅析
2020/06/18 Python
Python基础教程(一)——Windows搭建开发Python开发环境
2020/07/20 Python
python-图片流传输的思路及示例(url转换二维码)
2020/12/21 Python
css3绘制百度的小度熊
2018/10/29 HTML / CSS
台湾百利市购物中心:e-Payless
2017/08/16 全球购物
英语专业大学生求职简历的自我评价
2013/10/18 职场文书
内衣营销方案
2014/03/15 职场文书
我的中国梦演讲稿1000字
2014/08/19 职场文书
2014年教育教学工作总结
2014/11/13 职场文书
小学生节约用水倡议书
2019/08/12 职场文书
对PyTorch中inplace字段的全面理解
2021/05/22 Python