c - C中的静态成员
问题描述
我试图编写一个代码来确定一棵树是否是 BST。
我从网站上搜索了解决方案以供参考。
解决方案之一如下:
我真的不明白静态指针在这个函数中的作用。
谁能给我解释一下?太感谢了!
这是代码片段。
int isBSTtree(treeNode *T)
{
static treeNode *prev=NULL;
if(T)
{
if(!isBSTtree(T->left))
{
return 0;
}
if(prev!=NULL && T->value<=prev->value)
{
return 0;
}
prev=T;
return isBST(T->right);
}
return 1;
}
解决方案
静态变量在函数调用之间保留它们的值。如果它们作为声明的一部分被初始化,如 中
static treeNode *prev=NULL;
,则初始化只发生一次。
例如,如果你有 f:
void f(int n) {
static int x = 4;
if (!n) {
printf(" : ");
return;
}
x += 2;
printf("%d ", x);
f(n - 1);
printf("(%d) ", x);
}
然后f(3)
会打印6 8 10 (10) (10) (10)
。静态变量用于将值传递给递归调用并返回值。在 BST 检查的情况下,它被用来查找左子树最右边元素的值。
但是这样做有几个问题。
f(3); putchar('\n'); f(3);
印刷
6 8 10 (10) (10) (10)
12 14 16 (16) (16) (16)
因为我们忘记在非递归调用之间重置静态变量。如果我们f(3)
同时从两个不同的线程调用,那么两个调用都会使用同一个静态变量,并且不知道数字会以什么顺序出现。
isBSTtree 背后的逻辑是进行从左到右的遍历,跟踪迄今为止看到的最大元素,如果在节点左侧看到的最大元素大于节点的值,则表明失败。因此,更好的方法是:
int isBSTaux(treeNode *T, treeNode **prev) {
if(!T) return 1;
if (!isBSTaux(T->left, prev)) return 0;
if (*prev && (*prev)->value > T->value) return 0;
*prev = T;
return isBSTaux(T->right, prev);
}
int isBSTtree(treeNode *root) {
treeNode *prev = NULL;
return isBSTaux(root, &prev);
}
对 isBSTtree 的每次调用都会获得自己的 prev 副本,每次都会重新初始化,并且不会在不同调用之间共享。
(这并不是说静态局部变量没有它们的用途;它们只是在这种特殊情况下不是正确的选择。)
推荐阅读
- ruby-on-rails - 如何将参数传递给 Rails 控制器的回调
- javascript - 未设置本地存储默认选项的页面加载 Jquery
- qt - QT 如何使用 QFileDialog 将先前用户选择的图像路径保留在内存中以便即时加载
- python - 招摇代码生成失败:缺少招摇输入或配置
- mysql - 如何在 cakephp 3.6 中将 3 个模型关联在一起
- python - 虚拟环境无法启动python——“没有这样的文件或目录”
- oracle-ebs - 使用开源技术自动化 oracle ebs
- python - 来自社交媒体的文本聚类
- c++ - TCP 缓冲区的解析器
- python - 使用python将内容从xlsx复制到记事本