亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

php實(shí)現(xiàn)無(wú)限級(jí)分類查詢(遞歸、非遞歸)

 更新時(shí)間:2016年03月10日 15:24:05   作者:跡憶  
這篇文章分為兩種情況,介紹了在遞歸和不使用遞歸的情況下PHP實(shí)現(xiàn)無(wú)限級(jí)分類,感興趣的小伙伴們可以參考一下

做PHP這么長(zhǎng)時(shí)間,發(fā)現(xiàn)后臺(tái)管理系統(tǒng)不可少的一個(gè)應(yīng)用模塊就是對(duì)欄目的分類,一般情況下欄目都要做成是無(wú)限級(jí)的,也就是說(shuō)每個(gè)欄目理論上都可以添加子欄目。在我看來(lái)這種情況處理起來(lái)整體上說(shuō)也不是很復(fù)雜,唯一一個(gè)相對(duì)來(lái)說(shuō)較難的點(diǎn)是無(wú)限級(jí)欄目的查詢。

下面就這種情況我來(lái)向大家做一個(gè)簡(jiǎn)單的介紹,對(duì)于這種無(wú)限級(jí)欄目的查詢一般情況下有兩種方式,其中一種就是使用棧的機(jī)制,另一種是使用遞歸函數(shù)的方式(當(dāng)然遞歸函數(shù)實(shí)現(xiàn)機(jī)制也是借助于棧來(lái)實(shí)現(xiàn)的)。就這兩種方式下面我們分別介紹。

遞歸函數(shù)實(shí)現(xiàn)方式

上面提到,遞歸函數(shù)的也是借助于棧的機(jī)制實(shí)現(xiàn)的,但是底層對(duì)于棧的處理對(duì)于程序員來(lái)說(shuō)都是透明的,程序員只需要關(guān)心應(yīng)用的實(shí)現(xiàn)邏輯。所以說(shuō)使用遞歸處理上述問(wèn)題理解起來(lái)比較容易,代碼也比較簡(jiǎn)潔。

既然使用遞歸函數(shù),看名字我們就知道必須借助于自定義的函數(shù)。我先大概說(shuō)一下其實(shí)現(xiàn)思路,具體細(xì)節(jié)我們反映在代碼中。

對(duì)于每一層的函數(shù)其主要做的工作就是查找父Id為當(dāng)前Id的欄目,查找到以后再次調(diào)用自身函數(shù),將查找到的欄目的id作為下一層的父id。

其流程圖如下

圖一

不知道對(duì)于上面的解釋大家能不能理解,沒(méi)關(guān)系我們下面直接看代碼

<?php
/**
 * 個(gè)人博客:跡憶博客
 * 博客地址:www.onmpw.com
 * 遞歸實(shí)現(xiàn)無(wú)限極分類
 */
$channels = array(
  array('id'=>1,'name'=>"衣服",'parId'=>0),
  array('id'=>2,'name'=>"書(shū)籍",'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'=>"運(yùn)動(dòng)鞋",'parId'=>5),
  array('id'=>8,'name'=>"耐克",'parId'=>7),
  array('id'=>9,'name'=>"耐克",'parId'=>3),
  array('id'=>10,'name'=>"鴻星爾克",'parId'=>7),
  array('id'=>11,'name'=>"小說(shuō)",'parId'=>2),
  array('id'=>12,'name'=>"科幻小說(shuō)",'parId'=>11),
  array('id'=>13,'name'=>"古典名著",'parId'=>11),
  array('id'=>14,'name'=>"文學(xué)",'parId'=>2),
  array('id'=>15,'name'=>"四書(shū)五經(jīng)",'parId'=>14)
);
$html = array();
/**
 * 遞歸查找父id為$parid的結(jié)點(diǎn)
 * @param array $html  按照父-》子的結(jié)構(gòu)存放查找出來(lái)的結(jié)點(diǎn)
 * @param int $parid  指定的父id
 * @param array $channels  數(shù)據(jù)數(shù)組
 * @param int $dep  遍歷的深度,初始化為1
 */
