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 相关文章推荐
加速XP搜索功能堪比vista
Mar 22 PHP
PHP 得到根目录的 __FILE__ 常量
Jul 23 PHP
php ftp文件上传函数(基础版)
Jun 03 PHP
ubuntu 编译安装php 5.3.3+memcache的方法
Aug 05 PHP
ThinkPHP3.1之D方法实例详解
Jun 20 PHP
php ci框架中加载css和js文件失败的原因及解决方法
Jul 29 PHP
phpmyadmin提示The mbstring extension is missing的解决方法
Dec 17 PHP
利用PHP将部分内容用星号替换
Apr 21 PHP
thinkphp配置文件路径的实现方法
Aug 30 PHP
php的api数据接口书写实例(推荐)
Sep 22 PHP
php指定长度分割字符串str_split函数用法示例
Jan 30 PHP
[原创]PHP实现字节数Byte转换为KB、MB、GB、TB的方法
Aug 31 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/01/03 PHP
浏览器加载、渲染和解析过程黑箱简析
2012/11/29 Javascript
jQuery中fadeIn、fadeOut、fadeTo的使用方法(图片显示与隐藏)
2013/05/08 Javascript
jquery 实现窗口的最大化不论什么情况
2013/09/03 Javascript
JS 页面计时器示例代码
2013/10/28 Javascript
HTML5之WebSocket入门3 -通信模型socket.io
2015/08/21 Javascript
详解jQuery选择器
2016/12/21 Javascript
React Js 微信禁止复制链接分享禁止隐藏右上角菜单功能
2017/05/26 Javascript
redux-saga 初识和使用
2018/03/10 Javascript
vue中的计算属性实例详解
2018/09/19 Javascript
微信小程序上传多图到服务器并获取返回的路径
2019/05/05 Javascript
ES5新增数组的实现方法
2020/05/12 Javascript
javascript canvas时钟模拟器
2020/07/13 Javascript
[01:56]生活中的妖精之七夕特别档
2016/08/09 DOTA
Python实现爬取需要登录的网站完整示例
2017/08/19 Python
Python+request+unittest实现接口测试框架集成实例
2018/03/16 Python
python实现多线程网页下载器
2018/04/15 Python
Python DataFrame设置/更改列表字段/元素类型的方法
2018/06/09 Python
python提取包含关键字的整行数据方法
2018/12/11 Python
pyqt5利用pyqtDesigner实现登录界面
2019/03/28 Python
Django自定义模板过滤器和标签的实现方法
2019/08/21 Python
flask框架url与重定向操作实例详解
2020/01/25 Python
多个python文件调用logging模块报错误
2020/02/12 Python
Python基于Socket实现简单聊天室
2020/02/17 Python
Python 的 f-string 可以连接字符串与数字的原因解析
2021/02/20 Python
python学习之使用Matplotlib画实时的动态折线图的示例代码
2021/02/25 Python
CSS3动画效果回调处理详解
2014/12/10 HTML / CSS
夏威夷航空官网:Hawaiian Airlines
2016/09/11 全球购物
伊索寓言教学反思
2014/05/01 职场文书
2014物价局民主生活会对照检查材料思想汇报
2014/09/24 职场文书
党的群众路线教育实践活动心得体会范文
2014/11/05 职场文书
中层干部考核评语
2015/01/04 职场文书
2019年工作总结范文
2019/05/21 职场文书
MySQL主从搭建(多主一从)的实现思路与步骤
2021/05/13 MySQL
使用这 6个Vue加载动画库来减少我们网站的跳出率
2021/05/18 Vue.js
SQL Server数据库基本概念、组成、常用对象与约束
2022/03/20 SQL Server