首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

怎么用广度优先算法也就是队列实现文件夹的遍历

2013-08-23 
如何用广度优先算法也就是队列实现文件夹的遍历?如题:1.现在需要检索一个文件夹,文件夹里面的子目录有20多

如何用广度优先算法也就是队列实现文件夹的遍历?
如题:
1.现在需要检索一个文件夹,文件夹里面的子目录有20多W   文件有6W之多。
2.由于文件夹的宽度大,所以适合用广度优先来提高效率。
3.需要用纯C实现!
4.需要有人能提高答案。
谢谢! 算法 遍历 广度优先
[解决办法]
网上一搜大把的。
[解决办法]
广度优先你需要一个队列结构。

1. 把根文件夹路径放入队列。
2. 从队列中取出一个文件夹路径,获得这个目录下的文件夹和文件列表。
3. 文件夹列表中的文件夹路径一一放入队列。
4. 一一处理文件列表。
5. 如果队列为空,则结束,如果队列不为空,转到第二条。
[解决办法]
是文件夹,就push进队列
是文件,就处理
循环完毕,从队列中pop一个出来,继续。
队列空,完毕。
[解决办法]
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt");
//读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录
system("dir /b /ad  c:\\*.* >d:\\alldirs.txt");
//读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字
请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。

[解决办法]
一个队列就搞定的广度搜索啊。
[解决办法]
这是我写的一段代码,相互学习。


#include <windows.h>
#include <stdio.h>

/*A simple queue*/
#define SIZE 256
struct queue
{
char data[SIZE][SIZE];
int head_index;
int tail_index;
int size;
};
typedef struct queue Queue;

Queue q;
void init_queue(Queue *q)
{
q->head_index = 0;
q->tail_index = 0;
q->size = 0;
}

int enter_queue(Queue *q, char *dir)
{
if (q->size == SIZE - 1)
return -1;
q->tail_index ++;
q->size ++;
strncpy(q->data[q->tail_index], dir, SIZE);
return 0;


}

char *del_queue(Queue *q)
{
q->head_index ++;
q->size --;
return q->data[q->head_index];
}

int is_empty_queue(Queue *q)
{
return q->size == 0 ? 1 : 0;
}

