Рекурсивный поиск по бинарному дереву, возвращающий как true, так и false

0

Для назначения я должен придумать рекурсивную функцию 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, чтобы проверить, были ли правые/левые поддеревья пустыми и продолжались оттуда, но на самом деле они ничего не делали.

  • 0
    Вы вызываете all_less рекурсивно и игнорируете возвращаемое значение. Зачем вам эти звонки?
Теги:
recursion
tree
binary-tree

2 ответа

2
Лучший ответ

Вы игнорируете возвращаемые значения рекурсивных вызовов.

Конечный результат оказался бы верным, хотя ложь возвращалась один раз.

Это 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));
}
0

Ваша функция:

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 Неиспользованный код.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню