DFS เยี่ยมชมจุดยอดย่อยก่อนที่จะเยี่ยมชมจุดยอดพี่น้อง กล่าวคือ มันสำรวจความลึกของเส้นทางใด ๆ ก่อนสำรวจความกว้างของมัน โดยทั่วไปแล้ว stack (มักจะเป็น call stack ของโปรแกรมผ่านการเรียกซ้ำ) ถูกใช้เมื่อนำอัลกอริทึมไปใช้
ต่อไปนี้เป็นวิธีการทำงานของ DFS -
- เยี่ยมชมจุดยอดที่ไม่ได้เยี่ยมชมที่อยู่ติดกัน ทำเครื่องหมายว่าเยี่ยมชมแล้ว แสดงมัน ดันเป็นกอง
- หากไม่พบจุดยอดที่อยู่ติดกัน ให้เปิดจุดยอดจากสแต็ก (มันจะแสดงจุดยอดทั้งหมดจากสแต็ก ซึ่งไม่มีจุดยอดที่อยู่ติดกัน)
- ทำซ้ำกฎ 1 และกฎ 2 จนกว่าสแต็กจะว่างเปล่า
ให้เรามาดูภาพประกอบว่า DFS Traversal ทำงานอย่างไร
| ขั้นตอน | การเดินทาง | คำอธิบาย |
|---|---|---|
| 1 | ![]() | เริ่มต้นสแต็ก |
| 2 | ![]() | มาร์ค S ตามที่เยี่ยมชมและวางไว้บนกอง สำรวจโหนดที่อยู่ติดกันที่ยังไม่ได้เยี่ยมชมจาก S . เรามีสามโหนดและเราสามารถเลือกโหนดใดก็ได้ สำหรับตัวอย่างนี้ เราจะใช้โหนดตามลำดับตัวอักษร |
| 3 | ![]() | มาร์ค A ตามที่เยี่ยมชมและวางไว้บนกอง สำรวจโหนดที่อยู่ติดกันที่ยังไม่ได้เยี่ยมชมจาก A . ทั้ง S และ D อยู่ติดกับ A แต่เรากังวลกับโหนดที่ไม่ได้เยี่ยมชมเท่านั้น |
| 4 | ![]() | เยี่ยมชม D และทำเครื่องหมายว่าเยี่ยมชมแล้ววางลงบนกอง ที่นี่ เรามี B และ C โหนดซึ่งอยู่ติดกับ D และทั้งสองก็ไม่มีใครมาเยี่ยมเยียน อย่างไรก็ตาม เราจะเลือกตามลำดับตัวอักษรอีกครั้ง |
| 5 | ![]() | เราเลือก B ทำเครื่องหมายว่าเยี่ยมชมแล้ววางลงบนกอง ที่นี่ B ไม่มีโหนดที่อยู่ติดกันที่ยังไม่ได้เยี่ยมชม เราก็เลย B จากกอง |
| 6 | ![]() | เราตรวจสอบบนสแต็กด้านบนเพื่อกลับไปยังโหนดก่อนหน้าและตรวจสอบว่ามีโหนดที่ยังไม่ได้เยี่ยมชมหรือไม่ ที่นี่เราพบ D ที่จะอยู่บนสุดของกอง |
| 7 | ![]() | เฉพาะโหนดที่อยู่ติดกันที่ไม่ได้เยี่ยมชมเท่านั้นที่มาจาก D คือ C ตอนนี้. เลยแวะ C ทำเครื่องหมายว่าเยี่ยมชมแล้ววางลงบนสแต็ก |
เป็น C ไม่มีโหนดที่อยู่ติดกันที่ยังไม่ได้เยี่ยมชม ดังนั้นเราจึงเปิดสแต็กต่อไปจนกว่าเราจะพบโหนดที่มีโหนดที่อยู่ติดกันที่ยังไม่ได้เยี่ยมชม ในกรณีนี้ จะไม่มีและเราจะแสดงต่อไปจนกว่าสแต็กจะว่างเปล่า มาดูกันว่าเราจะใช้สิ่งนี้ใน JavaScript ได้อย่างไร
ตัวอย่าง
DFS(node) {
// Create a Stack and add our initial node in it
let s = new Stack(this.nodes.length);
let explored = new Set();
s.push(node);
// Mark the first node as explored
explored.add(node);
// We'll continue till our Stack gets empty
while (!s.isEmpty()) {
let t = s.pop();
// Log every element that comes out of the Stack
console.log(t);
// 1. In the edges object, we search for nodes this node is directly connected to.
// 2. We filter out the nodes that have already been explored.
// 3. Then we mark each unexplored node as explored and push it to the Stack.
this.edges[t]
.filter(n => !explored.has(n))
.forEach(n => {
explored.add(n);
s.push(n);
});
}
} นั่นเป็นเรื่องง่าย เราเพิ่งเปลี่ยนคิวสำหรับสแต็กและ voila เรามี DFS นั่นเป็นข้อแตกต่างเพียงอย่างเดียวระหว่าง 2 DFS ที่สามารถใช้งานได้โดยใช้การเรียกซ้ำ แต่ควรหลีกเลี่ยงในกรณีนี้ เนื่องจากกราฟที่ใหญ่ขึ้นหมายความว่าเราต้องการหน่วยความจำเพิ่มเติมเพียงเพื่อติดตาม call stack
คุณสามารถทดสอบได้โดยใช้ −
let g = new Graph();
g.addNode("A");
g.addNode("B");
g.addNode("C");
g.addNode("D");
g.addNode("E");
g.addNode("F");
g.addNode("G");
g.addEdge("A", "C");
g.addEdge("A", "B");
g.addEdge("A", "D");
g.addEdge("D", "E");
g.addEdge("E", "F");
g.addEdge("B", "G");
g.DFS("A"); ผลลัพธ์
สิ่งนี้จะให้ผลลัพธ์
A D E F B G C






