#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" ); }