2012-02-03 36 views
9

Tôi có một hàm đệ quy trả về tất cả các nút con, cho nút gốc bắt đầu.Đệ quy với các phần tử trả về lợi nhuận trong cây

private IEnumerable<Node> getAllNodesRecursively(Node subnode) 
{ 
    foreach (Node node in subnode.Nodes) 
     getAllNodesRecursively(node); 

    yield return subnode; 
} 

Đối với cấu trúc cây sau:

A 
| 
+--B 
| 
+--C 
| | 
| +--D 
| 
+--E 

Khi tôi cố gắng lặp như vậy:

foreach (Node n in getAllNodesRecursively(a)) 
{ 
    Console.WriteLine(n); 
} 

hàm trả về chỉ A giá trị.

Tôi muốn sử dụng trả lại lợi nhuận với đệ quy và truy xuất các phần tử trong Đơn đặt hàng trước (A, B, C, D, E trong ví dụ này).

(Nếu tôi đặt lợi nhuận về lợi nhuận trước khi foreach, thì việc cho phép sẽ không bao giờ xảy ra).

Điều này có khả thi không?

+0

Bạn đã thử rằng việc bỏ qua không được gọi nếu bạn đặt lợi nhuận về trước? Tôi đoán nó sẽ được gọi. – okrumnow

+0

Vâng, bạn đã đúng. Lợi nhuận lợi nhuận không bỏ qua phần còn lại của mã. Có vẻ như đó chỉ là một cú pháp cú pháp để cho phép trả về giá trị và vẫn giữ chức năng hoạt động. Lỗi của tôi. –

Trả lời

16

Các bạn đã thử một cái gì đó như:

private IEnumerable<Node> getAllNodesRecursively(Node subnode) 
{ 
    // Return the parent before its children 
    yield return subnode; 

    foreach (Node node in subnode.Nodes) 
    { 
     foreach(Node n in getAllNodesRecursively(node)) 
     { 
      yield return n; 
     } 
    } 
} 

triển khai của bạn đang kêu gọi getAllNodesRecursively đệ quy, nhưng bỏ qua giá trị trả về của nó.

+0

Điều này có tác dụng, nhưng tại sao tôi phải lặp lại lần nữa (bên trong foreach)? Tại sao phương thức iterator không cho phép đệ quy như nó? Tôi đã thử với trình gỡ lỗi và nó chỉ đơn giản là bỏ qua cuộc gọi đệ quy của tôi trừ khi nó được sử dụng trong một lần lặp (chẳng hạn như foreach). Tại sao vậy? –

+0

@ChristianHayter "Sẽ không trả lại tất cả ngoại trừ nút trên cùng hai lần?" Số – Joe

+1

Ví dụ của Joe có thể được đơn giản hóa một chút: riêng IEnumerable getAllNodesRecursively (Nút gốc) { lợi nhuận gốc trả về; foreach (var con trong root.Nodes.SelectMany (getAllNodesRecursively)) { lợi nhuận cho trẻ em; } } – peter70

3

Có thể, chỉ cần đặt yield return trước foreach. Bạn đang suy nghĩ về hành vi của câu lệnh bình thường return.

+0

Tôi đã sửa đổi bài đăng của mình, bởi vì tôi đã sai về nội dung sẽ được hiển thị. Chỉ có phần tử đầu tiên được trả về. Nếu tôi đặt lợi nhuận trước khi rao giảng, điều tương tự cũng xảy ra. Làm thế nào mà? –

+0

Hmmm. Tôi không ở vị trí nào để tự mình thử ngay bây giờ. Bạn đã thử bước qua mã với trình gỡ rối chưa? –

+0

Trình gỡ lỗi chỉ đơn giản là bỏ qua cuộc gọi đệ quy. Đó là một điều thú vị. –

1
 public IEnumerable<int> preOrder(Node root) 
     { 
      if (root == null) 
       yield break; 

      yield return root.val; 

      if (root.left != null) 
       foreach (int i in preOrder(root.left)) 
        yield return i; 

      if (root.right != null) 
       foreach (int i in preOrder(root.right)) 
        yield return i; 
     } 
+0

Trong khi đoạn mã này có thể giải quyết được câu hỏi, [bao gồm cả giải thích] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho người đọc trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. – lokusking

Các vấn đề liên quan