我会保持简短。当我运行代码时,我输入第一个字符(例如:'k'),一切都很好。第二次我输入一个字符(例如:'j')我得到一个错误,编译器说它在线上(有一个注释)。请帮忙。谢谢。
代码:
struct nodeType{
char letter;
nodeType*leftNode;
nodeType*rightNode;
};
void putInNode(nodeType*n,char c){
if ((char)(n->letter) >='a' && (char)(n->letter) <='z')/* ERROR IS HERE*/
{
if(n->letter < c)
putInNode(n->leftNode, c);
else
putInNode(n->rightNode, c);
}
n->letter=c;
}
int main(){
nodeType*a=new nodeType();
char c;
do {
cin >> c;
if(c=='.')
break;
putInNode(a,c);
} while (true);
cout << a->letter << endl;
}
答案 0 :(得分:3)
如果这样做的目的是构建一个只包含来自输入流的字母的树,当你到达一个句点时停止,并跳过不在{'a'...'z'}
中的任何内容,我认为这就是你所追求的:
#include <iostream>
struct nodeType
{
nodeType(char ch = 0)
: letter(ch), leftNode(), rightNode()
{}
char letter;
nodeType* leftNode;
nodeType* rightNode;
};
void putInNode(nodeType*& n,char c)
{
if (!n)
{
n = new nodeType(c);
}
else if (n->letter >='a' && n->letter <='z')
{
if(c < n->letter)
putInNode(n->leftNode, c);
else
putInNode(n->rightNode, c);
}
}
int main()
{
nodeType* a = NULL;
char c;
while ((std::cin >> c) && c != '.')
putInNode(a,c);
if (a)
std::cout << a->letter << '\n';
}
注意:这会将重复按下右子行。如果不是这样,请更改以下内容:
if(c < n->letter))
putInNode(n->leftNode, c);
改为:
if(c <= n->letter)) // <== note less-or-equal
putInNode(n->leftNode, c);
我将生成的动态树的清理留给您。应该注意的是,在写入时(先前和现在),第一个节点将始终是树的根(我假设有一天你计划通过轮班进行平衡,比如你在这条路上走得更远)。 / p>
答案 1 :(得分:2)
非常确定问题是您实际上没有从根节点分配任何节点appart。因此,当您输入第二个字母时,第一个字母已经在父节点中设置了字母,并且当它尝试取消引用树中的左侧节点时,它会失败(b / c表示未分配的内存)。
答案 2 :(得分:1)
问题是您只为单个节点分配空间而不是初始化变量。
首次通过do
循环,我假设a->letter = 0
,因此在输入putInNode
函数时,该字母将分配给k
。下一次循环n->letter
将k
介于a
和z
之间,k < j
将为真putInNode(n->leftNode, c);
n->leftNode
尚未初始化,但是当您尝试将其视为n->letter
时,您会遇到段错误。
要解决此问题(假设您不希望此函数创建新节点),请为您的struct创建构造函数,然后检查null。
struct nodeType{
nodeType()
{
letter = 0;
leftNode = nullptr;
rightNode = nullptr;
}
char letter;
nodeType*leftNode;
nodeType*rightNode;
};
然后在putInNode
void putInNode(nodeType*n,char c){
if(n == nullptr) {
return;
}
if ((char)(n->letter) >='a' && (char)(n->letter) <='z') {
.
.
.