Реализация дерева двоичного поиска - Поиск братьев и сестер из заданного узла не работает должным образом - PullRequest
0 голосов
/ 23 июня 2019

Я строю программу, основанную на бинарных деревьях поиска.У меня проблемы с поиском братьев и сестер.Всякий раз, когда у дерева есть родной брат, оно работает отлично, никаких проблем.Но, если у него нет родного брата, он вылетает и не произносит сообщение «No tiene hermanos», что означает, что у него нет братьев.

Терминология:
izq = слева, der = right, nodo = узел, hermano = sibling

Я не понимаю, почему это не работает должным образом, я пытался быть общим,Конкретно, моих возможностей недостаточно.Я попытался включить операторы if, out, изменив код с родительским узлом, изменив порядок ifs.Я изменил функцию в void, изменил возврат, возвратил общее сообщение, нет возврата при перемещении влево и вправо, idk.

 bool Hermanos (Nodo *arbol, int n) {
     if (arbol == NULL){
         return false;
     }
     else if ((arbol->der->dato == n) || (arbol->izq->dato == n )) {
         if ( arbol->der->dato == n && arbol->izq != NULL){
             cout<<arbol->izq->dato;
         }
         else if (arbol->izq->dato == n && arbol->der != NULL){
             cout<<arbol->der->dato;
         }
         else if ((arbol->izq == NULL) || (arbol->der == NULL)){
             cout<<"No tiene hermanos";
         }
         return true;
      }
      else if (n < arbol -> dato) {
          return Hermanos(arbol->izq, n);
      }
      else {
          return Hermanos(arbol->der, n);
      }
  }

Допустим, у меня есть 2 узла, 5 и 20, являющиеся 20 правильными детьми.Если я посмотрю на 20, он должен сказать: «У него нет родного брата».

Ответы [ 3 ]

1 голос
/ 23 июня 2019

Основной if, который проверяет дочерние узлы на n, может разыменовать указатели NULL, если отсутствуют правый или левый узлы.

С примерами данных, как только вы найдете правый узел, которыйимеет n, ваше первое значение в этом блоке будет истинным, если этот узел является правым дочерним элементом И родительский узел (arbol) имеет левого дочернего элемента.Если это не так, мы проверяем следующее, если, и именно в этом проблема.Если левого потомка нет, arbol->izq->dato будет разыменовывать указатель NULL.

Это легко увидеть, если вы разыменовали arbol->izq->data, затем проверьте arbol->izq на NULL после проверки данные в (потенциально несуществующем) узле.

Таким образом, у вас есть несколько мест, где вы можете разыменовать нулевой указатель.

0 голосов
/ 24 июня 2019

Я изменил код, с помощью вашего комментария. Теперь это функция Node, где он возвращает узел, а в другой функции я спрашиваю, является ли он NULL или нет. Предполагается, что он возвращает NULL, если один из левого или правого узла имеет значение NULL.

Nodo* Hermanos (Nodo *arbol, int n){
if (arbol == NULL){
    return NULL;
}

else if ((arbol->der !=NULL) && (arbol->izq !=NULL )){

//ENCONTRO ARBOL DERECHO
    if( arbol -> der -> dato == n)
        return arbol->izq;

//ENCONTRO ARBOL IZQUIERDO
    else if( arbol -> izq -> dato == n)
        return arbol->der;

        }

    else if (n < arbol -> dato){
        return Hermanos(arbol->izq, n);
    }

    else if ( n > arbol ->dato){
        return Hermanos(arbol->der, n);
    }

    else /*if ( arbol -> der == NULL || arbol -> izq == NULL) */
    return NULL;

 }

Он отлично работает для корня и 1-го уровня дерева, но всякий раз, когда нет узла-брата, на последующих уровнях он читается так, как будто он есть.

Вторая функция

        gotoxy(32,26);
        cout<<"Hermano: ";

        b = Hermanos(arbol,num);
        if(b == NULL)
          cout<<"No tiene hermano";

        else
        cout<<b<<endl;
0 голосов
/ 23 июня 2019

Я изменил код, с помощью вашего комментария.

else if ((arbol->der->dato == n) || (arbol->izq->dato == n )){

//ENCONTRO ARBOL DERECHO
    if( arbol -> der -> dato == n){
        if( arbol -> izq != NULL){
        cout<< arbol->izq->dato;
        }
        else{
        cout<<"No tiene hermano izquierdo";
        }
    }

//ENCONTRO ARBOL IZQUIERDO
    else if( arbol -> izq -> dato == n){
        if( arbol -> der != NULL){
        cout<< arbol->der->dato;
        }
        else{
        cout<<"No tiene hermano derecho";
        }
    }

Я все еще показываю некоторые ошибки, но я думаю, что синтаксис здесь лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...