
在現實生活中,相信每個人對樹都很熟悉,不管是柳樹、楊樹還是桃樹,可以說樹在我們生活中隨處可見;在電腦世界,樹是一種分層結構的抽象模型,
如下圖所示:

樹結構的應用很多,就例如公司的組織架構,就可以用樹來表示,如下圖:

除了組織架構,像是族譜、省市等都可以使用樹狀結構來表示。
樹有很多的術語,如下圖:

n=0時,稱為空樹;ADH ;樹結構可以說是前端中最常見的資料結構之一,比如說DOM樹、級聯選擇、樹形元件等等;
JavaScript中並沒有提供樹這個資料結構,但是我們可以透過物件和陣列來模擬一片樹,
例如下面這段程式碼:
const tree = {
value: 'A',
children: [
{
value: 'B',
children: [
{ value: 'E', 孩子: null },
{ value: 'F', 孩子: null },
],
},
{
value: 'C',
children: [{ value: 'G', children: null }],
},
{
value: 'D',
children: [
{ value: 'H', 孩子: null },
{ value: 'I', 孩子: null },
],
},
],
}所謂的深度優先遍歷演算法,就是盡可能深的去搜尋樹的分支,它的遍歷順序如下圖:

實作想法如下:
children持續進行深度優先遍歷(遞歸);實作程式碼如下:
function dfs(root) {
console.log(root.value)
root.children && root.children.forEach(dfs) // 與下面一致// if (root.children) {
// root.children.forEach(child => {
// dfs(child)
// })
// }
}
dfs(tree) // 這個tree就是前面定義的那個樹/* 結果A
B
E
F
C
G
D
H
I
*/可以看到,和圖中的順序是一致的,也就是說我們的演算法沒有問題。
所謂的廣度優先就是依序存取離根節點近的節點,它的遍歷順序如下圖:

實現想法如下:
children依次入隊;實作程式碼如下:
function bfs(root) {
// 1. 新佇列跟節點入隊const q = [root]
// 4 重複執行while (q.length > 0) {
const node = q.shift() // 2 隊頭出隊console.log(node.value)
// 3 隊頭children 依序入隊node.children &&
node.children.forEach(child => {
q.push(child)
})
}
}
bfs(tree)
/* 結果A
B
C
D
E
F
G
H
I
*/可以看到,和圖中的順序是一致的,也就是說我們的演算法沒有問題。