Статические переменные сохраняют свои значения между вызовами функций.
Если они инициализированы как часть декларации, как в
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, которая каждый раз повторно инициализируется и не разделяется между различными вызовами.
(Это не означает, что статические локальные переменные не имеют своего применения; они просто не являются правильным выбором в данном конкретном случае.)