目錄
前言
在cmd命令中有一個tree命令來顯示目錄及文件,類似下圖:
樹轉二叉樹
其中,大寫字母的表示目錄,小寫字母的表示文件。根據左孩子右兄弟的規律,目錄下有文件或目錄則有左孩子,文件沒有左孩子,目錄XXX下的某個目錄或文件,若接下來目錄XXX還有其他目錄或文件,則有右孩子,否則沒有。
思路:之前寫過文章二叉樹基本操作函數(先、中、後、層次遍歷,含全部代碼), 我們將其改爲保存字符串的二叉樹,選擇先序遍歷函數,寫一個賦值函數,"#"代表爲NULL。另外,目錄下文件或目錄太多可能運行不出來,我們添加深度限制,減少遞歸深度,以上目錄的讀取順序爲:AAA BBB eee # FFF # # ccc # DDD ggg # # # #。
全部代碼
#include <iostream>
#include <io.h>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#define depth_limit 1 //開啓深度限制
#define max_depth 1 //最大深度2層
using namespace std;
//鏈式二叉樹數據結構
typedef struct BiTNode
{
char data[100];//數據域,存放目錄及文件名
struct BiTNode *lchild, *rchild;//左右孩子
}BiTNode, *BiTree;
int q = 0;
//創建二叉樹 規定數據域爲"#",則爲空 先序創建
void InitTree(BiTree &T, vector<string> files)
{
if ("#" == files[q])
{
q++;
T = NULL;
}
else {
T = new BiTNode;
strcpy_s(T->data,strlen(files[q].c_str())+1,files[q].c_str());
q++;
InitTree(T->lchild,files);
InitTree(T->rchild,files);
}
}
// 二叉樹賦值
void TreeAssign(BiTree &T,const char *path)
{
if ("#" == path) T = NULL;
else
{
T = new BiTNode;
strcpy_s(T->data,strlen(path)+1,path);
}
}
//二叉樹結點計算
int Count(BiTree T)
{
if (T == NULL)
return 0;
else
return 1 + Count(T->lchild) + Count(T->rchild);
}
//先序遍歷-遞歸
void PreOrder(BiTree T,int depth)
{
if (T != NULL)
{
for (int j = 0; j < depth; j++)
{
if (j == depth - 1)
{
cout << "|______";
}
else
cout << " ";
}
cout << T->data<<endl;
PreOrder(T->lchild,depth+1);//遞歸先序遍歷左右子樹
PreOrder(T->rchild,depth);
}
}
// 讀取文件大小
size_t GetFileSize(const std::string& file_name) {
std::ifstream in(file_name.c_str());
in.seekg(0, std::ios::end);
size_t size = in.tellg();
in.close();
return size; //單位是:byte
}
//讀取所有目錄及文件
void getAllFiles(string path, vector<string>& files, unsigned long long &filesize, int depth)
{
//文件句柄
long hFile = 0;
//文件信息
struct _finddata_t fileinfo; //很少用的文件信息讀取結構
string p; //string類很有意思的一個賦值函數:assign(),有很多重載版本
//有文件或目錄
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
if ((fileinfo.attrib & _A_SUBDIR)) //比較文件類型是否是目錄
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
files.push_back(p.assign(fileinfo.name));
if (depth_limit&&depth == max_depth)
{
files.push_back("#");
}
else
{
getAllFiles(p.assign(path).append("/").append(fileinfo.name), files, filesize, depth + 1);
}
}
}
else
{
files.push_back(p.assign(fileinfo.name));
filesize += GetFileSize(p.assign(path).append("/").append(fileinfo.name));
//文件沒有左孩子
files.push_back("#");
}
} while (_findnext(hFile, &fileinfo) == 0); //尋找下一個,成功返回0,否則-1
_findclose(hFile);
//目錄遍歷結束
files.push_back("#");
}
//沒有文件或目錄
else
{
files.push_back("#");
}
}
//主函數
int main() {
char * inPath = "F:/";
vector<string> files;
BiTree T;
files.push_back(inPath);
unsigned long long filesize = 0;
getAllFiles(inPath, files, filesize,0);
files.push_back("#");
TreeAssign(T, inPath);
TreeAssign(T->rchild, "#");
InitTree(T, files);
cout << "共" << Count(T) << "個目錄及文件," << "文件總大小爲" << filesize << "字節,目錄及文件如下:" << endl;
PreOrder(T,0);
return 0;
}
結果截圖
更多數據結構與算法實現:數據結構(嚴蔚敏版)與算法的實現(含全部代碼)
有問題請下方評論,轉載請註明出處,並附有原文鏈接,謝謝!如有侵權,請及時聯繫。