/*broad first search the directory*/
void broad_first_search_dir(char *path)
{
char next_path[SIZE];
HANDLE find;
WIN32_FIND_DATA find_file_data;

find = FindFirstFile(path, &find_file_data);
if (find == INVALID_HANDLE_VALUE)
{
printf("failed to find: %d\n", GetLastError());
return;
}

do
{
if (find_file_data.cFileName[0] == '.')
continue;
if (find_file_data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
{
memset(next_path, 0, SIZE);
strncat(next_path, path, strlen(path) - 2);
strcat(next_path, "\");
strcat(next_path, find_file_data.cFileName);
strcat(next_path, "\\*");
enter_queue(&q, next_path);
}
else
printf("%s\n", find_file_data.cFileName);
}while (FindNextFile(find, &find_file_data));

while (!is_empty_queue(&q)) 
{
broad_first_search_dir(del_queue(&q));
}
}

int main()
{
init_queue(&q);
broad_first_search_dir("E:\\vm\\*");
return 0;
}


[解决办法]
最近写了复制整个文件夹的,包括子文件夹,一层一层find,自己定义一个栈,是文件夹是push进栈,是文件是处理,循环,直到栈为空。
[解决办法]
以前写过一个,最后简单测试过,没啥问题
#ifndef _DIR_LIST_H_
#define _DIR_LIST_H_

#ifdef  __cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>

typedef struct file_list_s file_list_t;
struct file_list_s
{
    char file_name[512];
    file_list_t *next;
};

typedef struct cur_dir_s cur_dir_t;
struct cur_dir_s
{
    char dir_name[512];
    file_list_t *dir;
    file_list_t *regular;
    file_list_t *slink;
    cur_dir_t *next;


};

cur_dir_t *dir_init();
int dir_file(cur_dir_t *head, char *file_path);
void dir_info(cur_dir_t *head);
void dir_free(cur_dir_t *head);

cur_dir_t *recursive_dir_file(char *file_path);
void recursive_dir_info(cur_dir_t *head);
void recursive_dir_free(cur_dir_t *head);

void recursive_dir_and_print(char *file_path);


#ifdef __cplusplus
}
#endif


#endif



#include "filelist.h"

//static fix_mpool_t *mem_pool = NULL;
#define POOL_NUM 10000

static void destroy_list(file_list_t *head)
{
    if(!head) return;

    file_list_t *tmp;
    while(head)
    {
        tmp = head->next;
        //fmem_free(mem_pool, head);
        free(head);
        head = tmp;
    }

    return;
}

static void display_file(file_list_t *node)
{
    if(!node) return;

    while(node)
    {
        printf("name : [%s]\n", node->file_name);
        //LOG(LOG_DEBUG, "show list node : [%s]", p->file_name);
        node = node->next;
    }

    return;
}

cur_dir_t *dir_init()
{
    cur_dir_t *tmp = (cur_dir_t *)malloc(sizeof(cur_dir_t));
    if(!tmp)
    {
        fprintf(stderr,"dir_init() failed, Out Of Memory!!!\n");
        abort();
    }
    memset(tmp, 0, sizeof(cur_dir_t));
    tmp->dir = NULL;
    tmp->regular = NULL;
    tmp->slink = NULL;
    tmp->next = NULL;

    //if(!mem_pool) mem_pool = fmem_init(POOL_NUM, sizeof(file_list_t));

    return tmp;
}

void dir_free(cur_dir_t *head)


{
    if(!head) return;

    destroy_list(head->dir);
    destroy_list(head->regular);
    destroy_list(head->slink);
    free(head);

    return ;
}

int dir_file(cur_dir_t *head, char *file_path)
{
    if(!head 
[解决办法]
 !file_path) return -1;

/*
    char work_dir[512] = {0};
    if(getcwd(work_dir, sizeof(work_dir)) == NULL)
        snprintf(work_dir, sizeof(work_dir), "%s/bin", getenv("HOME"));

    if(chdir(file_path) == -1)
    {
        fprintf(stderr, "chdir() failed, path:[%s], error:[%s]\n",
                        file_path, strerror(errno));
        return -1;
    }
*/

    DIR *dir = NULL;
    struct dirent *entry;
    struct stat st;
    memset(&st, 0, sizeof(struct stat));

    if((dir = opendir(file_path)) == NULL)
    {
        fprintf(stderr, "opendir() failed, path:[%s], error:[%s]\n",
                        file_path, strerror(errno));
        return -1;
    }
    else
    {
        strncpy(head->dir_name, file_path, sizeof(head->dir_name));
        char full_name[512];
        while((entry = readdir(dir)) != NULL)
        {
            sprintf(full_name, "%s/%s", file_path, entry->d_name);
            if(stat(full_name, &st) == 0)
            {


                if(strncmp(entry->d_name, ".", 1) == 0
                   
[解决办法]
 strncmp(entry->d_name, "..", 2) == 0) continue;

                if(S_ISREG(st.st_mode))
                {
                    file_list_t *node = (file_list_t *)malloc(sizeof(*node));
                    strncpy(node->file_name, entry->d_name, sizeof(node->file_name));
                    node->next = head->regular;
                    head->regular = node;
                }
                else if(S_ISDIR(st.st_mode))
                {
                    file_list_t *node = (file_list_t *)malloc(sizeof(*node));
                    strncpy(node->file_name, entry->d_name, sizeof(node->file_name));
                    node->next = head->dir;
                    head->dir = node;
                }
                else if(S_ISLNK(st.st_mode))
                {
                    file_list_t *node = (file_list_t *)malloc(sizeof(*node));


                    strncpy(node->file_name, entry->d_name, sizeof(node->file_name));
                    node->next = head->slink;
                    head->slink = node;
                }
            }
        }
        closedir(dir);
    }

/*
    if(chdir(work_dir) == -1)
    {
        fprintf(stderr, "chdir() failed, path:[%s], error:[%s]\n",
                        work_dir, strerror(errno));
    }
*/

    return 0;
}


void dir_info(cur_dir_t *head)
{
    if(!head) return;

    printf("\n>>>>>>>>>>>>>>>cur dir name:[%s]<<<<<<<<<<<<<<<<<\n", head->dir_name);
    printf("show sub_directory info:\n");
    printf("-----------------------\n");
    display_file(head->dir);
    printf("-----------------------\n\n");

    printf("show regular file info:\n");
    printf("-----------------------\n");
    display_file(head->regular);
    printf("-----------------------\n\n");

    printf("show link file info:\n");
    printf("-----------------------\n");
    display_file(head->slink);
    printf("-----------------------\n\n");

    return ;
}

static void make_absolute_path(char *out, char *parent, char *sub)
{
    int len = strlen(parent);
    memcpy(out, parent, len+1);

    if(out[len-1] != '/')
    {
        out[len]='/';


        out[len+1] = '\0';
    }
    strcat(out, sub);

    return;
}

cur_dir_t *recursive_dir_file(char *file_path)
{
    if(!file_path) return NULL;

    cur_dir_t *dir_head = dir_init();
    int ret = dir_file(dir_head, file_path);
    if(ret == -1)
    {
        dir_free(dir_head);
        return NULL;
    }

    cur_dir_t *tail = dir_head;
    cur_dir_t *head = dir_head;
    char absolute_path[512];
    while(head)
    {
        file_list_t *sub_dir = head->dir;
        while(sub_dir)
        {
            cur_dir_t *sub_dir_info = dir_init();
            make_absolute_path(absolute_path, head->dir_name, sub_dir->file_name);
            int ret = dir_file(sub_dir_info, absolute_path);
            if(ret == -1)
            {
                dir_free(sub_dir_info);
                sub_dir = sub_dir->next;
                continue;
            }
            tail->next = sub_dir_info;
            tail = sub_dir_info;

            sub_dir = sub_dir->next;
        }
        head = head->next;
    }

    return dir_head;
}

void recursive_dir_info(cur_dir_t *head)
{
    while(head)


    {
        dir_info(head);
        head = head->next;
    }

    //fmem_info(mem_pool);
    return;
}
void recursive_dir_free(cur_dir_t *head)
{
    cur_dir_t *tmp = head;
    while(head)
    {
        tmp = head->next;
        dir_free(head);
        head = tmp;
    }
    printf("recursive_dir_free ok\n");
    //fmem_info(mem_pool);
    //fmem_destroy(mem_pool);

    return;
}

void recursive_dir_and_print(char *file_path)
{
    if(!file_path) return;

    cur_dir_t *dir_head = dir_init();
    int ret = dir_file(dir_head, file_path);
    if(ret == -1)
    {
        dir_free(dir_head);
        return;
    }

    cur_dir_t *tail = dir_head;
    cur_dir_t *head = dir_head;
    cur_dir_t *tmp;
    char absolute_path[512];
    while(head)
    {
        file_list_t *sub_dir = head->dir;
        while(sub_dir)
        {
            cur_dir_t *sub_dir_info = dir_init();
            make_absolute_path(absolute_path, head->dir_name, sub_dir->file_name);
            int ret = dir_file(sub_dir_info, absolute_path);
            if(ret == -1)
            {
                dir_free(sub_dir_info);
                sub_dir = sub_dir->next;
                continue;


            }
            tail->next = sub_dir_info;
            tail = sub_dir_info;

            sub_dir = sub_dir->next;
        }
        tmp = head;
        head = head->next;
        dir_info(tmp);
        dir_free(tmp);
    }

    //fmem_info(mem_pool);
    //fmem_destroy(mem_pool);

    return;
}


热点排行