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 相关文章推荐
?繁体转换的class
Oct 09 PHP
模板引擎Smarty深入浅出介绍
Dec 06 PHP
php表单转换textarea换行符的方法
Sep 10 PHP
php 读取文件头判断文件类型的实现代码
Aug 05 PHP
模板引擎smarty工作原理以及使用示例
May 25 PHP
将酷狗krc歌词解析并转换为lrc歌词php源码
Jun 20 PHP
ThinkPHP分组下自定义标签库实例
Nov 01 PHP
php获取YouTube视频信息的方法
Feb 11 PHP
php读取出一个文件夹及其子文件夹下所有文件的方法示例
Jun 15 PHP
ThinkPHP 3.2.3实现加减乘除图片验证码
Dec 05 PHP
php面向对象程序设计入门教程
Jun 22 PHP
laravel清除视图缓存的代码
Oct 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中mysql连接和基本操作代码(快速测试使用,简单方便)
2014/04/25 PHP
php实现zip压缩文件解压缩代码分享(简单易懂)
2014/05/10 PHP
微信公众平台接口开发入门示例
2014/12/24 PHP
php中解析带中文字符的url函数分享
2015/01/20 PHP
关于Javascript 的 prototype问题。
2007/01/03 Javascript
firefox下对ajax的onreadystatechange的支持情况分析
2009/12/14 Javascript
javascript getElementsByClassName函数
2010/04/01 Javascript
初学js 新节点的创建 删除 的步骤
2011/07/04 Javascript
关于html+ashx开发中几个问题的解决方法
2011/07/18 Javascript
jquery获取tr并更改tr内容示例代码
2014/02/13 Javascript
jQuery插件扩展测试实例
2016/06/21 Javascript
AngularJS ng-style中使用filter
2016/09/21 Javascript
js querySelector() 使用方法
2016/12/21 Javascript
vue实现动态按钮功能
2019/05/13 Javascript
基于VUE的v-charts的曲线显示功能
2019/10/01 Javascript
JavaScript实现图片轮播特效
2019/10/23 Javascript
Python3处理文件中每个词的方法
2015/05/22 Python
Scrapy框架CrawlSpiders的介绍以及使用详解
2017/11/29 Python
react+django清除浏览器缓存的几种方法小结
2019/07/17 Python
python实现文件的分割与合并
2019/08/29 Python
Python使用grequests(gevent+requests)并发发送请求过程解析
2019/09/25 Python
Python生成验证码、计算具体日期是一年中的第几天实例代码详解
2019/10/16 Python
pytorch 实现删除tensor中的指定行列
2020/01/13 Python
谈一谈数组拼接tf.concat()和np.concatenate()的区别
2020/02/07 Python
django实现将修改好的新模型写入数据库
2020/03/31 Python
Python脚本实现Zabbix多行日志监控过程解析
2020/08/26 Python
python简单利用字典破解zip文件口令
2020/09/07 Python
Emma Bridgewater官网:英国餐具制造商
2019/11/24 全球购物
什么是.net
2015/08/03 面试题
关于赌博的检讨书
2014/01/24 职场文书
幼儿园课题方案
2014/06/09 职场文书
民警个人对照检查剖析材料
2014/09/17 职场文书
开业典礼致辞
2015/07/29 职场文书
爱护环境建议书
2015/09/14 职场文书
SQL 窗口函数实现高效分页查询的案例分析
2021/05/21 SQL Server
MySql中的json_extract函数处理json字段详情
2022/06/05 MySQL