假设你有这个二叉搜索树(BST)。见下面的代码。属性:
节点的左子树只包含键小于节点键的节点。
节点的右子树只包含键大于节点键的节点。
左右子树也必须是二叉搜索树。
你将如何进行单元测试?您无法访问节点,也无法验证结构。您无法单独测试插入功能。
1)您可以从BST创建一个继承的测试类,并声明可以测试的额外方法。这是常见的吗?
2)以不同方式实施BST。有一个Tree类。该类可以访问子节点等,并实现基本树功能。从Tree继承BST。借助Tree提供的方法测试BST。
3)您的意见?
谢谢。
template <typename ValueType>
class BinarySearchTree
{
public:
BinarySearchTree() : m_count(0), m_root(nullptr) {}
void Insert(const ValueType& elementToInsert);
bool Remove(const ValueType& elementToRemove);
bool Contains(const ValueType& elementToFind);
bool IsEmpty() const;
size_t Count() const;
ValueType Max() const;
ValueType Min() const;
int Delimiter() const;
void PrintToFile(std::ofstream& outFile);
void BuildFromFile(std::ifstream& inFile);
~BinarySearchTree() { delete m_root; }
// TODO: copy ctr, copy assignment operator, move ctr
private:
struct Node
{
Node(const ValueType& value) : value(value), parent(nullptr), left(nullptr), right(nullptr) {}
~Node() { delete left; delete right; }
// TODO: copy ctr, copy assignment operator, move ctr
ValueType value;
Node* parent;
Node* left;
Node* right;
};
Node* m_root;
int m_count;
};
答案 0 :(得分:1)
遵循常见的STL实现,我将您的BinarySearchTree
类拆分为不同的组件:
一些仅适用于节点的二叉树类。让我们将其命名为BinaryTree
。它支持插入和删除Node *
,遍历(begin
和end
)以及有用的树操作(如rotate
来平衡树)。但它不会分配任何东西或找不到任何东西(没有ValueType
已知)。
保证log(n)
深度的特定二叉树版本。我们称之为AVLTree
(你也可以选择红黑或其他东西)。此树知道ValueType
并将实现诸如find
之类的方法以及值(包括内存管理)的插入/删除。它还将根据存储的值来处理平衡。
(最重要的是,您可以像STL那样构建类似set
或map
的内容。)
测试的好处:
BinaryTree
类将在树中使用的Node
类型中进行模板化(基于性能原因,模板化为多态virtual
方法)。因此,对于单元测试,您可以使用不同类型的BinaryTree
构建Nodes
。这些特殊类型的节点可以为您的测试维护额外的信息(例如计数器)(例如,在某些操作期间,左子项最多更改一次)。
另一方面,AVLTree
仅可根据值进行测试,例如。插入后可以找到一些值。这与您原来的BinarySearchTree
基本相同。我建议添加一些迭代完整树的测试方法(例如verify_invariants
)并检查所有不变量(例如log(n)
深度,节点的子节点父节点是节点)。这可能既昂贵又缓慢,但只应用于您的单元测试。
只是一句结束语:如果你为自己/作业写你的树 - 很好!如果这应该在“真实”世界的某个地方使用,强烈考虑使用STL容器。