#include <iostream>
#include <string.h>
#include <afx.h>
#include <cwchar>
#include "TreeNode.h"
#define MAX_LEN 1024
using namespace std;
struct CSNode *GetFiles(char *strPath,struct CSNode *treeN);//递归查找文件和文档
struct CSNode *InsertSibling(struct CSNode *pRoot,struct CSNode *pParent,char *filename);//是兄弟
struct CSNode *InsertChild(struct CSNode *pRoot,char *filename);//是孩子
struct CSNode *CreateTree(struct CSNode *node);//创建树节点
void PrintTree(struct CSNode *node,int nLevel);
void DeleteTree(struct CSNode *node);
void main()
{
struct CSNode *root;
root = CreateTree(root);
root = GetFiles("E://",root);
PrintTree(root,0);
DeleteTree(root);
}
/// <summary>
/// 创建第一个节点
/// </summary>
/// <param name="node">[out] struct CSNode *node:树的根。</param>
/// <returns>返回的是树的根</returns>
struct CSNode *CreateTree(struct CSNode *node)
{
node = (struct CSNode *)malloc(sizeof(struct CSNode));
if(node == NULL)
{
printf("Insufficient memory available/n");
}
else
{
strcpy(node->data,"E://project//C++_project//");
}
return node;
}
/// <summary>
/// 递归查找节点
/// </summary>
/// <param name="treeN">[out] struct CSNode *treeN:当前节点。</param>
/// <param name="strPath">[in] char *strPath:查找的路径。</param>
/// <returns>返回的是树的根节点</returns>
struct CSNode *GetFiles(char *strPath,struct CSNode *treeN)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFile;
bool isSibling = false;
struct CSNode *node = treeN;
char szPath[MAX_LEN];
char szFind[MAX_LEN];
strcpy(szPath,strPath);
strcpy(szFind,szPath);
strcat_s(szFind,"*.*");
hFile = FindFirstFile(szFind,&FindFileData);
while(INVALID_HANDLE_VALUE != hFile)
{//创建node孩子
struct CSNode *p;
struct CSNode *pCur = p;//辅助节点
p = node;//创建节点
char cfilename[256];
strcpy(cfilename,FindFileData.cFileName);
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if((strcmp(cfilename,".") != 0) &&(strcmp(cfilename,"..") != 0))//"."是当前路径,".." 是上一级的路径
{
if(isSibling == false)//是孩子
{
p = InsertChild(p,cfilename);
}
else//是兄弟 true
{
p = InsertSibling(pCur,node,cfilename);
}
// cout <<"Dir:" << FindFileData.cFileName << endl;
for(int i = 0; i < strlen(szFind);i++)
{
szFind[i] = NULL;
}
strcpy(szFind,szPath);
strcat_s(szFind,cfilename);
strcat_s(szFind,"//");
GetFiles(szFind,p);
}
}
else//是文档
{
if(isSibling == false)//孩子
{
p = InsertChild(p,cfilename);
}
else//兄弟
{
p = InsertSibling(pCur,node,cfilename);
}
//cout << FindFileData.cFileName << endl;
}
if(!FindNextFile(hFile,&FindFileData))//没有兄弟
{
hFile = INVALID_HANDLE_VALUE;
}
else//有兄弟
{
if((strcmp(cfilename,".") == 0) || (strcmp(cfilename,"..") == 0))
{
isSibling = false;
}
else
{
isSibling = true;//是兄弟
}
}
}
FindClose(hFile);
return node;
}
/// <summary>
///如果是该节点的孩子,就插入节点
/// </summary>
/// <param name="pRoot">[in] struct CSNode *pRoot:当前节点。</param>
/// <param name="filename">[in] char *filename:文件名称。</param>
/// <returns>返回的是插入孩子后的节点</returns>
struct CSNode *InsertChild(struct CSNode *pRoot,char *filename)//是孩子
{
struct CSNode *pNode, *node;
pNode = (struct CSNode *) malloc (sizeof(struct CSNode));
pRoot ->firstchild = pNode;
pNode ->parent = pRoot;
pNode ->nextsibling = NULL;
pNode ->firstchild = NULL;
node = pNode->nextsibling;
strcpy(pNode->data,filename);
return pNode;
}
/// <summary>
/// 如果是该节点的兄弟,就插入节点
/// </summary>
/// <param name="pRoot">[in] struct CSNode *pRoot:当前节点。</param>
/// <param name="pParent">[in] struct CSNode *pParent:当前节点的父节点。</param>
/// <param name="filename">[in] char *filename:文件名称。</param>
/// <returns>返回的是插入兄弟后的节点</returns>
struct CSNode *InsertSibling(struct CSNode *pRoot,struct CSNode *pParent,char *filename)//是兄弟
{
struct CSNode *pNode;
pNode = (struct CSNode *) malloc (sizeof(struct CSNode));
pRoot ->nextsibling = pNode;
pNode ->parent = pParent;
pNode ->firstchild = NULL;
pNode ->nextsibling = NULL;
strcpy(pNode->data,filename);
return pNode;
}
/// <summary>
/// 把创建的树打印出来
/// </summary>
/// <param name="node">[in] struct CSNode *node:树的根节点。</param>
/// <param name="nLevel">[in] int nLevel = 0:寻找节点的深度。</param>
void PrintTree(struct CSNode *node , int nLevel = 0)
{
if(!node) return;
static char buffer[100];
while(node != NULL)
{
const int t1 = max(0,nLevel - 1);
for(int i = t1 << 2;i > 0 ;buffer[--i] = ' ');//每一级缩进4个字符的位置,这里先把buffer的0到(t1 - 1) * 4 个字符全部设置为空格
for(int i = (t1 << 2)-4; i >= 0 ;buffer[i] = '|',i-=4);//把buffer中0,4,8,12..... 位置上的字符都设置为|;
if(nLevel) strcpy_s(&buffer[t1 << 2],5,"|___");//把最后连接文件之前的设置为"|___"
strcat_s(buffer,node ->data);//最后连接文件名
printf("%s/n",buffer);
PrintTree(node ->firstchild,nLevel + 1);//打印子节点
CSNode *tmpNode = node ->nextsibling;//循环下一个节点
node = tmpNode;
}
}
/// <summary>
/// 释放树空间
/// </summary>
/// <param name="node">[in] struct CSNode *node:树的根节点。</param>
void DeleteTree(struct CSNode *node)
{
if(!node) return;
static CSNode *ptemp;//删除节点,临时保存地址,定义为静态变量,递归的时候不保存此变量的现场,节约堆栈
while(node)
{
DeleteTree(node ->firstchild);//每次递归时保存现场,出来时恢复现场
ptemp = node;
node = node ->nextsibling;
free(ptemp);
}
}