我对C ++中的二进制搜索树实现有疑问。 这是下面的问题
实现一个存储整数的简单(非模板化)BST。提供以下操作:Insert,Remove,inOrder遍历,preOrder遍历,postOrder遍历。
使用递归例程处理树。
处理节点只需要打印出节点的内容,在这种情况下是存储在节点中的整数。
数据应来自测试文件。主程序应打开数据文件并插入树中并演示其他树操作。
本练习的目的是证明您了解BST。没有必要过度使用它并投入未被要求的操作。
到目前为止我只创建了Header文件。有谁可以看一看,并告知我是否朝着正确的方向前进?
using namespace std;
#ifndef BSTNODE_H
#define BSTNODE_H
class BSTNode
{
private:
//Defines the 'node' structure
struct tree_node
{
tree_node *left; // left subtree has smaller elements
tree_node *right; // right subtree has larger elements
int m_data;
};
//root * r;
public:
//The Constructor
BSTNode();
//The Destructor
~BSTNode();
//Inserts a value into a BST, public function
void insert(const m_data & d);
//Removes a value from a BST, public function
void remove(const m_data & d);
//isEmpty function, public function
bool isEmpty();
BSTNode getData();
void inOrder(const m_data & d);
void preOrder(const m_data & d);
void postOrder(const m_data & d);
};
#endif
接下来我必须创建BSTNode.cpp文件。感谢您的回复,请发送邮件至jediknight80n@hotmail.com提前致谢。
答案 0 :(得分:3)
您似乎忘记了typedef
您在各种方法中使用的m_data
类型,我不明白为什么您需要单独的tree_node
结构(而不是比使用类本身?)以及为什么getData
应该返回BSTNode
而不是int
。
答案 1 :(得分:3)
//Inserts a value into a BST, public function
void insert(const m_data & d);
//Removes a value from a BST, public function
void remove(const m_data & d);
//isEmpty function, public function
bool isEmpty();
BSTNode getData();
void inOrder(const m_data & d);
void preOrder(const m_data & d);
void postOrder(const m_data & d);
m_data是一个成员,而不是一个类型。你应该在这里使用int。此外,由于您的节点是tree_node,外部类可能应该整体表示树(即BSTree而不是BSTNode)。
也'使用命名空间std;'在标题中是邪恶的,因为它强制它包含任何包含标题而无法选择退出的内容。如果您打算使用它,我建议将它保存到.cpp文件中。
答案 2 :(得分:2)
微不足道的事情:
tree_node *left; // left subtree has smaller elements
通常,左子树也包含相等的元素。
答案 3 :(得分:1)
这是关于BST的经典问题 - 任何关于数据结构的好书都能为您提供完整的代码。以下页面包含C ++ http://cslibrary.stanford.edu/110/BinaryTrees.html的代码示例。
遍历函数不应该是BST类本身的一部分,事实上BSTNode应该公开左/右节点指针 - 并且调用应用程序应该以特定方式调用它。或者使用回调函数并在类中提供遍历代码,这样就会更清晰。
答案 4 :(得分:1)
一些事情 - 正如其他人所指出的那样,你将不得不使用
void insert(const int & d);
//Removes a value from a BST, public function
void remove(const int & d);
//isEmpty function, public function
bool isEmpty();
BSTNode getData();
void inOrder(const int & d);
void preOrder(const int & d);
void postOrder(const int & d);
其他的是你已经注释掉了你的根节点。虽然您定义错误,但您必须在类中包含根节点。正确的定义是
tree_node *root;
另外,如前所述,删除
使用namespace std;
从头文件中将其放入您的实现文件中。
这就是我现在所能看到的一切。
答案 5 :(得分:1)
另一个问题是指定的类声明了嵌套类型和方法,但没有成员数据。
您可以使用迭代器声明遍历功能:例如preorder方法返回一个interator,你可以取消引用一个节点,或者增加指向预订序列中的下一个节点。
或者,您可以使用回调声明遍历功能:即调用者将回调实例传递给preorder方法,preorder方法遍历树并为每个节点调用回调方法:回调方法将采用一个节点(或者,更具体地说,节点数据)作为一个参数,并且可能会返回一个布尔值,它会让回调特征化它想要遍历的遍历。
答案 6 :(得分:1)
我也会添加搜索方法。
bool search(int whatIlookfor);
甚至更好
tree_node* search(int whatIlookfor);
另外,请将tree_node *root
放在安全的地方。
答案 7 :(得分:1)
在你的例子中使用结构类型的左右指针会限制灵活性 - 假设我接受你的BST并遍历到root的左子节点,然后想要在这个新子树上调用操作。我不能,因为指针是结构类型。我宁愿建议使用BSTNode类型的两个指针。
BSTNode *left;
BSTNode *right;
这也可以解决你的根问题(不需要显式的根指针),因为用于在main中引用你的对象的指针,无论如何都将指向root。
当遍历函数基本上遍历整个树并打印所有数据项时,遍历函数不应该需要任何参数。数据项可以传递给另一个搜索成员函数,用于搜索TrueStar已经指出的位置。
我还建议使用一些私有成员函数来降低公共成员函数的复杂性(DeleteNodeCaseB(int data)
会一次又一次地调用DeleteNodeCaseA(int data)
) -
BSTNode * setleft(int data);
BSTNode * setright(int data);
void DeleteNodeCaseA(int data)
/ *左右儿童中的任何一个或两个都不存在* /
void DeleteNodeCaseB(int data)
/ *包含左右孩子* /
答案 8 :(得分:1)
由于您使用的是C ++,您可能需要考虑使用一些标准库而不是尝试自己实现它? STL库带有一个红黑树,可能更适合您的应用程序。二叉树可以变为lop-sided或退化为链接列表。
PS:当然,这假设你没有完成家庭作业。