国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

深度遞歸和廣度遞歸

stormgens / 2867人閱讀

摘要:遞歸遞歸算法在日常工作中算是用的比較多的一種,比如樹的遍歷,多層級(jí)樹狀結(jié)構(gòu)的生成,遍歷尋找某個(gè)樹節(jié)點(diǎn)等先來看下數(shù)據(jù)結(jié)構(gòu)張飛關(guān)羽劉備荀彧關(guān)平曹操貂蟬一般情況下后臺(tái)返回類似于如上的嵌套數(shù)據(jù)結(jié)構(gòu),或者說只得到一部分?jǐn)?shù)據(jù),點(diǎn)擊某個(gè)子節(jié)點(diǎn),異步加載節(jié)

遞歸

遞歸算法在日常工作中算是用的比較多的一種,比如DOM樹的遍歷,多層級(jí)樹狀結(jié)構(gòu)的生成,遍歷尋找某個(gè)樹節(jié)點(diǎn)等

1 先來看下數(shù)據(jù)結(jié)構(gòu)

var result = {
      id:0,
    name:"張飛",
      item:[
        {id:1,name:"關(guān)羽"},
        {id:2,name:"劉備",item:[
          {id:5,name:"荀彧"},
          {id:6,name:"關(guān)平"}

        ]},
        {id:3,name:"曹操"},
        {id:4,name:"貂蟬"},
      ]
}

一般情況下后臺(tái)返回類似于如上的嵌套數(shù)據(jù)結(jié)構(gòu),或者說只得到一部分?jǐn)?shù)據(jù),點(diǎn)擊某個(gè)子節(jié)點(diǎn),異步加載節(jié)點(diǎn),異步加載之后的數(shù)據(jù)可能如下:

  var result = {
  id:0,
  name:"張飛",
  item:[
    {id:1,name:"關(guān)羽"},
    {id:2,name:"劉備",item:[
      {id:5,name:"荀彧"},
      {id:6,name:"關(guān)平"}

    ]},
    //點(diǎn)擊曹操這一項(xiàng),加載出來劉禪和周倉,點(diǎn)擊周倉,又異步加載項(xiàng)羽和別姬
    {id:3,name:"曹操",item:[
      {id:8,name:"劉禪"},
      {id:9,name:"周倉",item:[
        {id:10,name:"項(xiàng)羽"},
        {id:11,name:"別姬"}
      ]}
    ]},
    {id:4,name:"貂蟬"},
  ]
}

//點(diǎn)擊曹操,返回如下數(shù)組
[
  {id:8,name:"劉禪"},
  {id:9,name:"周倉"}
]
//點(diǎn)擊周倉,返回如下數(shù)組
[
  {id:8,name:"項(xiàng)羽"},
  {id:9,name:"別姬"}
]

2 如何實(shí)現(xiàn)項(xiàng)目中的需求

以目前我做的一個(gè)react項(xiàng)目為例:需求是

將類似于這樣的數(shù)據(jù)以樹狀結(jié)構(gòu)展示出來

異步加載子節(jié)點(diǎn)的數(shù)據(jù),有可能是加載子節(jié)點(diǎn),有可能是加載同級(jí)節(jié)點(diǎn)

所以就需要定位到每次點(diǎn)擊的節(jié)點(diǎn)的位置,然后根據(jù)其他屬性判斷如何添加節(jié)點(diǎn)

關(guān)鍵就是如何通過遞歸找到對(duì)應(yīng)id的節(jié)點(diǎn)位置

我的實(shí)現(xiàn)思路就是維持一個(gè)state狀態(tài)對(duì)象,每次異步請(qǐng)求回來的數(shù)據(jù),根據(jù)返回的id來判斷點(diǎn)擊的位置(數(shù)據(jù)中所有節(jié)點(diǎn)id唯一),進(jìn)而將數(shù)據(jù)添加到state中對(duì)應(yīng)的id位置中

3 代碼實(shí)現(xiàn)遞歸

深度優(yōu)先

