本文实例讲述了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 非递归实现分类树的更多相关文章

  1. php非递归无限级分类.

    项目需要.递归无限级分类效率实在太低.理了半天思路写的. 分类越多效率越高. /** * 单次循环返回无限极分类嵌套 * @param array $data 操作的数组 * @param strin ...

  2. 非递归遍历N-ary树Java实现

    2019-03-25 14:10:51 非递归遍历二叉树的Java版本实现之前已经进行了总结,这次做的是非递归遍历多叉树的Java版本实现. 在非递归遍历二叉树的问题中我个人比较推荐的是使用双whil ...

  3. ZT 二叉树先序,中序,后序遍历非递归实现

    二叉树先序,中序,后序遍历非递归实现 分类: 数据结构及算法2012-04-28 14:30 8572人阅读 评论(6) 收藏 举报 structc 利用栈实现二叉树的先序,中序,后序遍历的非递归操作 ...

  4. c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

    二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: ...

  5. c/c++叉树的创建与遍历(非递归遍历左右中,不破坏树结构)

    二叉树的创建与遍历(非递归遍历左右中,不破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: ...

  6. 二叉树中序遍历,先序遍历,后序遍历(递归栈,非递归栈,Morris Traversal)

    例题 中序遍历94. Binary Tree Inorder Traversal 先序遍历144. Binary Tree Preorder Traversal 后序遍历145. Binary Tre ...

  7. php递归无限分类、根据子类获取所有顶类

    //递归无限分类树 public static function diGui($data, $pid) { $arr = collect([]); if (empty($data)) { return ...

  8. Best Coder Round#25 1003 树的非递归访问

    虽然官方解释是这题目里的树看作无向无环图,从答案来看还是在“以1作为根节点”这一前提下进行的,这棵树搭建好以后,从叶节点开始访问,一直推到根节点即可——很像动态规划的“自底向上”. 但这棵树的搭建堪忧 ...

  9. 二叉树之AVL树的平衡实现(递归与非递归)

    这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...

随机推荐

  1. Elasticsearch学习之深入聚合分析五---案例实战

    1. fielddata核心原理 fielddata加载到内存的过程是lazy加载的,对一个analzyed field执行聚合时,才会加载,而且是field-level加载的,一个index的一个f ...

  2. Oracle中V$SESSION等各表的字段解释,Oracle官方解释

    一.常用的视图 1.会话相关视图 View Description V$PROCESS Contains information about the currently active processe ...

  3. Web Uploader在低版本IE下无法显示Flash的一种情况

    用户反馈在IE 8下无法正常显示Web Uploader控件,并已安装了Flash插件.调试发现在内部抛出了Runtime Error的错误,关键代码如下: Runtime.create = func ...

  4. windows_xp下卸载office2003报无法打开此修补程序包错误

    今天在给公司一同事装完xp系统后.准备卸载预安装的Microsoft office2003,然后安装Microsoft office2007.结果在卸载office2003时报如下错误. 经过上网查询 ...

  5. JavaAgent入门

    JavaAgent 是JDK 1.5 以后引入的,也可以叫做Java代理. JavaAgent 是运行在 main方法之前的拦截器,它内定的方法名叫 premain ,也就是说先执行 premain ...

  6. Office Online Server2016安装手册

    Office Online Server2016安装手册 1.加入域 加入域,机器名为:OOS.Contoso.com 2.安装前提条件 运行powershell检查先决条件 Add-WindowsF ...

  7. Olivia Palermo & Johannes Huebl 模范情侣

    男才女貌,模范情侣-- 以后引用情侣时就用这个图了~ ref: http://bbs.55bbs.com/thread-8250584-1-1.html

  8. 关于IP地址子网的划分

  9. Django---简单模板遍历渲染

    简单路由: urlpatterns = [ path('admin/', admin.site.urls), path('index/', views.index), path('list/', vi ...

  10. 结对编程2—Fault&Error&Failure

    学习进度表 点滴成就 学习时间 新编写代码行数 博客量(篇) 学到知识点 第一周 8 0 0 了解软件工程 第二周 10 0 1 博文一篇 第三周 15 0 2 选择项目.调查问卷 第四周 20 80 ...