C语言二叉树 遍历目录树

举报
清雨小竹 发表于 2022/09/24 23:42:43 2022/09/24
【摘要】 #include "stdio.h"#include "windows.h"#include <iostream>using namespace std;unsigned long sum = 0;//// 目录树链表结点定义typedef struct _tFileTreeItem{   ...

#include "stdio.h"
#include "windows.h"
#include <iostream>
using namespace std;
unsigned long sum = 0;
//
// 目录树链表结点定义
typedef struct _tFileTreeItem
{
    struct _tFileTreeItem* pPrevItem;   // 前一个单元
    struct _tFileTreeItem* pNextItem;   // 后一个单元
    struct _tFileTreeItem* pParentItem; // 父单元
    struct _tFileTreeItem* pChildItem;  // 子单元
    char FilePath[MAX_PATH];
    char FileName[MAX_PATH];
    unsigned long dwHashIndex;          // 索引序号
    int level;                          // 树的深度
    int nNameLength;                    // 名称长度
    char *strItemName;                  // 单元名称,不包含路径.(可变长度)
}FileTreeItem, *PFileTreeItem;

//
//查找文件或文件夹,保存到树中
void FindDir( FileTreeItem* TreeNode )
{
    WIN32_FIND_DATA fd;
    HANDLE hSearch;
    char filePathName[MAX_PATH];

    FileTreeItem* temp;
    FileTreeItem* tempnode;

    ZeroMemory( &fd, sizeof(WIN32_FIND_DATA) );
    ZeroMemory( filePathName, MAX_PATH );

    strcpy_s( filePathName, MAX_PATH, TreeNode->FilePath );

    if( filePathName[strlen(filePathName) - 1] != '\\' )
    {
        strcat_s( filePathName, MAX_PATH, "\\" );
        strcat_s( TreeNode->FilePath, MAX_PATH, "\\" );
    }
    strcat_s( filePathName, MAX_PATH, "*" );

    char* wcFilePathName = filePathName;
    hSearch = FindFirstFile( wcFilePathName, &fd );
    if ( hSearch != INVALID_HANDLE_VALUE )
    {
        if( (fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
            && lstrcmp(fd.cFileName, ".") && lstrcmp(fd.cFileName,"..") )      
        {
            tempnode= new FileTreeItem;
            char *tempBuffer = fd.cFileName ;
            //保存临时节点的信息
            tempnode->level = TreeNode->level + 1;
            strcpy_s( tempnode->FilePath, MAX_PATH, TreeNode->FilePath );
            strcat_s( tempnode->FilePath, MAX_PATH, tempBuffer );
            strcpy_s( tempnode->FileName, MAX_PATH, tempBuffer );

            tempnode->pPrevItem = NULL;
            tempnode->pNextItem = NULL;
            tempnode->pParentItem = NULL;
            tempnode->pChildItem = NULL;

            if( NULL == TreeNode->pChildItem )
            {// 根结点没有孩子结点,这个就是第一个孩子结点了
                TreeNode->pChildItem = tempnode;
                tempnode->pPrevItem = tempnode->pNextItem = tempnode;// 双向循环链表指针指向自身
            }
            else
            {// 将此结点插入到父结点指向的双向循环链表中去
                temp = TreeNode->pChildItem;// 指向父结点的第一个孩子用来插入结点
                // 将此结点插入到第一个结点之前,即本级目录树的尾部【小技巧】
                tempnode->pNextItem = temp;
                tempnode->pPrevItem = temp->pPrevItem;
                temp->pPrevItem->pNextItem = tempnode;
                temp->pPrevItem = tempnode;
            }
            tempnode->pParentItem = TreeNode;// 指向父结点
            FindDir(tempnode);
        }
        while( FindNextFile(hSearch, &fd) )
        {
            if ( !lstrcmp(fd.cFileName, ".") || !lstrcmp(fd.cFileName,"..") )
            {
                continue;
            }
            else if ( (fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) || (fd.dwFileAttributes ==48)
                && lstrcmp(fd.cFileName, ".") && lstrcmp(fd.cFileName,"..") )
            { 
                tempnode= new FileTreeItem;
                char *tempBuffer = fd.cFileName ;
                //保存临时节点的信息
                tempnode->level = TreeNode->level + 1;
                strcpy_s( tempnode->FilePath, MAX_PATH, TreeNode->FilePath );
                strcat_s( tempnode->FilePath, MAX_PATH, tempBuffer );
                strcpy_s( tempnode->FileName, MAX_PATH, tempBuffer );

                tempnode->pPrevItem = NULL;
                tempnode->pNextItem = NULL;
                tempnode->pParentItem = NULL;
                tempnode->pChildItem = NULL;

                if( NULL == TreeNode->pChildItem )
                {// 根结点没有孩子结点,这个就是第一个孩子结点了
                    TreeNode->pChildItem = tempnode;
                    tempnode->pPrevItem = tempnode->pNextItem = tempnode;// 双向循环链表指针指向自身
                }
                else
                {// 将此结点插入到父结点指向的双向循环链表中去
                    temp = TreeNode->pChildItem;// 指向父结点的第一个孩子用来插入结点
                    // 将此结点插入到第一个结点之前,即本级目录树的尾部【小技巧】
                    tempnode->pNextItem = temp;
                    tempnode->pPrevItem = temp->pPrevItem;
                    temp->pPrevItem->pNextItem = tempnode;
                    temp->pPrevItem = tempnode;
                }
                tempnode->pParentItem = TreeNode;// 指向父结点
                FindDir(tempnode);
            }
            else if ( lstrcmp( fd.cFileName, ".." ) && fd.dwFileAttributes != 48 )
            {// 此时存放的是文件
                tempnode= new FileTreeItem;
                char *tempBuffer = fd.cFileName;
                //保存临时节点的信息
                tempnode->level = TreeNode->level + 1;
                strcpy_s( tempnode->FilePath, MAX_PATH, TreeNode->FilePath );
                strcat_s( tempnode->FilePath, MAX_PATH, tempBuffer );
                strcpy_s( tempnode->FileName, MAX_PATH, tempBuffer );

                tempnode->pPrevItem = NULL;
                tempnode->pNextItem = NULL;
                tempnode->pParentItem = NULL;
                tempnode->pChildItem = NULL;

                if( NULL == TreeNode->pChildItem )
                {// 根结点没有孩子结点,这个就是第一个孩子结点了
                    TreeNode->pChildItem = tempnode;
                    tempnode->pPrevItem = tempnode->pNextItem = tempnode;// 双向循环链表指针指向自身
                }
                else
                {// 将此结点插入到父结点指向的双向循环链表中去
                    temp = TreeNode->pChildItem;// 指向父结点的第一个孩子用来插入结点
                    // 将此结点插入到第一个结点之前,即本级目录树的尾部【小技巧】
                    tempnode->pNextItem = temp;
                    tempnode->pPrevItem = temp->pPrevItem;
                    temp->pPrevItem->pNextItem = tempnode;
                    temp->pPrevItem = tempnode;
                }
                tempnode->pParentItem = TreeNode;// 指向父结点
            }
        }
        FindClose(hSearch);
    }
}

//
//深度遍历
void SearchTree(FileTreeItem* treeRoot)
{
    printf(treeRoot->FilePath);
    printf("\tlevel:%d.",treeRoot->level );
    printf("\n");
    sum++;

    if( (treeRoot->pChildItem != NULL) )
    {
        SearchTree( treeRoot->pChildItem );
    }

    if ( treeRoot->pNextItem != treeRoot->pParentItem->pChildItem )
    {
        SearchTree( treeRoot->pNextItem );
    }
}

void main()
{
    char* input_path= "e:\\";
    //初始化树根节点
    DWORD dw_time_start  = GetTickCount();
    FileTreeItem *DirTreeRoot= new FileTreeItem;
    DirTreeRoot->level = 0; 
    strcpy_s( DirTreeRoot->FileName, strlen(DirTreeRoot->FileName), input_path );
    strcpy_s(DirTreeRoot->FilePath, strlen(DirTreeRoot->FilePath), input_path);
    DirTreeRoot->pPrevItem = NULL;
    DirTreeRoot->pNextItem = NULL;
    DirTreeRoot->pParentItem = DirTreeRoot;
    DirTreeRoot->pChildItem = NULL;     
    FindDir( DirTreeRoot );

    DWORD dw_time_end  = GetTickCount();
    DWORD dw_time_delta  = dw_time_end - dw_time_start;
   
    SearchTree(DirTreeRoot->pChildItem);
    cout << "目录树建立时间:" << dw_time_delta / 1000.0 << "秒." << endl;
    cout << "文件和目录的总数为:" << sum << endl;
    system( "pause" );
}

文章来源: zzzili.blog.csdn.net,作者:清雨小竹,版权归原作者所有,如需转载,请联系作者。

原文链接:zzzili.blog.csdn.net/article/details/8265453

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。