Для назначения я должен придумать рекурсивную функцию all_less
которая принимает указатель aa на любое произвольное дерево (TN<T>*
) и параметр T
Он возвращает true, если все значения меньше, чем параметр T, иначе он возвращает false.
Переменные экземпляра для моего класса Tree
следующие:
T value;
TN<T>* left;
TN<T>* right;
И прототип функции для all_less
выглядит следующим образом:
template<class T>
bool all_less(TN<T>* t, T v)
Поскольку я должен рассмотреть несортированное двоичное дерево, я решил рекурсивно спустить каждое поддерево и проверить, что каждое значение будет работать нормально. После проверки этой функции:
template<class T>
bool all_less(TN<T>* t, T v)
{
if(v <= t->value) {
return false;
} else if(v > t->value) {
if(t->right != nullptr && t->left != nullptr) {
all_less(t->right, v);
all_less(t->left, v);
}
}
return true;
}
После того, как некоторые проблемы с функцией почти всегда возвращают true, я помещаю некоторые инструкции для печати перед return true
и return false
чтобы увидеть, что происходит.
В качестве примера скажем, что мы имеем значения 12, 15, 14, 5 в двоичном дереве. Запуск моей функции с использованием:
TN<int>* t;
std::cout << all_less(t, 15);
как вход, выдаст это:
true
false
true
true
Конечный результат оказался бы верным, хотя ложь возвращалась один раз. Как я могу получить его так, чтобы, если он возвращает false, функция возвращает false и немедленно останавливается? Также есть ли лучший способ реализовать эту функцию? Вначале у меня было несколько дополнительных команд if-else, чтобы проверить, были ли правые/левые поддеревья пустыми и продолжались оттуда, но на самом деле они ничего не делали.
Вы игнорируете возвращаемые значения рекурсивных вызовов.
Конечный результат оказался бы верным, хотя ложь возвращалась один раз.
Это false
было возвращено из другого вызова функции и исчезло в большой битбакет в небе.
Рекурсивные функции работают точно так же, как и любые другие функции - если у вас есть
int f() { return 0:}
int g(int x) {
if (x == 0)
f();
return 1;
}
g(0)
вернет 1, хотя 0 был возвращен один раз.
Если g(0)
должно возвращать значение f()
, оно должно делать это явно:
int g(int x) {
if (x == 0)
return f();
return 1;
}
Вы также предполагаете, что все узлы имеют либо ноль, либо два ребенка.
Если вы примете соглашение о том, что все элементы в пустом дереве меньше значения, вы можете написать
template<class T>
bool all_less(TN<T>* t, T v)
{
return !t
|| ( t->value < v
&& all_less(t->right, v)
&& all_less(t->left, v));
}
Ваша функция:
template<class T>
bool all_less(TN<T>* t, T v)
{
if(v <= t->value) {
return false;
} else if(v > t->value) { // Why do you need this check?
if(t->right != nullptr && t->left != nullptr) {
// This is wrong because it possible for one them to
// nullptr while the other is not.
all_less(t->right, v);
all_less(t->left, v);
// The above function calls are no op. You are calling
// the function recursively but are ignoring the return
// values.
}
}
return true;
}
Это должно работать:
template<class T>
bool all_less(TN<T>* t, T v)
{
if(v <= t->value) {
return false;
}
if(t->right != nullptr )
{
if ( !all_less(t->right, v) )
{
return false;
}
}
if ( t->left != nullptr)
{
if ( !all_less(t->left, v) )
{
return false;
}
}
return true;
}
ps Неиспользованный код.
all_less
рекурсивно и игнорируете возвращаемое значение. Зачем вам эти звонки?