帮助使用 BST 插入函数
嘿,我正在尝试编写 BST,但我遇到了很多错误,而且我非常不知所措,不知道该怎么做。你们能看一下并指出任何不对的地方吗?老师在解释任何事情上根本没有多大用处。
.h 文件中的标头
class Tree
{
public:
bool insert(int k, string s);
private:
struct Node
{
int key;
string data;
Node *left;
Node *right;
};
Node* root;
bool insert(Node *& root, int k, string s);
};
.cpp 文件
bool Tree::insert(int k, string s)
{
return insert(root, k, s);
}
bool Tree::insert (Node *& root, int k, string s)
{
if (root == NULL){
root = new Node;
root->key = k;
root->data = s;
root->left = NULL;
root->right = NULL;
}
else if (root == k)
return false;
else if (root->key < k)
insert (root ->left, k);
else
insert (root -> right, k);
}
Hey so I am attempting to write a BST but I am having a lot of errors and I am pretty overwhelmed and lost on what to do. Can you guys take a look and point out anything that is off. The teacher wasn't very useful at all at explaining anything.
header in the .h file
class Tree
{
public:
bool insert(int k, string s);
private:
struct Node
{
int key;
string data;
Node *left;
Node *right;
};
Node* root;
bool insert(Node *& root, int k, string s);
};
the .cpp file
bool Tree::insert(int k, string s)
{
return insert(root, k, s);
}
bool Tree::insert (Node *& root, int k, string s)
{
if (root == NULL){
root = new Node;
root->key = k;
root->data = s;
root->left = NULL;
root->right = NULL;
}
else if (root == k)
return false;
else if (root->key < k)
insert (root ->left, k);
else
insert (root -> right, k);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看来您有很多未经测试的代码。您必须一次让一项功能发挥作用。
此外,我已经看到至少一个重复工作的例子。
preOrder
和postOrder
方法应该是同一算法的轻微变体,但一个是基于循环的,另一个是通过函数递归工作的。将这些源文件放在一边,创建一个新项目,然后一次复制粘贴一个功能。在继续下一个功能之前进行彻底测试。如果您遇到现有代码中可能已经隐藏的功能,请不要从旧代码中复制粘贴,而是利用现有的经过测试的代码。
编辑
这看起来应该可行。如果您需要的话,这里有一些风格上的批评:v)。
Node
结构应该有自己的构造函数。始终提供构造函数来帮助保证任何内容都不会处于无效状态。Tree
时,需要将root
设置为NULL
。left
和right
似乎永远不会接收非NULL
值。就我个人而言,我更喜欢这里使用指针到指针,但有些人可能会同意您的实现。It appears that you have a lot of untested code. You will have to get the features working one at a time.
Furthermore, I see at least one instance of duplicated effort already. The
preOrder
andpostOrder
methods should be slight variations of the same algorithm, yet one is loop-based and the other works by function recursion.Set these source files aside, create a new project, and copy-paste over one feature at a time. Test thoroughly before moving on to the next feature. If you reach a feature that might already be latent in the existing code, don't copy-paste from the old code, but instead leverage the existing tested code.
Edit
That looks like it should work. Here are a couple stylistic criticisms, if you want them :v) .
Node
structure should have its own constructor. Always provide a constructor to help guarantee that nothing can be in an invalid state.root
toNULL
when you create a newTree
.root
argument is not good style. At first glance, it looks likeleft
andright
never receive non-NULL
values. Personally I favor a pointer-to-pointer here, but some might agree with your implementation instead.一方面,代码末尾缺少括号。
For one thing, you have a missing bracket at the end of your code.
如果不考虑实际的实现,就会发现有很多与接口相关的陷阱。以下是其中一些:
Tree::findKey
方法接受字符串作为非常量引用,为什么?Tree::insert
按值接受字符串,这涉及到不必要的复制,有什么用呢?preOrder
和levelOrder
需要指向函数的指针。如果我想调用类方法或传递附加参数怎么办?我想说你最好在那里使用谓词,或者boost::function
。const
修饰符)。例如,isEmpty()
方法。makeCopy
方法不是异常安全。size_t
。希望有帮助。
Not looking at actual implementation, there are lots of interface-related pitfalls. Here are some of them:
Tree::findKey
method accepts string as non-constant reference, why?Tree::insert
accepts string by value, which involves unnecessary copying, what for?preOrder
andlevelOrder
expects pointer to a function. What if I want to invoke a class method, or pass additional arguments? I'd say you better off with predicate there, orboost::function
.const
modifier). For example,isEmpty ()
method.makeCopy
method is not exception-safe.size_t
.Hope it helps.
编写你的第一个 BST 可能很困难......根据 Potatoswatter 的建议,我首先要确保你有一个非常可靠的插入函数,然后再去其他地方。因此,您可以为 BST 创建类,包括函数的声明,但在它们的定义中,只需将它们设为空函数,例如:
在头文件中:
在 .cpp 文件中:
现在使用这种方法,您可以测试确保您正确地将节点插入到树中而不会崩溃等,完成后,您可以测试是否可以找到已插入的节点。之后,您可以完成其余函数的定义,这些函数负责删除、迭代等。但是,通过将每个阶段不需要的函数的定义留空,您可以正确构建解决方案,而无需一堆编译器错误和其他不相关的项目使您无法为手头的任务构建实际的界面。换句话说,您无法从一开始就没有正确插入节点的树中找到或删除节点而不会出现问题,因此当您第一步还没走对。此外,您可能会发现,当您实现后续步骤(例如查找节点)时,仍然存在插入问题...如果您只实现了插入和查找节点的完整定义,那么这些是您唯一的两个函数我们将不得不担心修复问题。
因此,将其分解为基本部分(插入、查找、删除,然后是其他所有部分),然后您就可以完成工作了:-)
Writing your first BST can be hard ... Taking the advice of Potatoswatter, I would first start with making sure you have a VERY SOLID insert function working before going anywhere else. So you can create the class for your BST, including the declarations for the functions, but in their definitions, just make them empty functions, for example:
In your header file:
In your .cpp file:
Now with this approach, you can test to make sure you are properly inserting nodes into your tree without crashing, etc., and once that is done, you can test to see if you can find the nodes you've inserted. After that, you can complete the definitions for the rest of the functions that take care of deletion, iteration, etc. But by leaving the definitions empty for functions you don't need for each stage, you can properly build-up your solution without having a mess of compiler errors and other non-related items keeping you back from building the actual interface for the task-at-hand. In other words you can't find or delete a node from a tree that hasn't has a node properly inserted in it in the first place without issues, so you don't want to go around chasing your tail on those steps when you're not getting the first step right. Also you may find when you implement a later step, like finding a node, that there are still insertion problems ... if you've only implemented the full definitions for insertion and finding a node, then those are the only two functions you're going to have to worry about fixing.
So break it down into its basic parts (inserting, finding, deleting, and then everything else), and you'll get the job done :-)