我想将二叉树保存到txt文件中。这就是我所拥有的
qt.h
#ifndef QT_H_INCLUDED
#define QT_H_INCLUDED
#include<iostream>
using namespace std;
template<typename T>
class Node{
T data;
Node<T> *left;
Node<T> *right;
public:
Node(T d) : data(d), left(nullptr), right(nullptr){}
void print(){
cout << data << endl;}
T getData()const {
return data;
}
void setData(const T &value){
data = value;
}
template<typename X> friend class Tree;
template<T> friend ostream& operator<<(ostream &os, Node &n);
};
template<typename T>
ostream& operator<<(ostream &os, Node<T> &n){
os << n->data;
return os;
}
#endif // QT_H_INCLUDED
然后是tree.h
#ifndef TREE_H_INCLUDED
#define TREE_H_INCLUDED
#include "qt.h"
#include <fstream>
#include <iostream>
namespace std;
template<typename T>
class Tree{
Node<T> *root;
void insertIntoTree(T &d, Node<T> *&r);
void printTree(Node<T> *r);
void deleteTree(Node<T> *&r);
Node<T>* findInTree(T &d, Node<T> *r, Node<T> *&parent);
void deleteLeaf(Node<T> *p, Node<T> *q);
void deleteInBranch(Node<T> *p, Node<T> *g);
void zapisDoSouboru(Node<T> *r);
public:
Tree() : root(nullptr){}
~Tree(){
clean();
}
bool find(T d){
Node<T> *dummy=nullptr;
return findInTree(d, root, dummy);
};
void clean(){
deleteTree(root);}
void insert(T d){
insertIntoTree(d, root);}
void print(){
printTree(root);
}
bool deleteNode(T d);
void zapis(){
zapisDoSouboru(root);
}
}
template<typename T>
void Tree<T>::zapisDoSouboru(Node<T> *r){
fstream f;
f.open("mytext.txt", ios_base::app);
if(r){
f << r;
}
f.close();
zapisDoSouboru(r->left);
zapisDoSouboru(r->right);
}
想法是重载运算符&lt;&lt;对于Node,然后在zapisDoSouboru中使用递归并将其保存为Node by Node。不幸的是它不起作用。 有谁知道,问题在哪里? 谢谢你的帮助
EDIT 在
class Tree{
void zapis(ostream& f, Node<T> *r);
public:
void zapisDoSouboru(){
fstream f;
f.open("mytext.txt", ios_base::app);
zapis(f, root);
f.close();
}
}
template<typename T>
void Tree<T>::zapis(ostream& f,Node<T> *r){
if(r){
zapis(f, r->left);
f << r;
zapis(f, r->right);
}
}
我改变了整个递归,但现在看起来它有效,但它不会在文件中写任何东西。不是f的引用吗?该文件打开和关闭,zapis()遍历所有节点。
答案 0 :(得分:0)
在函数zapisDoSouboru中,您需要检查子节点是否为nullptr,否则它将在到达叶节点时发生段错误。
以下是修改后的版本: 模板
void Tree<T>::zapisDoSouboru(Node<T> *r){
fstream f;
f.open("mytext.txt", ios_base::app);
if(r){
f << r;
}
f.close();
if(nullptr != r->left) {
zapisDoSouboru(r->left);
}
if(nullptr != r->right) {
zapisDoSouboru(r->right);
}
}
您为节点定义的运算符也未被编译器选中。 这是运营商的代码:
template<typename T>
ostream& operator<<(ostream &os, Node<T> &n){
os << n->data;
return os;
}
变量n
它是通过引用传递的,并且您正在使用需要指针的->
来访问它。代码编译的原因是因为当您调用f << r
时实际上使用Node<T>*
调用运算符,因此编译器不使用期望Node<T>&
的模板函数。这意味着模板函数永远不会被实例化。
我认为在这种情况下不需要让操作员过载。您只需致电r->getData()
在查看代码时我注意到的一般事项:
如果您需要任何澄清,请告诉我