2016-11-29 4 views
2

Как изменить этот рекурсивный цикл с нерекурсивным? Я знаю, что этот метод прост, но меня интересует нерекурсивный способ этого решения.Прогулка дерева папок без рекурсии C#

using System; 
using System.IO; 

namespace NonRecursion { 
    class NonRecursion { 
     static void Main() { 
      string createPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 

      string getPath = createPath + @"\folder"; 
      GetDirsPath(getPath); 

      Console.ReadKey(); 
     } 

     static void GetDirsPath(string getPath) { 
      string[] dirs = Directory.GetDirectories(getPath); 

      for (int i = 0; i < dirs.Length; i++) { 
       Console.WriteLine(dirs[i]); 
       GetDirsPath(dirs[i]); 
      } 
     } 
    } 
} 

Могу ли я изменить только эту функцию?

static void GetDirsPath(string getPath) { 
      string[] dirs = Directory.GetDirectories(getPath); 

      for (int i = 0; i < dirs.Length; i++) { 
       Console.WriteLine(dirs[i]); 
       GetDirsPath(dirs[i]); 
      } 
     } 
+2

Подсказка: вы хотите использовать Queue <> или Stack <> в 'GetDirsPath' – Sean

+5

Является ли это упражнением или нет? Потому что, если это не упражнение, вы должны посмотреть на версию [GetDirectories] (https://msdn.microsoft.com/en-us/library/ms143314 (v = vs.110) .aspx), которая подходит вам дерево подпапок и возвращает все с помощью одного вызова – Steve

+0

И вы должны выбрать очередь и стек по типу обхода, который вам нужно сделать, будь то ширина или первый. –

ответ

3

Как об этом:

public static IEnumerable<string> AllFolders(string root) 
{ 
    var folders = new Stack<string>(); 
    folders.Push(root); 

    while (folders.Count > 0) 
    { 
     string folder = folders.Pop(); 
     yield return folder; 

     foreach (var item in Directory.EnumerateDirectories(folder)) 
      folders.Push(item); 
    } 
} 

тестовый код (консольного приложения):

static void Main() 
{ 
    foreach (var dir in AllFolders("<your root folder here>")) 
    { 
     Console.WriteLine(dir); 
    } 
} 

Вот альтернативный подход с использованием List<string>:

public static IEnumerable<string> AllFolders(string root) 
{ 
    var folders = new List<string> {root}; 

    while (folders.Count > 0) 
    { 
     string folder = folders[folders.Count - 1]; 
     folders.RemoveAt(folders.Count-1); 
     yield return folder; 
     folders.AddRange(Directory.EnumerateDirectories(folder)); 
    } 
} 

Они оба работают то же самое:

Они сохраняют список (или стек) каталогов, которые еще не были выведены, начиная с корневого каталога.

Алгоритмы удаляют верхний (стек) или последний (список) каталог из стека/списка и выводят его. Затем они добавляют все подкаталоги этого каталога в список/стек и повторяют, пока список/стек не будет пустым.

В частности, обратите внимание, что версия List<> на самом деле просто использует List<> как Stack<>, поэтому она алгоритмически идентична.

Если вы просто хотите, чтобы сделать минимальные изменения в GetDirsPath() метода:

static void GetDirsPath(string getPath) 
{ 
    var dirs = new List<string> { getPath }; 

    while (dirs.Count > 0) 
    { 
     string dir = dirs[dirs.Count - 1]; 
     dirs.RemoveAt(dirs.Count - 1); 
     Console.WriteLine(dir); 
     dirs.AddRange(Directory.EnumerateDirectories(dir)); 
    } 
} 
+0

Он работает, но я хочу изменить функцию GetDirPath. –

+0

«Как насчет этого» похоже на «попробуй это» для меня. Мне не нравятся ответы «попробуйте», потому что я могу много попробовать, просто чтобы узнать, что это не работает. Ваш ответ сильно отличается от ответа OPs, поэтому мне кажется, что вы не преобразовали его рекурсивный код в нерекурсивный, но переписали все. –

+1

@ Mr.Pro Добавлена ​​версия с минимальными изменениями в 'GetDirsPath()'. –

1

Вы можете использовать метод GetDirectories:

string getPath = createPath + @"\folder"; 

var allDirectories = Directory.GetDirectories(getPath, "*.*", System.IO.SearchOption.AllDirectories); 

Чтобы получить перебирать через них:

foreach (string dir in allDirectories) 
{ 
    Console.WriteLine(dir); 
} 

https://msdn.microsoft.com/en-us/library/bb513869.aspx

+1

Я знаю этот метод, но я хочу только изменить функцию GetDirPath. –

Смежные вопросы