2011-04-30 54 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

你總是可以解決不遞歸問題。那麼,沒有遞歸就只能說明遞歸如何工作。

您刪除子文件夾例如可以使用列表和循環來解決。