1. 程式人生 > >js對樹的廣度優先遍歷和深度優先遍歷

js對樹的廣度優先遍歷和深度優先遍歷

如下圖一棵樹:

廣度優先遍歷順序:ABCDEFGHIJKLMN

深度優先遍歷順序:ABEFJLMNGCDHKI

廣度優先遍歷藉助於佇列,佇列的特點是先進先出,後進後出。步驟如下:

1.將A放入佇列,將A彈出佇列;

2.將A的子節點BCD順序放入佇列(此時B在隊頭),將B彈出佇列,判斷B是否有子節點,若有則將B的子節點放入佇列,若沒有將佇列頭部元素繼續彈出佇列(上圖B有EFG三個子節點,所以將EFG順序放入,然後將C彈出佇列),繼續判斷彈出節點是否有子元素,重複此步驟直到佇列為空。

深度優先遍歷藉助於棧,棧的特點是先進後出,後進先出。步驟如下:

1.將A放入棧,將A出棧;

2.將A的子節點BCD倒序入棧(此時B在棧的頂端),將B出棧,判斷B是否有子節點,若有則將B的子節點入棧,若沒有將佇列頭部元素繼續出棧(上圖B有EFG三個子節點,所以將EFG倒序入棧,此時E在棧的頂端,所有將E出棧),繼續判斷出棧節點是否有子元素,重複此步驟直到棧為空。

程式碼如下:

class Stack { constructor(data = []) { this.data = Array.from(data) } push (v) { return this.data.push(v) } pop () { return this.data.pop() }}
class Queue { constructor(data = []) { this.data = Array.from(data) } push (v) { return this
.data.push(v) } pop () { return this.data.shift() }}
class Tree { constructor (data = []) { this.data = Array.from(data) this.queue = new Queue() this.stack = new Stack() } // 廣度優先 printBFS () { this.bfs(this.data) } bfs (data) { data
.forEach(item => { this.queue.push(item) }) this.bfsFn() } bfsFn () { if (this.queue.data.length === 0) return const popV = this.queue.pop() console.log(popV.value) if (popV.children) { this.bfs(popV.children) } else { this.bfsFn() } } // 深度優先 printDFS () { this.dfs(this.data) } dfs (data) { // 倒序將子節點壓入棧中 for (let i = data.length - 1;i >= 0;i--) { this.stack.push(data[i]) } this.dfsFn() } dfsFn () { if (this.stack.data.length === 0) return const popV = this.stack.pop() console.log(popV.value) if (popV.children) { this.dfs(popV.children) } else { this.dfsFn() } }}const tree = new Tree([{ value: 'A', children: [{ value: 'B', children: [{ value: 'E' }, { value: 'F', children: [{ value: 'J', children: [{ value: 'L' }, { value: 'M' }, { value: 'N' }] }] }, { value: 'G' }] }, { value: 'C' }, { value: 'D', children: [{ value: 'H', children: [{ value: 'K' }] }, { value: 'I' }] }]}])console.log('廣度優先遍歷:')tree.printBFS()console.log('深度優先遍歷:')tree.printDFS()

如有錯誤,歡迎大家指正