由于我已经使用一年多了,所以我正尝试重新使用C ++。
我正在以下网站上尝试作业:www.testdome.com
当前,我的任务是在排序的二叉树中找到一个值。我应该使用的Node
类看起来像这样:
class Node
{
public:
Node(int value, Node* left, Node* right)
{
this->value = value;
this->left = left;
this->right = right;
}
int getValue() const
{
return value;
}
Node* getLeft() const
{
return left;
}
Node* getRight() const
{
return right;
}
private:
int value;
Node* left;
Node* right;
};
我完成了任务,并提出了两个实现。我在上一次测试中都遇到了一个错误:超过了时间限制
我想知道如何更快地编写它。我的实现:
std::stack
处理所有节点我将嵌套节点保存在std::stack
中,并遍历它们直到获得一个值。我认为这应该是正确的解决方案,避免真正的递归。
bool containsStdStack(const Node& root, int value)
{
std::stack<const Node*> queue;
queue.push(&root);
while(!queue.empty()) {
const Node*const tmp = queue.top();
queue.pop();
if(tmp->getValue() == value) {
return true;
}
// Do not push nulls to avoid extra iterations
if(const Node* left = tmp->getLeft()) {
queue.push(left);
}
if(const Node* right = tmp->getRight()) {
queue.push(right);
}
}
return false;
}
由于以上方法均未通过性能测试,因此我尝试了这种幼稚的方法-简单的解决方案往往比预期的要快。
bool containsRecursive(const Node&root, int value) {
return containsRecursive(&root, value);
}
bool containsRecursive(const Node*root, int value) {
return root!=nullptr &&(
root->getValue() == value
|| containsRecursive(root->getLeft(), value)
|| containsRecursive(root->getRight(), value)
);
}
但是它仍然没有通过性能测试。
我错过了重要的事情吗?也许性能测试真的很苛刻?是否可以在没有黑客的情况下进一步优化?
答案 0 :(得分:5)
您的递归方法是一个不错的开始,但是考虑到树已排序,它可以访问(最多)每个节点。
在每个阶段,只需根据当前节点小于还是大于子节点,在左边子树 或在右边子树 您要查找的节点。
所以:
这将您的算法从线性更改为对数,因为每次好的树搜索都应如此。 :)
这就是std::map
使用小于比较器进行工作的原因。您也可以从中得出相等性(对于x==y => !(x < y) && !(y < x)
持有的那些值)。
答案 1 :(得分:1)
我假设树已排序。话虽如此,我只是在检查是否需要在树的左侧或右侧搜索值。搜索复杂度是对数的。
bool containsRecursive(const Node&root, int value) {
return containsRecursive(&root, value);
}
bool containsRecursive(const Node*root, int value) {
// root is null
if (root == NULL) return false;
// value is present at root
if(root->getValue()== value) return true;
// value is greater than root's value //this saves lot of time
if (root->getValue() < value)
return containsRecursive(root->getRight(), value);
// value is smaller than root's key
return containsRecursive(root->getLeft(), value);
}