只是一个简单的BST来按顺序打印数字。无法弄清楚我做错了什么。
#include <iostream>
using namespace std;
class bst {
private:
bst* root;
bst* left;
bst* right;
int value;
public:
bst(const int& numb) : root(NULL), left(NULL), right(NULL) {
value = numb;
}
void insert(const int& numb) {
if (numb < value) {
if (left == NULL) {
left = new bst(numb);
left->root = left;
} else {
left->insert(numb);
}
} else if (numb > value) {
if (right == NULL) {
right = new bst(numb);
right->root = right;
} else {
left->insert(numb);
}
} else if (numb == value) {
cout << "duplicated value" << endl;
}
}
void inorder() {
if (left == NULL) cout << value << endl;
else left->inorder();
right->inorder();
}
};
int main() {
bst tree(5);
tree.insert(7);
tree.insert(1);
tree.insert(3);
tree.insert(2);
tree.insert(9);
tree.insert(10);
return 0;
}
答案 0 :(得分:3)
第29行应为:
right->insert(numb);
目前的内容为:
left->insert(numb);
我强烈建议您查看gdb以解决此类问题。
答案 1 :(得分:1)
inorder()
应该是:
if (left != NULL) left->inorder();
cout << value << endl;
if (right != NULL) right->inorder();
我认为其余的都是正确的。
答案 2 :(得分:1)
整个逻辑错误。
崩溃就在这里:
if (right == NULL) {
right = new bst(numb);
right->root = right;
} else {
left->insert(numb);
}
其他情况下使用权利,而不是留下。
答案 3 :(得分:1)
至少在我看来,你的基本设计是有缺陷的。虽然我意识到许多教科书(等等)将树描述为递归结构,其中每个节点都有两个子树,但我从来没有找到一种设计代码的好方法。
至少根据我的经验,在实际代码中,你(更好)将树中节点的概念与整个树的概念分开。外面的世界只能看到树; node
应隐藏在树内,对外界不可见。
class bst {
class node {
int value;
node *left;
node *right;
// ...
};
// ...
node *root;
};
然后我将insert
拆分为两部分:一个公共函数,它接受一个值,然后转发到以root
为起点的第二个函数。第二个实际遍历三个并插入新项目:
// public interface:
void insert(int v) {
insert(new node(v), root);
}
// private workhorse:
void insert(node *n, node *&pos) {
if (pos == NULL)
pos = n;
else if (n->value < pos->value)
insert(n,pos->left);
else if (n->value > pos->value)
insert(n,pos->right);
else
// duplicate value.
}
同样,inorder
被分为公共和私人对,公众只提供一个界面,而私人一方完成所有实际工作:
// public interface:
void inorder() {
inorder(root);
}
// private worker
void inorder(node *n) {
if (n==NULL)
return;
inorder(n->left);
std::cout << n->value << endl;
inorder(n->right);
}
对于它的价值:是的,我已经测试了这段代码,它至少可以用你main
中使用的输入。但它确实有缺点。例如,insert
和inorder
递归地遍历树,因此一个大的,严重不平衡的树可能导致堆栈溢出。迭代地插入是相当容易的,但是对于实际使用,你通常只需切换到某种平衡树。