คำตอบส่วนใหญ่ที่นำเสนอในที่นี้คือการสร้างลำดับความลึกก่อนหรือซิกแซก ตัวอย่างเช่นเริ่มต้นด้วยต้นไม้ด้านล่าง:
1 2
/ \ / \
/ \ / \
/ \ / \
/ \ / \
11 12 21 22
/ \ / \ / \ / \
/ \ / \ / \ / \
111 112 121 122 211 212 221 222
คำตอบของ dasblinkenlight สร้างลำดับที่แบนราบ:
111, 112, 121, 122, 11, 12, 211, 212, 221, 222, 21, 22, 1, 2
คำตอบของ Konamiman (ซึ่งสรุปคำตอบของ Eric Lippert ) สร้างลำดับที่ราบเรียบนี้:
2, 22, 222, 221, 21, 212, 211, 1, 12, 122, 121, 11, 112, 111
คำตอบของ Ivan Stoev สร้างลำดับที่ราบเรียบนี้:
1, 11, 111, 112, 12, 121, 122, 2, 21, 211, 212, 22, 221, 222
หากคุณสนใจลำดับความกว้างก่อนเช่นนี้:
1, 2, 11, 12, 21, 22, 111, 112, 121, 122, 211, 212, 221, 222
... นี่คือทางออกสำหรับคุณ:
public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source,
Func<T, IEnumerable<T>> childrenSelector)
{
var queue = new Queue<T>(source);
while (queue.Count > 0)
{
var current = queue.Dequeue();
yield return current;
var children = childrenSelector(current);
if (children == null) continue;
foreach (var child in children) queue.Enqueue(child);
}
}
ความแตกต่างในการใช้งานนั้นโดยพื้นฐานแล้วจะใช้ a Queue
แทนStack
. ไม่มีการเรียงลำดับที่แท้จริงเกิดขึ้น
ข้อควรระวัง:การใช้งานนี้ยังห่างไกลจากประสิทธิภาพที่ดีที่สุดเกี่ยวกับประสิทธิภาพของหน่วยความจำเนื่องจากส่วนใหญ่ของจำนวนองค์ประกอบทั้งหมดจะถูกเก็บไว้ในคิวภายในระหว่างการแจงนับ Stack
- การสำรวจตามต้นไม้ที่อิงตามนั้นมีประสิทธิภาพในการใช้หน่วยความจำมากกว่าการใช้งานQueue
ตามฐาน