如何把递归改为循环模式

如何把一个递归获取所有子目录的函数写成使用循环调用的,下面的我的实例递归代码,主要想举一反三,所以想知道大致是个什么实现思路。

        public static List<string> files = new List<string>();
        public static void GetFiles(DirectoryInfo file) {
            string path = file.FullName;
            bool isFile = File.Exists(path);
            bool isDir = Directory.Exists(path);
            if (!isFile && !isDir) {
                return;
            } else if (isFile) {//是文件
                files.Add(path);
                return;
            }
            //是文件夹
            FileSystemInfo[] fis = file.GetFileSystemInfos();
            foreach (FileSystemInfo fi in fis) {
                //文件夹,递归
                DirectoryInfo tempDirPath = new DirectoryInfo(fi.FullName);
                GetFiles(tempDirPath);

            }
        }

要将递归获取所有子目录的函数改为循环调用,可以使用栈(Stack)数据结构来实现。具体实现思路如下:

  1. 将根目录压入栈中,并标记为未访问状态。

  2. 在循环中,取出栈顶元素,如果该元素是文件,则把文件路径加入列表中。如果该元素是目录且未访问过,则将该目录下所有子节点压入栈中,并标记为未访问状态。

  3. 重复执行第2步,直到栈为空。

下面是使用循环实现获取所有子目录的代码:

        public static List<string> files = new List<string>();
        public static void GetFiles(string path) {
            Stack<DirectoryInfo> stack = new Stack<DirectoryInfo>();
            stack.Push(new DirectoryInfo(path)); //将根目录压入栈中
            while (stack.Count > 0) {
                DirectoryInfo dir = stack.Pop();
                string dirPath = dir.FullName;
                bool isFile = File.Exists(dirPath);
                bool isDir = Directory.Exists(dirPath);
                if (!isFile && !isDir) {
                    continue;
                } else if (isFile) { //是文件
                    files.Add(dirPath);
                    continue;
                }
                //是目录
                if (dir.Attributes == FileAttributes.Directory) {
                    DirectoryInfo[] dirs = dir.GetDirectories();
                    foreach (DirectoryInfo d in dirs) {
                        stack.Push(d); //将子节点压入栈中
                    }
                    FileInfo[] fileInfos = dir.GetFiles();
                    foreach (FileInfo f in fileInfos) {
                        files.Add(f.FullName);
                    }
                }
            }
        }

该回答引用gpt:
要将递归函数改写成循环调用的形式,可以使用栈来实现。具体实现方法如下:

  1. 创建一个空栈,将根目录压入栈中。

  2. 循环执行以下步骤,直到栈为空:

    a. 弹出栈顶元素,判断其是否为目录。

    b. 如果是目录,则将该目录下的所有子目录和文件依次压入栈中。

    c. 如果是文件,则将文件路径添加到结果列表中。

  3. 返回结果列表。

以下是使用栈实现递归获取所有子目录的代码示例:

public static List<string> GetFiles(DirectoryInfo root)
{
    var stack = new Stack<DirectoryInfo>();
    var files = new List<string>();

    stack.Push(root);
    while (stack.Count > 0)
    {
        var dir = stack.Pop();
        if (dir.Exists)
        {
            foreach (var file in dir.GetFiles())
            {
                files.Add(file.FullName);
            }
            foreach (var subDir in dir.GetDirectories())
            {
                stack.Push(subDir);
            }
        }
    }

    return files;
}

这个函数接受一个根目录作为参数,返回该目录下所有文件的路径列表。函数内部使用了一个栈来保存目录信息,通过循环不断地从栈中弹出目录并将其子目录和文件压入栈中,直到栈为空为止。