2011-04-30 55 views
2

可能重复:
Can every recursion be converted into iteration?例子只能是递归

是否有其中一个必须使用递归的问题,有没有办法做到这一点反复?例如删除子文件夹内的文件。

public static boolean deleteFile(String sFilePath) 
{ 
    File oFile = new File(sFilePath); 
    if(oFile.isDirectory()) 
    { 
    File[] aFiles = oFile.listFiles(); 
    for(File oFileCur: aFiles) 
    { 
     deleteFile(oFileCur.getAbsolutePath()); 
    } 
    } 
    return oFile.delete(); 
} 

,我们必须手之前知道文件夹的许多水平如何,实际上那里,如果我们引入一个新的子文件,我们将不得不改变我想不出的一个以上的迭代版本代码。是否有可能以这种方式制作上述代码的迭代版本,以便将来不需要更改代码?

回答

6

您可以随时使用堆栈自己存储必要的变量,而无需递归调用的函数。

在这种情况下,人会做的文件树的深度优先遍历,以所属目录等之前先删除文件“最深的倒”

public static void deleteFile(String sFilePath) 
{ 
    File oFile = new File(sFilePath); 
    Stack<File> filesToDelete = new Stack<File>(); 
    Stack<File> directoriesToDelete = new Stack<File>(); 

    filesToDelete.push(oFile); 

    while (! filesToDelete.empty()) 
    { 
    oFile = filesToDelete.pop(); 

    if(oFile.isDirectory()) 
    { 
     File[] aFiles = oFile.listFiles(); 
     for(File oFileCur: aFiles) 
     { 
     filesToDelete.push(oFileCur); 
     } 

     // it's a directory, delete it at the end 
     // note that we'll see directories 
     // 'deeper down' later but we'll have 
     // to delete them before those 'higher up' 
     // so use a stack here to delete them 
     // after all non-directories were 
     // deleted 
     directoriesToDelete.push(oFile); 

    } 
    else 
     // it's a file, delete right now 
     oFile.delete(); 

    } 

    // delete the directories 
    while (! directories.empty()) 
    directoriesToDelete.pop().delete(); 

} 
1

如果允许适当的数据结构,它总是可以通过引入一个包含原始调用的“返回点”的堆栈来解决这种递归问题。

1

这取决于你的意思是通过迭代什么。如果你的意思是没有一个调用自己的函数,那么你可以通过明确地使用堆栈来避免递归。

0

尽管在这种情况下,队列可能更合适:

def delete(path): 
    todo = queue() 
    todo.put(path) 
    while todo: 
     item = todo.get() 
     if item.isdir(): 
      empty = True 
      for entry in item.listdir(): 
       todo.put(entry) 
       empty = False 
      if empty: 
       item.delete() 
      else: 
       todo.put(item) 
     else: 
      item.delete() 
+0

取决于是否要执行什么样的提问* *说(“删除所有文件”),或者是提问者的代码*不*(“删除所有文件和目录”)。 – 2011-04-30 09:23:47

2

你总是可以解决不递归问题。那么,没有递归就只能说明递归如何工作。

您删除子文件夹例如可以使用列表和循环来解决。