本文目錄
- 回顧數(shù)組本篇使用的五個方法
- 深度優(yōu)先遍歷 (遞歸方法) 思路+代碼
- 深度優(yōu)先遍歷 (非遞歸方法) 思路+代碼
- 廣度優(yōu)先遍歷 (非遞歸方法) 思路+代碼
雖然剛好舉的例子是二叉樹,但是幾個叉都能遍歷哈,因為遍歷思路和叉數(shù)沒關(guān)系
需求:遍歷root拿到所有的 'name' 值
var root = {
name: 'A',
children: [
{
name: 'B1',
children: [
{
name: 'C1',
children: [
{
name: 'D',
children: [
{
name: 'D1' ,
children: [{name: 'F1 '},{name: 'F2'}]
},
{ name: 'D2' }
]
}
]
}
]
},
{
name: 'B2',
children: [ {name: 'C2' }, { name: 'C3' } ]
}
]
}
1. 首先回顧下本篇用到的數(shù)組的5個方法
方法 | 參數(shù) | 作用 | 返回值 |
---|---|---|---|
arr.unshift(1) | 要插入的值 | 向數(shù)組頭部插入一個值 | 新數(shù)組length |
arr.shift() | 無 | 從數(shù)組頭部取出一個值 | 取出的值 |
arr.push(1) | 要放入的值 | 向數(shù)組尾部放入一個值 | 新數(shù)組length |
arr.pop() | 無 | 從數(shù)組尾部取出一個值 | 取出的值 |
arr.reverse() | 無 | 反轉(zhuǎn)數(shù)組的值 |
2. 深度優(yōu)先遍歷 (遞歸方法) => 前序遍歷
前序遍歷: 根節(jié)點--> 左節(jié)點 --> 右節(jié)點
let arr = []; // 存放遍歷得到的 'name' 的值
function traverseTree(node) {
if (!node) {
return;
}
arr.push(node.name)
if (node.children && node.children.length > 0) {
node.children.map(item => this.traverseTree(item)) // 遞歸調(diào)用該函數(shù)
}
return arr
}
traverseTree(root);
3. 深度優(yōu)先遍歷 (非遞歸方法) 思路+代碼 => 前序遍歷
思路:
1:聲明一個數(shù)組用于存放所有的節(jié)點;
2:通過循環(huán)依次從數(shù)組stack頭部拿一個節(jié)點進(jìn)行遍歷沈矿;
3:若其有子節(jié)點,則將其子節(jié)點(即tmpNode)放入stack隊頭憨攒;
4:若其無子節(jié)點,則再次進(jìn)入while循環(huán);
function traverseTree2(node) {
if (!node) {
return;
}
let stack = []; // 用于存放所有待處理節(jié)點
let arr = []; // 存放遍歷后的結(jié)果
let tmpNode; //當(dāng)前正在被處理的節(jié)點
stack.push(node);
while (stack.length) {
tmpNode = stack.shift(); // !!
arr.push(tmpNode.name)
if (tmpNode.children && tmpNode.children.length) {
tmpNode.children.reverse().map(item => stack.unshift(item)) // !!廣度和深度唯一的區(qū)別在這里
}
}
return arr
}
廣度優(yōu)先遍歷 (非遞歸方法) 思路+代碼 => 按層遍歷
思路:
與深度優(yōu)先唯一不同點是遍歷當(dāng)前節(jié)點時,若其有子節(jié)點時, 則將其子節(jié)點放于stack的尾部;
function traverseTree3(node) {
if (!node) {
return;
}
let stack = []; // 用于存放所有待處理節(jié)點
let arr = []; // 存放遍歷后的結(jié)果
let tmpNode; //當(dāng)前正在被處理的節(jié)點
stack.push(node);
while (stack.length) {
tmpNode = stack.shift(); // !!
// 當(dāng)前節(jié)點的'name'屬性放進(jìn)arr
arr.push(tmpNode.name);
if (tmpNode.children && tmpNode.children.length) {
tmpNode.children.map(item => stack.push(item)) // !!
}
}
return arr;
}