var item = [result]
//設(shè)置一個(gè)全局的value,存放找到對(duì)應(yīng)item的時(shí)候的引用地址
var value = null ;
//函數(shù)要有返回值,否則默認(rèn)返回undefiend
function getName(item,id){
  if(!item) return null ;
  for (var i = 0 ;i

如果想要更加的通用一些,可以稍加優(yōu)化一下

var item = [result]
function getName(item,id){
  let value = null ;
  let ret = recurision(item,id);
  return ret ;
  function recurision(item,id){
    if(!item) return null ;
    for (var i = 0 ;i

以上代碼實(shí)現(xiàn)遞歸的核心思路是依靠聲明一個(gè)外部的變量,遞歸函數(shù)內(nèi)部進(jìn)行查找,如果找到對(duì)應(yīng)的item,則將此item賦值給value,遞歸函數(shù)返回改value值;

總感覺代碼還不夠簡(jiǎn)潔,大家有好的思路歡迎隨時(shí)交流。

上面這種方法,傳入的item是數(shù)組,當(dāng)時(shí)考慮的是傳入數(shù)組可能會(huì)方便一些;

下面這種方法傳入的rootItem是對(duì)象,感覺下面這種方法會(huì)比較好一些;

這兩者采取的遞歸方式都是深度優(yōu)先的搜索方式,通過我們記錄遞歸的執(zhí)行軌跡可以看出來;

====2017/9/20更新,地鐵上看了一些文章;優(yōu)化一下代碼;

function transerDF(rootItem,id){
  var value = null ;
  (function recurse(currentItem){
    if(currentItem == null) return null ;
    console.log(currentItem.id);//記錄遞歸的執(zhí)行軌跡
    if(currentItem.item){
      for(var i = 0 ; i < currentItem.item.length ; i++){
        recurse(currentItem.item[i])
      }
    }
    if(currentItem.id == id){
      value = currentItem;
    }
  })(rootItem)
  return value ;
}
var ret = transerDF(result,1);
console.log(ret);

廣度優(yōu)先

function transerBF(rootItem,id){
  var value ;
  var queue = [];//用數(shù)組模擬隊(duì)列
  queue.push(rootItem);//放入隊(duì)列末尾
  var currentItem = queue.shift();//取出隊(duì)列中的首位
  while(currentItem){
    console.log(currentItem.id);//記錄遞歸軌跡
    if(currentItem.item){
      for(var i=0;i

以上分析通過記錄遞歸軌跡,我們可以很清晰的看到遞歸執(zhí)行的順序以及深度遞歸和廣度遞歸不同的實(shí)現(xiàn)思想;

jimwmg@foxmail.com

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/91979.html

相關(guān)文章

  • 實(shí)現(xiàn)深度遍歷廣度遍歷(遞歸與非遞歸版本)

    摘要:先畫個(gè)樹,然后解釋何為深度,何為廣度第一層子集第二層子集第二層子集第三層,子集第三層第四層圖就不畫太復(fù)雜了,最高四層的結(jié)構(gòu),如果換成的形式的話可以理解成第一層第二層 先畫個(gè)樹,然后解釋 何為深度, 何為廣度 第一層 子集 | ...

    Betta 評(píng)論0 收藏0
  • 遍歷多叉樹(遞歸、非遞歸廣度優(yōu)先、深度優(yōu)先)

    簡(jiǎn)單的遍歷一個(gè)樹形結(jié)構(gòu)數(shù)據(jù)的幾種方法、非遞歸方法效率最好。 (function (window, undefined) { var treeNodes = [ { id: 1, name: 1, children: [ { i...

    wing324 評(píng)論0 收藏0
  • js 中二叉樹的深度遍歷與廣度遍歷(遞歸實(shí)現(xiàn)與非遞歸實(shí)現(xiàn))

    摘要:樹中結(jié)點(diǎn)的最大層次稱為樹的深度或高度。二叉樹有深度遍歷和廣度遍歷,深度遍歷有前序中序和后序三種遍歷方法。二叉樹的前序遍歷可以用來顯示目錄結(jié)構(gòu)等中序遍歷可以實(shí)現(xiàn)表達(dá)式樹,在編譯器底層很有用后序遍歷可以用來實(shí)現(xiàn)計(jì)算目錄內(nèi)的文件及其信息等。 樹的簡(jiǎn)介 棧、隊(duì)列、鏈表等數(shù)據(jù)結(jié)構(gòu),都是順序數(shù)據(jù)結(jié)構(gòu)。而樹是非順序數(shù)據(jù)結(jié)構(gòu)。樹型結(jié)構(gòu)是一類非常重要的非線性結(jié)構(gòu)。直觀地,樹型結(jié)構(gòu)是以分支關(guān)系定義的層次結(jié)...

    Yuanf 評(píng)論0 收藏0
  • JS數(shù)據(jù)結(jié)構(gòu)描述之廣度遍歷深度遍歷

    摘要:一數(shù)據(jù)模型二遞歸實(shí)現(xiàn)遞歸實(shí)現(xiàn)三非遞歸廣度優(yōu)先實(shí)現(xiàn)先將第一層節(jié)點(diǎn)放入棧如果該節(jié)點(diǎn)有子節(jié)點(diǎn),繼續(xù)添加進(jìn)入棧底非遞歸廣度優(yōu)先實(shí)現(xiàn)四非遞歸深度優(yōu)先實(shí)現(xiàn)先將第一層節(jié)點(diǎn)放入棧如果該節(jié)點(diǎn)有子節(jié)點(diǎn),繼續(xù)添加進(jìn)入棧頂非遞歸深度優(yōu)先實(shí)現(xiàn) 文章來源:http://www.html-js.com/articl... 簡(jiǎn)單的遍歷一個(gè)樹形結(jié)構(gòu)數(shù)據(jù)的幾種方法、非遞歸方法效率最好。 一:數(shù)據(jù)模型: (function...

    printempw 評(píng)論0 收藏0
  • JS算法之深度優(yōu)先遍歷(DFS)廣度優(yōu)先遍歷(BFS)

    摘要:算法之深度優(yōu)先遍歷和廣度優(yōu)先遍歷背景在開發(fā)頁面的時(shí)候,我們有時(shí)候會(huì)遇到這種需求在頁面某個(gè)節(jié)點(diǎn)中遍歷,找到目標(biāo)節(jié)點(diǎn),我們正常做法是利用選擇器,或者,但在本文,我們從算法的角度去查找節(jié)點(diǎn),同時(shí)理解一下深度優(yōu)先遍歷和廣度優(yōu)先遍歷的原理。 JS算法之深度優(yōu)先遍歷(DFS)和廣度優(yōu)先遍歷(BFS) 背景 在開發(fā)頁面的時(shí)候,我們有時(shí)候會(huì)遇到這種需求:在頁面某個(gè)dom節(jié)點(diǎn)中遍歷,找到目標(biāo)dom節(jié)點(diǎn),...

    roadtogeek 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<