先畫個樹,而後解釋 何爲深度, 何爲廣度html
第一層 子集 | __________________________ | | 第二層1 子集 第二層2 子集 | | ----------------- 第三層11,子集 第三層12 | 第四層111
圖就不畫太複雜了,最高四層的結構,若是換成html的形式的話能夠理解成node
<div>------第一層 <ul>----------第二層1 <li> -----------第三層 11 <span></span> -----------第四層 111 </li> <li>---------------第三層 12 </li> </ul> <p></p> ------------第一層2 <div>
深度遍歷,就是 從 第一層開始 -》 1 -》 11 -》111 -》 12 -》 2
這個意思就是,若是有下一級優先探索下一級的,沒有了話,再去探索兄弟層級(以此類推)
就是作一道菜,須要菜和調料,調料是須要調製的,好比調料須要雞汁和糖,雞汁又須要調製,那麼 正常流程 就是 ,
一、開始作菜 -》 開始調料 -》 雞汁 -》調製雞汁的材料
二、等這些弄完了,再去加糖 ,完成調料步驟
三、糖加完了,再去切菜,完成作菜步驟
這個就是一個深度的過程算法
而廣度遍歷則相反, 順序應該是 -> 1-> 2 -> 11 -> 12 -> 111
意思就是有兄弟層級優先解析兄弟層級,而後解析下一層級數組
廣度比較符合正常人的思惟,就像複習的時候,
1.先把整本書捋一遍,而後畫重點,
2.捋完以後看重點,重點內容裏面有一些具體時間,再整理出來,
3.最後重點背誦時間
廣度遍歷須要手動去終結(判斷還有沒有整理內容了)spa
根據js單線程的原理,深度很好實現,由於循環遞歸默認就是深度遍歷
把剛剛的圖 寫成一個數組線程
const arr = [ { name: '1', childrens: [ { name: '11', childrens: [ { name: '111' } ] }, { name: '12' } ] }, { name: '2' } ]
我多加了一些換行,方便看清楚code
深度遍歷htm
function check(nodeArr) { nodeArr.forEach(node => { console.log(node.name) if(node.childrens) { check(node.childrens) } }) } check(arr) // 1 11 111 12 2
這段代碼很好理解,若是有子集,將子集和父集作一樣處理,或者說,做爲一個新的參數給check這個方法。遞歸
廣度遍歷
廣度遍歷的話須要一個容器去記錄子集,等此層級的兄弟集處理完成,再去處理子集,子集的處理也以此類推
先上代碼io
function checkN(nodeX) { var node_ = []; // 用來存儲子集 nodeX.forEach(node => { console.log(node.name); if(node.childrens) { node_ = [...node_, ...node.childrens]; } }) if(node_[0]) checkN(node_); } checkN(arr) // 1 2 11 12 111
具體內容就這些了,這兩個算法我剛剛本身想着寫的,不知道和一些比較正式的文章算法是否是略有出入,我也懶得去看了
應一個大佬朋友,也是我高中同窗的要求,寫了一個非遞歸版本
這個是深度優先的.....
function check_(nodeArr) { let processList = nodeArr; while(processList[0]) { const a = processList.shift(); if(a.childrens) processList = [...a.childrens, ...processList]; console.log(a.name); } } check_(arr);// 1 11 111 12 2
這個是廣度優先的
function checkX_(nodeArr) { let processList = nodeArr; while(processList[0]) { const a = processList.shift(); if(a.childrens) { processList = [...processList,...a.childrens]; } console.log(a.name); } } checkX_(arr);// 1 2 11 12 111
這兩個代碼的類似度幾乎是百分之九十,惟一的區別就是先進先出(廣度優先),和先進後出(深度優先)
先進先出的話,後來者就排到其後面,先進後出,後來者就排到其前面那麼惟一的區別就是 processList = [...a.childrens, ...processList]; 仍是 processList = [...processList,...a.childrens];