Originally Posted by
anonytmouse
INothing is impossible without recursion. Recursion is just the
lazy and dangerous version of a loop with a stack. See
this post for an example.
You are right -- the coding is only slightly more complex but the recursive method runs about twice as fast as the iterative method (see code below).
As for infinite recursion ... that isn't a problem in MS-Windows file system because there is a maximum path size. But as a general rule-of-thumb recursion has that problem.
Code:
#pragma warning(disable:4786)
#include <windows.h>
#include <stdio.h>
#include <time.h>
struct stack
{
char *path;
struct stack* next;
};
struct stack* head = NULL;
char* pop()
{
char* path = head->path;
struct stack* s = head;
head = head->next;
free(s);
return path;
}
void push(const char* path)
{
struct stack* node = (struct stack *)malloc(sizeof(struct stack));
if(node)
{
node->next = head;
node->path = strdup(path);
head = node;
}
}
size_t iterative(const char* beginPath, int* nFiles, int* nDirs)
{
WIN32_FIND_DATA data;
time_t t1;
t1 = GetTickCount();
*nFiles = 0;
*nDirs = 0;
push(beginPath);
while(head != NULL)
{
char hpath[_MAX_PATH];
char* path = pop();
char flist[_MAX_PATH];
strcpy(hpath,path);
strcpy(flist,path);
strcat(flist,"\\*.*");
free(path);
path = NULL;
HANDLE hFile = FindFirstFile(flist,&data);
if(hFile != INVALID_HANDLE_VALUE)
{
do {
if(strcmp(data.cFileName,".") != 0 && strcmp(data.cFileName,"..") != 0)
{
if( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
strcpy(flist,hpath);
strcat(flist,"\\");
strcat(flist,data.cFileName);
push(flist);
(*nDirs)++;
}
else
{
(*nFiles)++;
}
}
} while( FindNextFile(hFile, &data) != 0);
FindClose(hFile);
}
}
return GetTickCount() - t1;
}
void recursive(const char* beginPath, int* nFiles, int* nDirs)
{
WIN32_FIND_DATA data;
char flist[_MAX_PATH];
strcpy(flist,beginPath);
strcat(flist,"\\*.*");
HANDLE hFile = FindFirstFile(flist,&data);
if(hFile != INVALID_HANDLE_VALUE)
{
do {
if(strcmp(data.cFileName,".") != 0 && strcmp(data.cFileName,"..") != 0)
{
if( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
strcpy(flist,beginPath);
strcat(flist, "\\");
strcat(flist, data.cFileName);
(*nDirs)++;
recursive(flist,nFiles,nDirs);
}
else
{
(*nFiles)++;
}
}
} while( FindNextFile(hFile, &data) != 0);
FindClose(hFile);
}
}
int main()
{
int nFiles, nDirs;
time_t t = iterative("c:\\windows", &nFiles, &nDirs);
printf("time: %u Number of files: %d, Directories: %d\n", t, nFiles, nDirs);
nFiles = 0;
nDirs = 0;
t = GetTickCount();
recursive("c:\\windows", &nFiles, &nDirs);
time_t t2 = GetTickCount();
printf("time: %u Number of files: %d, Directories: %d\n", t2 - t, nFiles, nDirs);
system("PAUSE");
return 0;
}