帮助使用BST插入函数

Help with a BST insert function

本文关键字:插入 函数 BST 帮助      更新时间:2023-10-16

嘿,所以我试图写一个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);
}

看起来您有很多未测试的代码。你必须让这些特性一次工作一个。

此外,我已经看到了至少一个重复工作的实例。preOrderpostOrder方法应该是同一算法的细微变化,但一个是基于循环的,另一个是通过函数递归工作的。

将这些源文件放在一边,创建一个新项目,并在上复制粘贴一个特性。在进行下一个功能之前进行彻底的测试。如果您发现了一个可能已经隐藏在现有代码中的特性,不要从旧代码中复制粘贴,而是利用现有的测试代码。

<标题>编辑

看起来应该可以工作。这里有一些文体上的批评,如果你想要的话:

  1. Node结构应该有自己的构造函数。总是提供一个构造函数来帮助保证没有任何东西处于无效状态。
  2. 同样,当你创建一个新的Tree时,需要将root设置为NULL
  3. 改变root参数的值不是好的风格。乍一看,leftright似乎从不接收非NULL的值。我个人更喜欢指针对指针,但有些人可能会同意你的实现。

首先,代码末尾缺少一个括号。

不考虑实际实现,有许多与接口相关的陷阱。以下是其中一些:

  • 头文件中缺少include保护。
  • 在被包含的头文件的全局范围内说"使用命名空间std"是允许的,但这是非常糟糕的风格。
  • Tree::findKey方法接受字符串作为非常量引用,为什么?
  • Tree::insert按值接受字符串,这涉及不必要的复制,为什么?
  • preOrderlevelOrder期望指针指向函数。如果我想调用一个类方法,或者传递额外的参数,该怎么办?我想说你最好在那里使用谓词,或者boost::function
  • 不修改状态(类中的数据)的方法不作为常量(const修饰符)销售。例如:isEmpty ()方法。
  • makeCopy方法不是异常安全的。
  • 使用有符号整数代替size_t

希望能有所帮助。

写你的第一个BST可能很难…采纳Potatoswatter的建议,我首先要确保你有一个非常可靠的插入函数在去其他地方之前工作。因此,您可以为BST创建类,包括函数的声明,但在其定义中,仅将其设置为空函数,例如:

头文件:

class BST
{
    public:
        BST();
        bool insert(int k, const string& s);
        bool findKey(int k, string& s);
        int maxKey();
        /* ... the rest of your class ...*/
};

在你的。cpp文件中:

#include "BST.h"
BST::BST()
{
    /*initialize anything required for your insert function to work*/
}
//pass in a const reference for your string argument, 
//or else you could end up doing a lot
//of extra processing creating a new copy of your string on the stack for
//each insertion call
bool BST::insert(int k, const string& s)
{
    /* write your insertion algorithm implementation */
}
//make the rest of your function definitions that don't
//apply to insertion empty so you can compile and test your insertion algorithm
//without adding more cruft
bool BST::findKey(int k, string& s) {}
int BST::maxKey() {}
/* continue process for the rest of the class */

现在,使用这种方法,您可以进行测试,以确保正确地将节点插入到树中而不会崩溃等,一旦完成,您可以进行测试,看看是否可以找到已插入的节点。之后,您可以完成其他函数的定义,这些函数负责删除、迭代等。但是,通过将每个阶段不需要的函数的定义保留为空,您可以正确地构建解决方案,而不会出现编译器错误和其他不相关项的混乱,使您无法为手头的任务构建实际接口。换句话说,如果一开始就没有正确插入节点,那么您就无法从树中找到或删除节点,因此,如果第一步没有做对,您就不希望在这些步骤中到处追着尾巴走。此外,当您实现后面的步骤(如查找节点)时,您可能会发现仍然存在插入问题……如果您只实现了插入和查找节点的完整定义,那么您只需要担心修复这两个函数。

所以把它分解成基本的部分(插入,查找,删除,然后其他的一切),你会完成工作的:-)