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和ACCESS写聊天室(九)
Oct 09 PHP
PHP的array_diff()函数在处理大数组时的效率问题
Nov 27 PHP
PHP 第一节 php简介
Apr 28 PHP
PHP中使用Imagick实现各种图片效果实例
Jan 21 PHP
php实现的单一入口应用程序实例分析
Sep 23 PHP
php文档工具PHP Documentor安装与使用方法
Jan 25 PHP
Yii2框架使用计划任务的方法
May 25 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
Sep 16 PHP
使用PHPStorm+XDebug搭建单步调试环境
Nov 19 PHP
thinkPHP5框架分页样式类完整示例
Sep 01 PHP
Laravel核心解读之异常处理的实践过程
Feb 24 PHP
6个常见的 PHP 安全性攻击实例和阻止方法
Dec 16 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编写简单的文章发布程序
2015/06/18 PHP
Yii2语言国际化的配置教程
2018/08/19 PHP
浅谈php常用的7大框架的优缺点
2020/07/20 PHP
js 调用本地exe的例子(支持IE内核的浏览器)
2012/12/26 Javascript
javascript完美拖拽的实现方法
2013/09/29 Javascript
JS实现带缓冲效果打开、关闭、移动一个层的方法
2015/05/09 Javascript
js实现带圆角的多级下拉菜单效果
2015/08/28 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
JavaScript代码实现左右上下自动晃动自动移动
2016/04/08 Javascript
js传值后台中文出现乱码的解决方法
2016/06/30 Javascript
javascript数组遍历的方法实例分析
2016/09/13 Javascript
Vuex之理解Store的用法
2017/04/19 Javascript
解决IE7中使用jQuery动态操作name问题
2017/08/28 jQuery
gulp安装以及打包合并的方法教程
2017/11/19 Javascript
javascript连接mysql与php通过odbc连接任意数据库的实例
2017/12/27 Javascript
微信小程序如何像vue一样在动态绑定类名
2018/04/17 Javascript
vue router动态路由设置参数可选问题
2019/08/21 Javascript
JS实现提示效果弹出及延迟隐藏的功能
2019/08/26 Javascript
小程序实现横向滑动日历效果
2019/10/21 Javascript
vue scroll滚动判断的实现(是否滚动到底部、滚动方向、滚动节流、获取滚动区域dom元素)
2020/06/11 Javascript
详解JavaScript 高阶函数
2020/09/14 Javascript
vuex的数据渲染与修改浅析
2020/11/26 Vue.js
[59:35]DOTA2-DPC中国联赛定级赛 Aster vs DLG BO3第一场 1月8日
2021/03/11 DOTA
在Linux上安装Python的Flask框架和创建第一个app实例的教程
2015/03/30 Python
利用Python生成文件md5校验值函数的方法
2017/01/10 Python
python3.6+opencv3.4实现鼠标交互查看图片像素
2018/02/26 Python
Python实现的爬取网易动态评论操作示例
2018/06/06 Python
Python实现的拉格朗日插值法示例
2019/01/08 Python
Python进阶之使用selenium爬取淘宝商品信息功能示例
2019/09/16 Python
python 使用elasticsearch 实现翻页的三种方式
2020/07/31 Python
秘书岗位职责
2013/11/18 职场文书
创建学习型党组织实施方案
2014/03/29 职场文书
财务会计实训报告
2014/11/05 职场文书
全国助残日活动总结
2015/05/11 职场文书
2019学校请假条格式及范文
2019/06/25 职场文书
Python还能这么玩之用Python做个小游戏的外挂
2021/06/04 Python