เมื่อทำการสำรวจต้นไม้ / กราฟความแตกต่างระหว่างความกว้างก่อนและระยะลึกก่อนคืออะไร ตัวอย่างการเข้ารหัสหรือรหัสเทียมใด ๆ จะดีมาก
เมื่อทำการสำรวจต้นไม้ / กราฟความแตกต่างระหว่างความกว้างก่อนและระยะลึกก่อนคืออะไร ตัวอย่างการเข้ารหัสหรือรหัสเทียมใด ๆ จะดีมาก
คำตอบ:
คำสองคำนี้แยกความแตกต่างระหว่างการเดินต้นไม้สองวิธี
มันอาจจะง่ายที่สุดเพียงแค่แสดงความแตกต่าง พิจารณาต้นไม้:
A
/ \
B C
/ / \
D E F
การสำรวจเส้นทางแรกที่มีความลึกจะเยี่ยมชมโหนดตามลำดับนี้
A, B, D, C, E, F
สังเกตว่าคุณลงไปถึงขาข้างหนึ่งก่อนที่จะเดินต่อไป
การสำรวจเส้นทางแรกที่กว้างที่สุดจะไปที่โหนดตามลำดับนี้
A, B, C, D, E, F
ที่นี่เราทำงานไปทั่วทุกระดับก่อนลงไป
(โปรดสังเกตว่ามีความคลุมเครือบางอย่างในคำสั่งการแวะผ่านและฉันก็โกงที่จะรักษาลำดับ "การอ่าน" ในแต่ละระดับของต้นไม้ในทั้งสองกรณีฉันสามารถไปที่ B ก่อนหรือหลัง C และในทำนองเดียวกันฉันก็สามารถ E ก่อนหรือหลัง F. สิ่งนี้อาจจะใช่หรือไม่ใช่ก็ได้ขึ้นอยู่กับการสมัครของคุณ ... )
การสำรวจเส้นทางทั้งสองประเภทนี้สามารถทำได้ด้วยการปลอมแปลง:
Store the root node in Container
While (there are nodes in Container)
N = Get the "next" node from Container
Store all the children of N in Container
Do some work on N
Container
ความแตกต่างระหว่างสองคำสั่งสำรวจเส้นทางการโกหกในการเลือกของ
การใช้งานแบบเรียกซ้ำดูเหมือนว่า
ProcessNode(Node)
Work on the payload Node
Foreach child of Node
ProcessNode(child)
/* Alternate time to work on the payload Node (see below) */
การเรียกซ้ำจะสิ้นสุดลงเมื่อคุณไปถึงโหนดที่ไม่มีลูกดังนั้นจึงรับประกันได้ว่าจะสิ้นสุดสำหรับกราฟ จำกัด
เมื่อมาถึงจุดนี้ฉันยังคงโกงเล็กน้อย ด้วยความฉลาดเล็กน้อยคุณสามารถทำงานกับโหนดตามลำดับนี้ได้:
D, B, E, F, C, A
ซึ่งเป็นรูปแบบของความลึกก่อนที่ฉันไม่ทำงานที่แต่ละโหนดจนกว่าฉันจะเดินกลับขึ้นไปบนต้นไม้ อย่างไรก็ตามฉันได้เยี่ยมชมโหนที่สูงขึ้นระหว่างทางเพื่อค้นหาลูก ๆ ของพวกเขา
การสำรวจเส้นทางนี้ค่อนข้างเป็นธรรมชาติในการใช้งานแบบเรียกซ้ำ (ใช้บรรทัด "เวลาสำรอง" ด้านบนแทนบรรทัด "งาน" บรรทัดแรก) และไม่ยากเกินไปหากคุณใช้สแต็กที่ชัดเจน แต่ฉันจะปล่อยไว้เป็นแบบฝึกหัด
A, B, D, C, E, F
- อันแรกที่นำเสนอ), infix ( D, B, A, E, C, F
- ใช้สำหรับการเรียงลำดับ: เพิ่มเป็นแผนผัง AVL จากนั้นอ่าน infix) หรือ postfix ( D, B, E, F, C, A
ทางเลือกที่นำเสนอ) ชื่อถูกกำหนดโดยตำแหน่งที่คุณประมวลผลรูท ควรสังเกตว่ามัดเท่านั้นทำให้รู้สึกสำหรับต้นไม้ไบนารี @batbrat เป็นชื่อ ... ได้รับเวลาตั้งแต่ที่คุณถามคุณอาจรู้อยู่แล้ว
ภาพนี้ควรให้ความคิดเกี่ยวกับบริบทที่คำว่าความกว้างและความลึกจะใช้
อัลกอริทึมการค้นหาความลึกแรกทำหน้าที่ราวกับว่ามันต้องการได้ไกลจากจุดเริ่มต้นโดยเร็วที่สุด
โดยทั่วไปใช้ a Stack
เพื่อจดจำว่าควรไปที่ไหนเมื่อถึงจุดจบ
กฎที่จะปฏิบัติตาม: กดจุดสุดยอด A แรกไปที่ Stack
รหัส Java:
public void searchDepthFirst() {
// Begin at vertex 0 (A)
vertexList[0].wasVisited = true;
displayVertex(0);
stack.push(0);
while (!stack.isEmpty()) {
int adjacentVertex = getAdjacentUnvisitedVertex(stack.peek());
// If no such vertex
if (adjacentVertex == -1) {
stack.pop();
} else {
vertexList[adjacentVertex].wasVisited = true;
// Do something
stack.push(adjacentVertex);
}
}
// Stack is empty, so we're done, reset flags
for (int j = 0; j < nVerts; j++)
vertexList[j].wasVisited = false;
}
แอปพลิเคชัน : การค้นหาความลึกครั้งแรกมักใช้ในการจำลองเกม (และสถานการณ์ที่เหมือนเกมในโลกแห่งความเป็นจริง) ในเกมทั่วไปคุณสามารถเลือกหนึ่งในการกระทำที่เป็นไปได้หลายอย่าง แต่ละตัวเลือกนำไปสู่การเลือกเพิ่มเติมซึ่งแต่ละทางเลือกนำไปสู่การเลือกเพิ่มเติมและอื่น ๆ ลงในกราฟของความเป็นไปได้รูปต้นไม้
Queue
ชนิดของการค้นหานี้จะดำเนินการโดยทั่วไปใช้รหัส Java:
public void searchBreadthFirst() {
vertexList[0].wasVisited = true;
displayVertex(0);
queue.insert(0);
int v2;
while (!queue.isEmpty()) {
int v1 = queue.remove();
// Until it has no unvisited neighbors, get one
while ((v2 = getAdjUnvisitedVertex(v1)) != -1) {
vertexList[v2].wasVisited = true;
// Do something
queue.insert(v2);
}
}
// Queue is empty, so we're done, reset flags
for (int j = 0; j < nVerts; j++)
vertexList[j].wasVisited = false;
}
แอปพลิเคชั่น : การค้นหาความกว้างก่อนอื่นก่อนพบจุดยอดทั้งหมดที่อยู่ห่างจากจุดเริ่มต้นหนึ่งจุดจากนั้นจุดยอดทั้งหมดที่อยู่ห่างออกไปสองขอบและอื่น ๆ สิ่งนี้มีประโยชน์หากคุณกำลังพยายามหาเส้นทางที่สั้นที่สุดจากจุดเริ่มต้นไปยังจุดสุดยอดที่กำหนด
หวังว่าควรจะเพียงพอสำหรับการทำความเข้าใจการค้นหาความกว้างและความลึกก่อน สำหรับการอ่านเพิ่มเติมฉันอยากจะแนะนำบทกราฟจากหนังสือโครงสร้างข้อมูลที่ยอดเยี่ยมโดย Robert Lafore
รับต้นไม้ไบนารีนี้:
การสำรวจเส้นทางแรกกว้าง:
ข้ามผ่านแต่ละระดับจากซ้ายไปขวา
"ฉัน G ลูก ๆ ของฉันคือ D และฉันหลานของฉันคือ B, E, H และ K หลานของพวกเขาคือ A, C, F"
- Level 1: G
- Level 2: D, I
- Level 3: B, E, H, K
- Level 4: A, C, F
Order Searched: G, D, I, B, E, H, K, A, C, F
การสำรวจเส้นทางลึกครั้งแรก: การ
สำรวจเส้นทางไม่ได้ทำผ่านข้ามระดับทั้งหมดในเวลาเดียวกัน แต่กลับข้ามไปดำดิ่งเข้าไปในความลึก (จากรากถึงใบไม้) ของต้นไม้ก่อน อย่างไรก็ตามมันค่อนข้างซับซ้อนกว่าเพียงแค่ขึ้นและลง
มีสามวิธี:
1) PREORDER: ROOT, LEFT, RIGHT.
You need to think of this as a recursive process:
Grab the Root. (G)
Then Check the Left. (It's a tree)
Grab the Root of the Left. (D)
Then Check the Left of D. (It's a tree)
Grab the Root of the Left (B)
Then Check the Left of B. (A)
Check the Right of B. (C, and it's a leaf node. Finish B tree. Continue D tree)
Check the Right of D. (It's a tree)
Grab the Root. (E)
Check the Left of E. (Nothing)
Check the Right of E. (F, Finish D Tree. Move back to G Tree)
Check the Right of G. (It's a tree)
Grab the Root of I Tree. (I)
Check the Left. (H, it's a leaf.)
Check the Right. (K, it's a leaf. Finish G tree)
DONE: G, D, B, A, C, E, F, I, H, K
2) INORDER: LEFT, ROOT, RIGHT
Where the root is "in" or between the left and right child node.
Check the Left of the G Tree. (It's a D Tree)
Check the Left of the D Tree. (It's a B Tree)
Check the Left of the B Tree. (A)
Check the Root of the B Tree (B)
Check the Right of the B Tree (C, finished B Tree!)
Check the Right of the D Tree (It's a E Tree)
Check the Left of the E Tree. (Nothing)
Check the Right of the E Tree. (F, it's a leaf. Finish E Tree. Finish D Tree)...
Onwards until...
DONE: A, B, C, D, E, F, G, H, I, K
3) POSTORDER:
LEFT, RIGHT, ROOT
DONE: A, C, B, F, E, D, H, K, I, G
การใช้งาน (aka ทำไมเราถึงสนใจ):
ฉันชอบคำอธิบาย Quora อย่างง่าย ๆ ของวิธีการสำรวจเส้นทางลึกครั้งแรกและวิธีการใช้งานทั่วไป:
"การสำรวจเส้นทางในการสั่งซื้อจะพิมพ์ค่า [เพื่อ BST (ต้นไม้ค้นหาแบบไบนารี)] "
" การสำรวจเส้นทางการสั่งซื้อล่วงหน้าใช้เพื่อสร้างสำเนาของ [แผนผังการค้นหาแบบทวิภาค] "
"การสำรวจเส้นทางของ Postorder ใช้เพื่อลบ [แผนผังการค้นหาแบบทวิภาค]"
https://www.quora.com/What-is-the-use-of-pre-order-and-post-order-traversal-of-binary-trees-in-computing
ฉันคิดว่ามันน่าสนใจที่จะเขียนทั้งคู่ในแบบที่เพียงแค่เปลี่ยนโค้ดบางบรรทัดจะให้อัลกอริธึมหนึ่งหรืออีกอันหนึ่งเพื่อคุณจะเห็นว่าดิลมาของคุณไม่แข็งแรงอย่างที่คิดในตอนแรก .
ฉันชอบการตีความ BFS เป็นการส่วนตัวที่ทำให้เกิดภูมิทัศน์: พื้นที่ที่มีระดับความสูงต่ำจะถูกน้ำท่วมเป็นอันดับแรกและจากนั้นจะมีพื้นที่สูงตามมา ถ้าคุณจินตนาการถึงความสูงของภูมิทัศน์ในฐานะที่เป็นโดดเดี่ยวอย่างที่เราเห็นในหนังสือภูมิศาสตร์มันง่ายที่จะเห็นว่า BFS เติมทุกพื้นที่ภายใต้ไอโซโทปเดียวกันในเวลาเดียวกันเช่นเดียวกับฟิสิกส์ ดังนั้นการตีความระดับความสูงเป็นระยะทางหรือราคาที่ปรับให้เป็นแนวคิดที่ค่อนข้างใช้งานง่าย
ด้วยสิ่งนี้ในใจคุณสามารถปรับความคิดที่อยู่เบื้องหลังการค้นหาความกว้างแรกเพื่อค้นหาแผนผังการขยายขั้นต่ำได้อย่างง่ายดายเส้นทางที่สั้นที่สุดและอัลกอริธึมการลดขนาดอื่น ๆ อีกมากมาย
ฉันไม่เห็นการตีความที่เป็นธรรมชาติของ DFS (เฉพาะมาตรฐานเกี่ยวกับเขาวงกต แต่มันไม่ทรงพลังเท่ากับ BFS one และน้ำท่วม) ดังนั้นสำหรับฉันดูเหมือนว่า BFS จะสัมพันธ์กับปรากฏการณ์ทางกายภาพได้ดีกว่าที่อธิบายไว้ข้างต้นในขณะที่ DFS มีความสัมพันธ์ที่ดีขึ้นกับตัวเลือก dillema บนระบบที่มีเหตุผล (เช่นคนหรือคอมพิวเตอร์ตัดสินใจว่าจะย้ายเกมหมากรุกหรือออกไปจากเขาวงกต)
ดังนั้นสำหรับฉันความแตกต่างระหว่างการโกหกซึ่งปรากฏการณ์ทางธรรมชาติที่ดีที่สุดตรงกับรูปแบบการแพร่กระจายของพวกเขา (transversing) ในชีวิตจริง