#include <iostream>
#include <vector>
#include <queue>
#include <dirent.h>
#include <fstream>
using namespace std;
vector<string> GetRecords()
{
std::vector<std::string> files;
struct dirent *entry;
DIR *dir = opendir("Directory/i'm/using");
if (dir == NULL)
{
return files;
}
while ((entry = readdir(dir)) != NULL)
{
files.push_back(entry->d_name);
}
closedir(dir);
return files;
}
class node
{
private:
node *left;
node *right;
node *par;
bool isExternal;
int depth;
int position;
int num;
public:
node() : isExternal(true), depth(0), position(0), num(0) {}
node(int num) : num(num), depth(0), isExternal(true)
{
this->left = generate_left();
this->right = generate_right();
}
node *get_left() { return left; }
node *generate_left()
{
this->left = new node();
left->par = this;
left->depth = left->par->depth + 1;
return left;
}
node *get_right() { return right; }
node *generate_right()
{
this->right = new node();
right->par = this;
right->depth = right->par->depth + 1;
return right;
}
void set_num(int num)
{
this->num = num;
this->par->isExternal = false;
}
int get_num() { return this->num; }
int get_depth() { return this->depth; }
int get_position() { return this->position; }
void set_position(int pos) { this->position = pos; }
bool check_External() { return isExternal; }
};
class BinaryTree
{
private:
node root;
queue<node *> ptr_queue;
int max_depth;
int max_width;
public:
BinaryTree(int num) : root(num), max_width(0), max_depth(0)
{
ptr_queue.push(root.generate_left());
ptr_queue.push(root.generate_right());
}
~BinaryTree()
{
while (!ptr_queue.empty())
{
node *temp_ptr = ptr_queue.front();
delete temp_ptr;
ptr_queue.pop();
}
}
void add(int num)
{
node *temp_ptr = ptr_queue.front();
ptr_queue.push(temp_ptr->generate_left());
ptr_queue.push(temp_ptr->generate_right());
if (num == -1)
{
if (ptr_queue.size() == 0)
return;
ptr_queue.pop();
}
else
{
temp_ptr->set_num(num);
ptr_queue.pop();
}
return;
}
void traverse() { traverse(&root); }
void traverse(node *ptr_node)
{
if (ptr_node->get_num() == 0)
return;
if (ptr_node->check_External())
{
if (ptr_node->get_depth() > max_depth)
max_depth = ptr_node->get_depth();
ptr_node->set_position(max_width++);
return;
}
traverse(ptr_node->get_left());
ptr_node->set_position(max_width++);
traverse(ptr_node->get_right());
}
void fill_zero(int **arr)
{
// when traverse() is finished max_width gets extra +1 because of ++ operator, while max_depth doesn't. So it needs extra +1
for (int i = 0; i < max_depth + 1; ++i)
{
arr[i] = new int[max_width];
for (int j = 0; j < max_width; ++j)
{
arr[i][j] = 0;
}
}
}
void fill_array(int **arr) { fill_array(&root, arr); }
void fill_array(node *ptr_node, int **arr)
{
if (ptr_node->get_num() == 0)
return;
if (ptr_node->check_External())
{
arr[ptr_node->get_depth()][ptr_node->get_position()] = ptr_node->get_num();
return;
}
fill_array(ptr_node->get_left(), arr);
arr[ptr_node->get_depth()][ptr_node->get_position()] = ptr_node->get_num();
fill_array(ptr_node->get_right(), arr);
}
void print(int **arr)
{
for (int i = 0; i < max_depth + 1; ++i)
{
for (int j = 0; j < max_width; ++j)
cout << arr[i][j] << "\t";
cout << endl;
}
}
node get_root() { return root; }
int get_depth() { return max_depth; }
int get_width() { return max_width; }
};
void Macro(string path_file, int *check)
{
queue<int> inputs;
ifstream input(path_file);
int num = 0;
int length = 0;
while (input >> num)
inputs.push(num);
length = inputs.size();
// for (int i = 0; i < length; ++i)
// {
// cout << inputs.front() << endl;
// inputs.pop();
// }
BinaryTree tree(inputs.front());
inputs.pop();
for (int i = 1; i < length; ++i)
{
tree.add(inputs.front());
inputs.pop();
}
tree.traverse();
int **arr = new int *[tree.get_depth()];
tree.fill_zero(arr);
tree.fill_array(arr);
cout << (*check)++ << endl;
tree.print(arr);
cout << endl;
input.close();
// cout << file << endl;
}
int main()
{
string path = "Directory/i'm/using";
vector<string> files;
int *check = new int;
*check = 0;
files = GetRecords();
// erase first three elements
for (int i = 0; i < 3; ++i)
files.erase(files.begin());
for (auto file : files)
{
string path_file = path + file;
cout << path_file << endl;
Macro(path_file, check);
}
cout << "Ended" << endl;
return 0;
// test.print();
}
这是我的整个代码。
该程序的目的是从目录中的文件中获取输入并生成二叉树。
给定条件的输入是从 1 到 999 的整数。
如果程序读取 -1,则它会跳过节点的该位置并移动到它旁边。
这是一些例子
输入
933 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
输出
933
输入
60 889 331 230 115 -1 229 652 -1 276 282
输出
0 0 0 0 0 0 60 0 0
0 0 889 0 0 0 0 331 0
0 230 0 0 115 0 0 0 229
652 0 0 276 0 282 0 0 0
输入
231 580 -1 600 449 -1 -1 408 109 -1 451 -1 -1
输出
0 0 0 0 0 0 231
0 0 0 580 0 0 0
0 600 0 0 449 0 0
408 0 109 0 0 451 0
我希望你现在得到它。
因此,为了实现这一点,我在测量数组的整个长度和宽度的同时通过BinaryTree.traverse()
用零填充它来制作程序BinaryTree.fill_zero(),并通过 改变我需要的位置BinaryTree.fill_array()。
从逻辑上看,它似乎工作得很好,除了它不适用于编译的 exe 文件。
程序在没有退出循环的情况下停止,所以我猜是运行时错误。
但我不知道是什么原因造成的,因为调试器打印出来没有任何问题。
我使用的程序是 VSCode,编译器是 g++。
希望有人帮助我找出问题所在以及为什么在发布版本失败时调试有效。
https://ibb.co/4pVKMJH(调试器结果)
https://ibb.co/cDd1gvL(发布结果)
感谢您阅读。祝你今天过得愉快!