Help with binary tree

1

Dear stack overflow friends.

The present is to request collaboration in the last cut project, I must make a binary tree that saves people with their age, I already have an advanced code, but I have an error when assigning the new_node-> field name that takes the value of the variable nom that is of type char, I will show you the code and beforehand I thank you for the collaboration

#include <iostream>
#include <string.h>

struct Nodo{
    char nombre[30];
    int edad;
    Nodo *der;
    Nodo *izq;
};

using namespace std;
//prototipos de funcion

Nodo *crearNodo(int,char[]);
void insertarNodo(Nodo *&, int, char[]);
void mostrarArbol(Nodo *, int);
void menu();

Nodo *arbol = NULL;


int main(int argc, char** argv) {

    menu();

    return 0;
}

//menu

void menu(){
    int ed, opcion, contador=0;
    char nom[30];
    do{
        cout<<"MENU"<<endl;
        cout<<"1. insertar un nuevo nodo"<<endl;
        cout<<"2.mostrar arbol"<<endl;
        cout<<"3.salir"<<endl;
        cout<<"opcion"<<endl;
        cin>>opcion;

        switch(opcion){
            case 1: cout<<"digite su edad"<<endl;
            cin>>ed;
            cout<<"digite su nombre"<<endl;
            cin.getline(nom,30);
            insertarNodo(arbol,ed, nom);
            cout<<"\n";
            system("pause");
            break;

            case 2: cout<<"mostrar el arbol\n\n";
            mostrarArbol(arbol,contador);
            cout<<"\n";
            system("pause");
        }
        system("cls");
    }while(opcion!=3);
}

Nodo *crearNodo(int ed, char nom){


    Nodo *nuevo_nodo = new Nodo();
          nuevo_nodo->edad = ed;
          nuevo_nodo->nombre=nom;
          nuevo_nodo->der = NULL;
          nuevo_nodo->izq = NULL;

          return nuevo_nodo;
}

void insertarNodo(Nodo *&arbol, int ed, char nom){

    if(arbol == NULL){
        Nodo *nuevo_nodo = crearNodo(ed,nom);
        arbol = nuevo_nodo;
    }
    else{
        int valorRaiz = arbol->edad;
        if(ed<valorRaiz){
            insertarNodo(arbol->izq,ed,nom);

        }
        else{
            insertarNodo(arbol->der,ed,nom);
        }
    }


}


void mostrarArbol(Nodo *arbol, int cont){

    if(arbol==NULL){

        return;
    }
    else{

        mostrarArbol(arbol->der,cont+1);
        for(int i=0;i<cont;i++){
            cout<<" ";
        }
        cout<<arbol->edad<<endl;
        cout<<arbol->nombre<<endl;
        mostrarArbol(arbol->izq,cont+1);
    }
}
    
asked by Edwin Garcia 17.05.2018 в 19:46
source

2 answers

1

The code fails in the function createNode (), specifically in the following line:

strcpy(nuevo_nodo->nombre,nom);

The problem is that your functions insertNode () and createNode () should receive pointers to char and simply receive char.

Change this:

Nodo *crearNodo(int ed, char nom);
void insertarNodo(Nodo *&arbol, char nom);

To this:

Nodo *crearNodo(int ed, char *nom);
void insertarNodo(Nodo *&arbol, char *nom);
    
answered by 17.05.2018 в 22:59
1

Your code two important problems:

  • Function prototypes do not match definitions :
    • crearNodo is declared as Nodo *(int,char[]) and is defined as Nodo *(int, char) .
    • insertarNodo is declared as void(Nodo *&, int, char[]) and is defined as void(Nodo *&, int, char) .
  • You are programming C ++ using headers from C : the header <string.h> is from C language , you have a version for C ++ that is <cstring> . Read this thread for more information.

Apart from the above problems, you have other minor problems:

  • Programs in C ++ with paradigms of C : Not that it is forbidden to do it, but since C ++ offers utilities to make your code more secure and compact, why use more verbose alternatives that require more control ( and therefore are more likely to error)?
  • Why do not you use objects? : This is a variation of the previous one, C ++ is a multi-paradigm language, but in its fundamentals is object orientation, why do not you take advantage of it?

Knowing these problems of your code, let's see the fault:

Nodo *crearNodo(int ed, char nom){


    Nodo *nuevo_nodo = new Nodo();
          nuevo_nodo->edad = ed;
          nuevo_nodo->nombre=nom; // Asignación incorrecta.
          nuevo_nodo->der = NULL;
          nuevo_nodo->izq = NULL;

          return nuevo_nodo;
}

Your problem is in assigning the name, and it is normal. The argument nom is of type char while Nodo::nombre is type char[30] . They are different types and therefore not assignable, you could solve it like this:

nuevo_nodo->nombre[0] = nom; // Asignación correcta.

But even if it is correct, surely it is not what you want to do; I assume that you expect nom to be more than one letter and assuming that the function crearNodo had the same signature as in its definition the correct code would be this:

Nodo *crearNodo(int ed, char nom[]){
//  char[], no char --> ~~~~~~~~~~


    Nodo *nuevo_nodo = new Nodo();
          nuevo_nodo->edad = ed;
          std::copy(nom, nom + 30, nuevo_nodo->nombre);
//        ~~~~~~~~~ <-- función de copia.
          nuevo_nodo->der = NULL;
          nuevo_nodo->izq = NULL;

          return nuevo_nodo;
}

However, I propose something different:

Proposal.

Start by changing your Nodo like this:

struct Nodo{
    std::string nombre;
    int edad = 0;
    Nodo *der = nullptr;
    Nodo *izq = nullptr;
};

As member Nodo::nombre an object of type std::string you can assign arbitrarily long names (not limited to 30 characters). In the rest of the members, when you add values by defecation in your definition, you can have control over your data in a more secure way.

The Nodo should be an internal object of a class Arbol , this last class being the owner of the creation and insertion functions of nodes (instead of single functions):

struct Arbol{

    void insertar(int edad, std::string nombre);
    void mostrar();

private:

    Nodo *crear(int edad, std::string nombre);
    void insertar(Nodo *&posicion, int edad, std::string nombre);

    struct Nodo{
//  ~~~~~~~~~~~ <--- El Nodo pertenece al Abol y es inaccesible desde fuera
        std::string nombre;
        int edad = 0;
        Nodo *der = nullptr;
        Nodo *izq = nullptr;
    };

    Nodo *raiz = nullptr;
};

The previous code follows the principles of encapsulation by hiding the user from the object Arbol everything that you should not interact with. Private functions can be much simpler even if you follow the same code:

Nodo *Arbol::crear(int edad, std::string nombre){
    return new Nodo{nombre, edad};
}

void Arbol::insertar(Nodo *&posicion, int edad, char nombre){

    if (posicion == nullptr){
        posicion = crearNodo(edad, nombre);
    }
    else{
        insertarNodo(edad < posicion->edad ? posicion->izq : posicion->der, edad, nombre);
    }
}
    
answered by 18.05.2018 в 08:30