function getChild(&$html,$parid,$channels,$dep){
  /*
   * 遍歷數(shù)據(jù),查找parId為參數(shù)$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);
?>

這是遞歸實(shí)現(xiàn)無(wú)限級(jí)欄目查詢的核心代碼,結(jié)合圖一對(duì)其實(shí)現(xiàn)流程應(yīng)該有一個(gè)較清晰的認(rèn)識(shí)。

非遞歸,即使用棧機(jī)制實(shí)現(xiàn)無(wú)限級(jí)欄目的查詢

在上面我們大概介紹了一下使用遞歸的方式實(shí)現(xiàn)無(wú)限級(jí)欄目的查詢,下面我們簡(jiǎn)單介紹一下非遞歸的方式。雖說(shuō)不用遞歸函數(shù)的方式,但是鑒于無(wú)限級(jí)欄目的結(jié)構(gòu)頁(yè)需要參考遞歸的實(shí)現(xiàn)機(jī)制——棧的機(jī)制,解決這一問(wèn)題。

在上學(xué)的時(shí)候老師就說(shuō),其實(shí)棧的核心機(jī)制也就四個(gè)字:先進(jìn)后出。

在這對(duì)于棧的機(jī)制不多說(shuō),主要說(shuō)一下如何借助棧實(shí)現(xiàn)無(wú)限級(jí)欄目查詢。

1. 首先將頂級(jí)欄目壓入棧中

2. 將棧頂元素出棧

3. 將出棧元素存入數(shù)組中,標(biāo)記其深度(其深度就是在其父欄目的深度上面加1)

4. 以出棧的元素為父欄目,查找其子欄目

5. 將查找到的子欄目入棧,重復(fù)步驟2

6. 判斷棧為空的話,流程結(jié)束;

通過(guò)對(duì)以上步驟的翻譯,可以將這些步驟翻譯成PHP代碼,其核心代碼如下

<?php
/**
 * 個(gè)人博客:跡憶博客
 * 博客地址:www.onmpw.com
*使用非遞歸,即使用棧的方式實(shí)現(xiàn)欄目的無(wú)限極分類查詢
*/
$channels = array(
  array('id'=>1,'name'=>"衣服",'parId'=>0),
  array('id'=>2,'name'=>"書(shū)籍",'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'=>"運(yùn)動(dòng)鞋",'parId'=>5),
  array('id'=>8,'name'=>"耐克",'parId'=>7),
  array('id'=>9,'name'=>"耐克",'parId'=>3),
  array('id'=>10,'name'=>"鴻星爾克",'parId'=>7),
  array('id'=>11,'name'=>"小說(shuō)",'parId'=>2),
  array('id'=>12,'name'=>"科幻小說(shuō)",'parId'=>11),
  array('id'=>13,'name'=>"古典名著",'parId'=>11),
  array('id'=>14,'name'=>"文學(xué)",'parId'=>2),
  array('id'=>15,'name'=>"四書(shū)五經(jīng)",'parId'=>14)
);
$stack = array(); //定義一個(gè)空棧
$html = array();  //用來(lái)保存各個(gè)欄目之間的關(guān)系以及該欄目的深度
/*
 * 自定義入棧函數(shù)
 */
function pushStack(&$stack,$channel,$dep){
  array_push($stack, array('channel'=>$channel,'dep'=>$dep));
}
/*
 * 自定義出棧函數(shù)
 */
function popStack(&$stack){
  return array_pop($stack);
}
/*
 * 首先將頂級(jí)欄目壓入棧中
 */
foreach($channels as $key=>$val){
  if($val['parId'] == 0)
    pushStack($stack,$val,0);
}
/*
 * 將棧中的元素出棧,查找其子欄目
 */
do{
  $par = popStack($stack); //將棧頂元素出棧
  /*
   * 查找以此欄目為父級(jí)欄目的id,將這些欄目入棧
   */
  for($i=0;$i<count($channels);$i++){
    if($channels[$i]['parId'] == $par['channel']['id']){
      pushStack($stack,$channels[$i],$par['dep']+1);
    }
  }
  /*
   * 將出棧的欄目以及該欄目的深度保存到數(shù)組中
   */
  $html[] = array('id'=>$par['channel']['id'],'name'=>$par['channel']['name'],'dep'=>$par['dep']);
}while(count($stack)>0);

上面就是使用非遞歸方式實(shí)現(xiàn)的。

下載代碼:https://github.com/onmpw/phpApp

總結(jié)

上面兩種方式各有利弊,雖然實(shí)現(xiàn)形式上面不同,但是鑒于無(wú)限級(jí)欄目的結(jié)構(gòu),二者實(shí)現(xiàn)的機(jī)制都是相同的——都借助棧的方式來(lái)實(shí)現(xiàn)。在現(xiàn)實(shí)情況中,我們要根據(jù)現(xiàn)實(shí)情況的需要選擇一種方式來(lái)實(shí)現(xiàn)。

相關(guān)文章

  • PHP觀察者模式實(shí)例分析【對(duì)比JS觀察者模式】

    PHP觀察者模式實(shí)例分析【對(duì)比JS觀察者模式】

    這篇文章主要介紹了PHP觀察者模式,結(jié)合實(shí)例形式對(duì)比分析JS觀察者模式實(shí)現(xiàn)方法,給出了php觀察者模式的完整定義與使用操作示例,需要的朋友可以參考下
    2019-05-05
  • PHP實(shí)現(xiàn)的簡(jiǎn)單路由和類自動(dòng)加載功能

    PHP實(shí)現(xiàn)的簡(jiǎn)單路由和類自動(dòng)加載功能

    這篇文章主要介紹了PHP實(shí)現(xiàn)的簡(jiǎn)單路由和類自動(dòng)加載功能,結(jié)合實(shí)例形式分析了php路由及類自動(dòng)加載的原理與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2018-03-03
  • 在php中判斷一個(gè)請(qǐng)求是ajax請(qǐng)求還是普通請(qǐng)求的方法

    在php中判斷一個(gè)請(qǐng)求是ajax請(qǐng)求還是普通請(qǐng)求的方法

    如何在php中判斷一個(gè)網(wǎng)頁(yè)請(qǐng)求是ajax請(qǐng)求還是普通請(qǐng)求?你可以通過(guò)傳遞參數(shù)的方法來(lái)實(shí)現(xiàn),例如使用如下網(wǎng)址請(qǐng)求
    2011-06-06
  • PHP依賴注入(DI)和控制反轉(zhuǎn)(IoC)詳解

    PHP依賴注入(DI)和控制反轉(zhuǎn)(IoC)詳解

    這篇文章主要介紹了PHP依賴注入(DI)和控制反轉(zhuǎn)(IoC)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 用PHP實(shí)現(xiàn)Ftp用戶的在線管理

    用PHP實(shí)現(xiàn)Ftp用戶的在線管理

    最近接手一案子,要求必須實(shí)現(xiàn)在線報(bào)名和上傳作品。通過(guò)FreeBSD+Apache+PHP+Mysql+FTP我實(shí)現(xiàn)了該要求
    2012-02-02
  • 用phpmyadmin更改mysql5.0登錄密碼

    用phpmyadmin更改mysql5.0登錄密碼

    mysql5.0更改登錄密碼完成架站完成大斌的BLOG也一并處理今天忙了整整一天,做了一些無(wú)聊并且重復(fù)的體力勞動(dòng),幾乎沒(méi)有學(xué)到什么東西,卻浪費(fèi)了一天時(shí)間??上В杀?,可嘆。不過(guò)總算把算服務(wù)器的MYSQL登錄密碼和PHPMYADMIN的遠(yuǎn)程訪問(wèn)方式改好了。MYSQL自4.1起就更改了加密方式,講原先16位的加密改成40位,把我害苦了,怎么都連接不上。查遍資料今天總算搞定了通過(guò)PHPMYADMIN更改MYSQL密碼,個(gè)人覺(jué)得簡(jiǎn)單實(shí)用
    2008-03-03
  • PHP查找數(shù)值數(shù)組中不重復(fù)最大和最小的10個(gè)數(shù)的方法

    PHP查找數(shù)值數(shù)組中不重復(fù)最大和最小的10個(gè)數(shù)的方法

    這篇文章主要介紹了PHP查找數(shù)值數(shù)組中不重復(fù)最大和最小的10個(gè)數(shù)的方法,涉及php中array_unique與array_slice方法的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • PHP實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求的方法總結(jié)

    PHP實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求的方法總結(jié)

    對(duì)于php發(fā)送網(wǎng)絡(luò)請(qǐng)求,我們最常用的請(qǐng)求就是curl,有時(shí)我們也會(huì)用到file_get_contents函數(shù)發(fā)送網(wǎng)絡(luò)請(qǐng)求。本文為大家總結(jié)了php實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求的方法及函數(shù),感興趣的可以學(xué)習(xí)一下
    2022-06-06
  • PHP面向?qū)ο蠖鄳B(tài)性實(shí)現(xiàn)方法簡(jiǎn)單示例

    PHP面向?qū)ο蠖鄳B(tài)性實(shí)現(xiàn)方法簡(jiǎn)單示例

    這篇文章主要介紹了PHP面向?qū)ο蠖鄳B(tài)性實(shí)現(xiàn)方法,簡(jiǎn)單說(shuō)明了面向?qū)ο蠖鄳B(tài)性的原理并結(jié)合具體實(shí)例給出了php實(shí)現(xiàn)多態(tài)性的相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09
  • php生成高清縮略圖實(shí)例詳解

    php生成高清縮略圖實(shí)例詳解

    這篇文章主要介紹了php生成高清縮略圖的方法,較為詳細(xì)的分析了php生成縮略圖時(shí)出現(xiàn)失真的解決方法,并給出了完整實(shí)例進(jìn)行總結(jié)分析,需要的朋友可以參考下
    2015-12-12

最新評(píng)論