下面的信息在文件中给出,您必须创建一个函数来重建C ++中的二叉树。
node leftchild rtchild
1 2 4
2 $ 5
5 6 7
6 $ $
7 $ $
4 $ 8
8 $ $
$ - 清空
任何人都可以建议重建二叉树...... ???
我做过: -
void rebuild_btree(node *tree)
{
ifstream fin("data.txt");
string a;
if (!fin)
cout << "\nError in opening file.." << endl;
else
cout << "\nFile is successfully opened.." << endl;
while (!fin.eof())
{
fin >> a;
tree = insert(tree, a);
}
fin.close();
}
node* insert(node *root, string &dat)
{
if(dat != "$")
{
if(root == NULL)
{
root = new node;
strcpy(root->data, dat);
root->left = root->right = NULL;
}
else if (root->left == NULL)
root->left = insert(root->left, dat);
else
root->right = insert(root->right, dat);
return root;
}
return root;
}
这不起作用..我认为有一些错误,我没有得到......如果你能抓住那么建议我....
答案 0 :(得分:1)
不要这样做:(这是错的)。在您尝试读取EOF之前,EOF标志不会设置,而最后一次成功读取会读取(但不会超过)EOF。所以你再次进入循环所需的时间。
while (!fin.eof())
{
fin >> a;
tree = insert(tree, a);
}
它应该这样写:这是有效的,因为运算符&gt;&gt;返回对流的引用。当一个流在布尔上下文中使用时(比如一段时间的条件),它被转换为一个可转换为bool的对象,如果没有设置错误标志,则该值为true。因此,如果读取成功,则输入循环,否则不是。
while (fin >> a)
{
tree = insert(tree, a);
}
这显然不能编译,因为String不是标准类型 类型是字符串(小写s),它位于std :: namespace中。所以请使用std :: string。
如果这是您定义的类型,那么我们需要知道了解这条线是如何工作的:
fin >> a;
如果传递的String为“$”,则函数insert()不返回值。 C ++函数必须始终返回一个值(除非返回类型为void)。否则它是'未定义的行为'。
Insert()显然无法正常工作。
您应该考虑二叉树的不同输入格式。由于需要两次通过,因此特别难以解析和重新构建。您需要第一遍才能读取所有节点。然后你需要第二遍来重建树结构。
这显然是功课!
一次读取一行并正确解析该行:
std::string line;
std::getline(fin, line);
一次解析整行,并构建一个对象来表示节点。不幸的是,您可以构建真实节点,因为此输入格式需要两次传递。
struct TmpNode { int value; std::string left; std::string right; } tmp;
std::istringstream data(line);
data >> tmp.value >> tmp.left >> tmp.right;
因为你需要一个两阶段构建1)阅读2)构建树。您需要存储TmpNode
个对象,直到您拥有它们并构建树。
std::map<int,TmpNode> nodes;
nodes[boost::lexical_cast<int>(tmp.value)] = tmp;
将所有TmpNode存储在地图中后。您现在可以轻松地遍历地图并构建树。
node* buildTree(std::string const& nodeID)
{
if (nodeID == "$") { return NULL;}
TmpNode& n = nodes[boost::lexical_cast<int>(nodeID)];
return new node(nodeID, buildTree(n.left), buildTree(n.right));
}
答案 1 :(得分:0)
第一印象:您正在混合使用C和C ++习语:您声明char a[20]
,将其作为insert()
传递给string
(使用隐式转换),然后使用{进行比较{1}}(它甚至不应该工作,因为它需要strcmp()
,而不是const char*
。相反,您应该从一开始就将其声明为string
,将其作为string
传递以避免不必要的复制,并使用const string&
进行比较。
通过递归调用==
,您似乎也一遍又一遍地向树中插入相同的值。您应该一次从文件中读取3个值的元组,然后在正确的位置将其作为子树插入一次。
顺便说一句“不工作”是一个非常模糊的描述 - 请详细说明执行时会发生什么。你得到错误的结果,崩溃,无限循环,......?