php实现无限级分类查询(递归、非递归)
递归函数实现方式
上面提到,递归函数的也是借助于栈的机制实现的,但是底层对于栈的处理对于程序员来说都是透明的,程序员只需要关心应用的实现逻辑。所以说使用递归处理上述问题理解起来比较容易,代码也比较简洁。
既然使用递归函数,看名字我们就知道必须借助于自定义的函数。我先大概说一下其实现思路,具体细节我们反映在代码中。
对于每一层的函数其主要做的工作就是查找父Id为当前Id的栏目,查找到以后再次调用自身函数,将查找到的栏目的id作为下一层的父id。
其流程图如下

不知道对于上面的解释大家能不能理解,没关系我们下面直接看代码
<?php
/**
* 个人博客:迹忆博客
* 博客地址:www.onmpw.com
* 递归实现无限极分类
*/
$channels = array(
array('id'=>1,'name'=>"衣服",'parId'=>0),
array('id'=>2,'name'=>"书籍",'parId'=>0),
array('id'=>3,'name'=>"T恤",'parId'=>1),
array('id'=>4,'name'=>"裤子",'parId'=>1),
array('id'=>5,'name'=>"鞋子",'parId'=>1),
array('id'=>6,'name'=>"皮鞋",'parId'=>5),
array('id'=>7,'name'=>"运动鞋",'parId'=>5),
array('id'=>8,'name'=>"耐克",'parId'=>7),
array('id'=>9,'name'=>"耐克",'parId'=>3),
array('id'=>10,'name'=>"鸿星尔克",'parId'=>7),
array('id'=>11,'name'=>"小说",'parId'=>2),
array('id'=>12,'name'=>"科幻小说",'parId'=>11),
array('id'=>13,'name'=>"古典名著",'parId'=>11),
array('id'=>14,'name'=>"文学",'parId'=>2),
array('id'=>15,'name'=>"四书五经",'parId'=>14)
);
$html = array();
/**
* 递归查找父id为$parid的结点
* @param array $html 按照父-》子的结构存放查找出来的结点
* @param int $parid 指定的父id
* @param array $channels 数据数组
* @param int $dep 遍历的深度,初始化为1
*/
function getChild(&$html,$parid,$channels,$dep){
/*
* 遍历数据,查找parId为参数$parid指定的id
*/
for($i = 0;$i<count($channels);$i++){
if($channels[$i]['parId'] == $parid){
$html[] = array('id'=>$channels[$i]['id'],'name'=>$channels[$i]['name'],'dep'=>$dep);
getChild($html,$channels[$i]['id'],$channels,$dep+1);
}
}
}
getChild($html,0,$channels,1);
?>
这是递归实现无限级栏目查询的核心代码,结合图一对其实现流程应该有一个较清晰的认识。
非递归,即使用栈机制实现无限级栏目的查询
在上面我们大概介绍了一下使用递归的方式实现无限级栏目的查询,下面我们简单介绍一下非递归的方式。虽说不用递归函数的方式,但是鉴于无限级栏目的结构页需要参考递归的实现机制——栈的机制,解决这一问题。
在上学的时候老师就说,其实栈的核心机制也就四个字:先进后出。
在这对于栈的机制不多说,主要说一下如何借助栈实现无限级栏目查询。
1. 首先将顶级栏目压入栈中
2. 将栈顶元素出栈
3. 将出栈元素存入数组中,标记其深度(其深度就是在其父栏目的深度上面加1)
4. 以出栈的元素为父栏目,查找其子栏目
5. 将查找到的子栏目入栈,重复步骤2
6. 判断栈为空的话,流程结束;
通过对以上步骤的翻译,可以将这些步骤翻译成PHP代码,其核心代码如下
<?php
/**
* 个人博客:迹忆博客
* 博客地址:www.onmpw.com
*使用非递归,即使用栈的方式实现栏目的无限极分类查询
*/
$channels = array(
array('id'=>1,'name'=>"衣服",'parId'=>0),
array('id'=>2,'name'=>"书籍",'parId'=>0),
array('id'=>3,'name'=>"T恤",'parId'=>1),
array('id'=>4,'name'=>"裤子",'parId'=>1),
array('id'=>5,'name'=>"鞋子",'parId'=>1),
array('id'=>6,'name'=>"皮鞋",'parId'=>5),
array('id'=>7,'name'=>"运动鞋",'parId'=>5),
array('id'=>8,'name'=>"耐克",'parId'=>7),
array('id'=>9,'name'=>"耐克",'parId'=>3),
array('id'=>10,'name'=>"鸿星尔克",'parId'=>7),
array('id'=>11,'name'=>"小说",'parId'=>2),
array('id'=>12,'name'=>"科幻小说",'parId'=>11),
array('id'=>13,'name'=>"古典名著",'parId'=>11),
array('id'=>14,'name'=>"文学",'parId'=>2),
array('id'=>15,'name'=>"四书五经",'parId'=>14)
);
$stack = array(); //定义一个空栈
$html = array(); //用来保存各个栏目之间的关系以及该栏目的深度
/*
* 自定义入栈函数
*/
function pushStack(&$stack,$channel,$dep){
array_push($stack, array('channel'=>$channel,'dep'=>$dep));
}
/*
* 自定义出栈函数
*/
function popStack(&$stack){
return array_pop($stack);
}
/*
* 首先将顶级栏目压入栈中
*/
foreach($channels as $key=>$val){
if($val['parId'] == 0)
pushStack($stack,$val,0);
}
/*
* 将栈中的元素出栈,查找其子栏目
*/
do{
$par = popStack($stack); //将栈顶元素出栈
/*
* 查找以此栏目为父级栏目的id,将这些栏目入栈
*/
for($i=0;$i<count($channels);$i++){
if($channels[$i]['parId'] == $par['channel']['id']){
pushStack($stack,$channels[$i],$par['dep']+1);
}
}
/*
* 将出栈的栏目以及该栏目的深度保存到数组中
*/
$html[] = array('id'=>$par['channel']['id'],'name'=>$par['channel']['name'],'dep'=>$par['dep']);
}while(count($stack)>0);
上面就是使用非递归方式实现的。
php实现无限级分类查询(递归、非递归)的更多相关文章
- Reverse Linked List 递归非递归实现
单链表反转--递归非递归实现 Java接口: ListNode reverseList(ListNode head) 非递归的实现 有2种,参考 头结点插入法 就地反转 递归的实现 1) Divide ...
- 【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)
一.搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右 ...
- PHP无限级分类实现(递归+非递归)
<?php /** * Created by PhpStorm. * User: qishou * Date: 15-8-2 * Time: 上午12:00 */ //准备数组,代替从数据库中检 ...
- 二叉树的先序、中序以及后序遍历(递归 && 非递归)
树节点定义: class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } 递归建立二 ...
- 二叉树——遍历篇(递归/非递归,C++)
二叉树--遍历篇 二叉树很多算法题都与其遍历相关,笔者经过大量学习.思考,整理总结写下二叉树的遍历篇,涵盖递归和非递归实现. 1.二叉树数据结构及访问函数 #include <stdio.h&g ...
- 树的广度优先遍历和深度优先遍历(递归非递归、Java实现)
在编程生活中,我们总会遇见树性结构,这几天刚好需要对树形结构操作,就记录下自己的操作方式以及过程.现在假设有一颗这样树,(是不是二叉树都没关系,原理都是一样的) 1.广度优先遍历 英文缩写为BFS即B ...
- java:合并两个排序的链表(递归+非递归)
//采用不带头结点的链表 非递归实现 public static ListNode merge(ListNode list1,ListNode list2){ if(list1==null) retu ...
- 全排列问题(递归&非递归&STL函数)
问题描述: 打印输出1-9的所有全排序列,或者打印输出a-d的全排列. 思路分析: 将每个元素放到余下n-1个元素组成的队列最前方,然后对剩余元素进行全排列,依次递归下去. 比如:1 2 3 为例首先 ...
- 二叉树的递归,非递归遍历(java)
import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private ...
随机推荐
- 计算机网络实验八实验报告——应用Packet Tracer 5.0模拟器工具对WLAN进行配置
计算机网络实验八实验报告 一.实验目的 1.熟练使用Packet Tracer 5.0模拟器: 2.应用Packet Tracer 5.0模拟器工具对WLAN进行配置. 二.实验环境 一台PC机. 模 ...
- Vim auto-pairs设置选项
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"'} 设置要自动配对的 ...
- Vue -- 双向过滤器去除html标签
<div id="box"> <input type="text" v-model="msg | filterHtml"& ...
- HDU 1079 Calendar Game (博弈)
Calendar Game Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- (链表 递归) leetcode 24. Swap Nodes in Pairs
Given a linked list, swap every two adjacent nodes and return its head. You may not modify the value ...
- (数论 最大公约数 最小公倍数) codeVs 1012 最大公约数和最小公倍数问题
题目描述 Description 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件: 1.P,Q是正整 ...
- PHP操作cookie
1.当只有一个参数的时候,默认是删除,响应报文里面设置了一个过去的时间 setcookie('key2'); 2.当有两个参数的时候,是设置cookie setcookie('key','value1 ...
- 打印流(PrintWriter )
PrintWriter package cn.lijun.demo1; import java.io.File; import java.io.FileNotFoundException; impor ...
- python3.x 和pip3的安装
python3.x 和pip3的安装 本人在学习python3的时候,视频中使用的是python3,在讲解到有些第三方库的时候,无法使用到pip3 install来安装所需的库.由于系统是centos ...
- mybatis多数据源报错
2018-12-06 16:58:35,709 [ main ] - [ INFO ] [ org.springframework.core.KotlinDetector : 57 ] - Kotli ...