我已经看到很多搜索算法要在二进制排序树中搜索,但它们都使用相同的方式:递归。我知道与循环相比,递归是昂贵的,因为每次调用搜索函数时,都会为该方法创建一个新的堆栈帧,如果二进制搜索树太大,最终将使用大量内存。
为什么我们不能像这样搜索二进制搜索树:
while (root!=NULL)
{
if (root->data==data)
return 0;
else if (data > root->data)
root=root->right;
else
root=root->left;
}
我认为这种方式比递归方式更快更有效,如果我错了,请纠正我!
答案 0 :(得分:5)
可能你的方式 - 这是在 C 中编码的常用方法 - 可能会更快,但你应该进行基准测试,因为一些C编译器(例如,用{调用时最近GCC {1}} ...)能够将大多数tail calls优化为跳转(并在寄存器中传递值)。尾调用优化意味着被调用者重用call stack帧(因此调用栈保持有界)。请参阅this question。
FWIW,在OCaml(或Scheme,或Haskell,或大多数Common Lisp实现)中,您将编写尾递归调用,并且您知道编译器正在优化它作为跳转。
递归并不总是比循环慢(特别是对于尾调用)。这是编译器优化的问题。
了解continuations和continuation passing style。如果您只知道C,请学习一些函数式语言(Ocaml,Haskell或带SICP的Scheme ...),其中经常使用尾部调用。阅读Scheme中的call/cc。
答案 1 :(得分:0)
是的,这是正常的做法。
答案 2 :(得分:0)
从理论上讲,您的解决方案和递归解决方案都具有相同的Big Oh complexity。理论上它们都是O(log n)。如果你想要以秒为单位测量性能,你需要实用,编写两种方法的代码(迭代,递归),运行它们并测量运行时间。