递归函数实现方式

上面提到,递归函数的也是借助于栈的机制实现的,但是底层对于栈的处理对于程序员来说都是透明的,程序员只需要关心应用的实现逻辑。所以说使用递归处理上述问题理解起来比较容易,代码也比较简洁。

既然使用递归函数,看名字我们就知道必须借助于自定义的函数。我先大概说一下其实现思路,具体细节我们反映在代码中。

对于每一层的函数其主要做的工作就是查找父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实现无限级分类查询(递归、非递归)的更多相关文章

  1. Reverse Linked List 递归非递归实现

    单链表反转--递归非递归实现 Java接口: ListNode reverseList(ListNode head) 非递归的实现 有2种,参考 头结点插入法 就地反转 递归的实现 1) Divide ...

  2. 【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)

    一.搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右 ...

  3. PHP无限级分类实现(递归+非递归)

    <?php /** * Created by PhpStorm. * User: qishou * Date: 15-8-2 * Time: 上午12:00 */ //准备数组,代替从数据库中检 ...

  4. 二叉树的先序、中序以及后序遍历(递归 && 非递归)

    树节点定义: class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } 递归建立二 ...

  5. 二叉树——遍历篇(递归/非递归,C++)

    二叉树--遍历篇 二叉树很多算法题都与其遍历相关,笔者经过大量学习.思考,整理总结写下二叉树的遍历篇,涵盖递归和非递归实现. 1.二叉树数据结构及访问函数 #include <stdio.h&g ...

  6. 树的广度优先遍历和深度优先遍历(递归非递归、Java实现)

    在编程生活中,我们总会遇见树性结构,这几天刚好需要对树形结构操作,就记录下自己的操作方式以及过程.现在假设有一颗这样树,(是不是二叉树都没关系,原理都是一样的) 1.广度优先遍历 英文缩写为BFS即B ...

  7. java:合并两个排序的链表(递归+非递归)

    //采用不带头结点的链表 非递归实现 public static ListNode merge(ListNode list1,ListNode list2){ if(list1==null) retu ...

  8. 全排列问题(递归&非递归&STL函数)

    问题描述: 打印输出1-9的所有全排序列,或者打印输出a-d的全排列. 思路分析: 将每个元素放到余下n-1个元素组成的队列最前方,然后对剩余元素进行全排列,依次递归下去. 比如:1 2 3 为例首先 ...

  9. 二叉树的递归,非递归遍历(java)

    import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private ...

随机推荐

  1. Swarm部署集群

    swarm-manager 是 manager node,swarm-worker是 worker node.所有节点的 Docker 版本均不低于 v1.12.在master上 docker swa ...

  2. OO第一阶段纪实

    $ 0 写在前面 在DDL一次次的推动下,历经三个周期的更迭,一个月的时光匆匆而过.谨撰此博文,以记录这一段见证成长的心路历程. $ 0-0 JAVA“一天速成”没有修习过传说中的“OO先导课”,在学 ...

  3. Manjaro下安装VirtualBox

    安装前需要知道 你需要知道你当前的内核版本 uname -r,比如输出了4.14.20-2-MANJARO那么你的内核版本为414 安装VirtualBox sudo pacman -S virtua ...

  4. Day26--Python--包

    1. from xxxx import * 从xxx导入所有. 如果XXX模块内部有__all__ 导入all中的内容. 如果没有__all__全部都导入 __all__ = ["money ...

  5. STL学习笔记:空间配置器allocator

    allocator必要接口: allocator::value_type allocator::pointer allocator::const_pointer allocator::referenc ...

  6. Tomcat源码组织结构

    Tomcat 源码组织结构 目录结构 这里所介绍的目录结构,是使用CATALINA-BASE变量定义的路径,如果没有通过配置多个CATALINA-BASE目录来使用多实例,则CATALINA-BASE ...

  7. node(基础三)_模块系统基础

      一.前言                                                                                         这篇文章主 ...

  8. python自动化开发-[第十七天]-django的ORM与其他

    今日概要: 1.name别名 2.模版的深度查询 3.模版语言之filter 4.自定义过滤器,filter和simpletag的区别 5.orm进阶 扫盲:url的组成 URL:协议+域名+端口+路 ...

  9. python bytes类型去除尾部字节

    by = b'\x01\x02' print(by) by = by.rstrip() print(by) by = by.rstrip(chr(2).encode()) print(by) b'\x ...

  10. django中文学习资料

    Django 2.0 中文官方文档地址: https://docs.djangoproject.com/zh-hans/2.0/ <Django Girls>中文版地址: https:// ...