我的数据结构与算法题目集代码仓:https://github.com/617076674/Data-structure-and-algorithm-topic-set
原题链接:https://pintia.cn/problem-sets/15/problems/857
题目描述:
知识点:深度优先遍历
思路:先建树,再深度优先遍历
用结构体file来作为树的节点,其中包含char name[261]存储文件名,bool型变量isDirectory表示是目录还是文件,bool型变量visited用来表示dfs过程中该文件节点是否被访问过,vector<file>型变量subFiles存储其子目录。
题目给的每个字符串,表示的都是从root的第一个孩子开始的路径。因此,我们用一个vector<file>型变量files存储每个字符串中的文件值,依次将files中的文件通过函数void add(file &f, int index)添加进以root为根的树中。
void add(file &f, int index)函数的实现如下:
注意,这个过程中我们会改变f文件的subFile值,所以需要传递引用。
(1)如果index == files.size(),说明已经遍历完了files中的所有文件,直接return。
(2)遍历f的子目录,寻找与files[index]名字相同且同是文件或同是目录的文件,如果找到,说明files[index]已经在f的子目录中,我们考虑第index + 1个文件,即递归地调用该函数add(f.subFiles[i], index + 1),并且返回。
(3)如果(2)过程没有在f的子目录中寻找到files[index],将files[index]加入f的子孩子中,并且递归地调用该函数add(f.subFiles[f.subFiles.size() - 1], index + 1)。
从root节点开始深度优先遍历这棵文件树,并用int型level变量记录空格数。
void dfs(file &nowVisit, int level)函数的实现如下:
注意,这个过程中,我们会对f文件的subFile进行排序,所以需要传递引用。
(1)如果当前文件还未被访问过,标记其已被访问,并且对其subFile进行排序。
(2)输出当前空格数和文件名。
(3)对其subFile里的文件,递归调用dfs函数,注意level需加2。
时间复杂度和空间复杂度均与题给的数据有关,很难计算。
C++代码:
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
struct file {
char name[261];
bool isDirectory, visited;
vector<file> subFiles;
};
int N;
file root;
vector<file> files;
void add(file &f, int index);
bool cmp(file f1, file f2);
void dfs(file &nowVisit, int level);
int main() {
scanf("%d", &N);
strcpy(root.name, "root");
root.isDirectory = true;
root.visited = false;
for(int i = 0; i < N; i++) {
char line[270];
scanf("%s", line);
int j = 0;
files.clear();
while(j < strlen(line)) {
char str[270];
int point = 0;
while(j < strlen(line) && line[j] != '\\') {
str[point++] = line[j++];
}
str[point] = '\0';
file f;
if(j < strlen(line)) {
f.isDirectory = true;
} else {
f.isDirectory = false;
}
f.visited = false;
strcpy(f.name, str);
files.push_back(f);
j++;
}
add(root, 0);
}
dfs(root, 0);
return 0;
}
void add(file &f, int index) {
if(index == files.size()) {
return;
}
for(int i = 0; i < f.subFiles.size(); i++){
if(strcmp(f.subFiles[i].name, files[index].name) == 0 && f.subFiles[i].isDirectory == files[index].isDirectory) {
add(f.subFiles[i], index + 1);
return;
}
}
f.subFiles.push_back(files[index]);
add(f.subFiles[f.subFiles.size() - 1], index + 1);
}
bool cmp(file f1, file f2) {
if(f1.isDirectory && !f2.isDirectory) {
return true;
} else if(!f1.isDirectory && f2.isDirectory) {
return false;
} else {
return strcmp(f1.name, f2.name) < 0;
}
}
void dfs(file &nowVisit, int level) {
if(!nowVisit.visited) {
nowVisit.visited = true;
sort(nowVisit.subFiles.begin(), nowVisit.subFiles.end(), cmp);
}
printf("%*s%s\n", level, "", nowVisit.name);
for(vector<file>::iterator it = nowVisit.subFiles.begin(); it != nowVisit.subFiles.end(); it++) {
dfs(*it, level + 2);
}
}
C++解题报告: