二叉搜索树

时间:2009-05-18 04:14:42

标签: c++ recursion binary-tree implementation

我对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提前致谢。

9 个答案:

答案 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:当然,这假设你没有完成家庭作业。