Binary Tree returning empty in search

3

In my menu it is not making the correct output in the print. In addition to the search return only empty tree.

#include<iostream>
#include<string>
#include<stdlib.h>
#include<stdio.h>
using namespace std;

typedef int TipoChave;

typedef struct TipoRegistro{
    TipoChave Chave;
    string Nome;
    float Preco;
    int QuantEstoque;
}TipoRegistro;

typedef struct TipoNo* Apontador;

typedef struct TipoNo{
    TipoRegistro Reg;
    Apontador Esq, Dir;
}TipoNo;


void ImprimeEmOrdem(TipoNo *pRaiz)
{
    if(pRaiz != NULL)
    {
        ImprimeEmOrdem(pRaiz->Esq);
        cout<<"IMPRIME  "<<pRaiz->Reg.Chave;
        ImprimeEmOrdem(pRaiz->Dir);
    }
}

void Pesquisa(TipoRegistro x, Apontador *p)
{
    if((*p) == NULL)
    {
        cout<<"ERRO 1: Regristo nao esta presente\n"<<endl;
    }

    if(x.Chave < (*p)->Reg.Chave)
    {
        Pesquisa(x, &((*p)->Esq));
    }
    if(x.Chave > (*p)->Reg.Chave)
    {
        Pesquisa(x, &((*p)->Dir));
    }
    else
    {
        x = (*p)->Reg;
    }
}

void Insere(TipoRegistro x, Apontador *p)
{
    cout << "teste";
    if(*p == NULL)
    {
        cout << "primeiro if";
        *p = (Apontador)malloc(sizeof(TipoNo));
        (*p)->Reg = x;
        (*p)->Esq = NULL;
        (*p)->Dir = NULL;
        cout << "Registro inserido com sucesso";
    }

    if(x.Chave < (*p)->Reg.Chave)
    {
        cout << "segundo if";
        Insere(x,&(*p)->Esq);
        return;
    }

    if(x.Chave > (*p)->Reg.Chave)
    {
        cout << "terceiro if";
        Insere(x, &(*p)->Dir);
        return;
    }

    //else cout<<"ERRO 2 : Regristo ja existe na arvore\n";
}

void Inicializa(Apontador p) //Apontador 'e um ponteiro
{
    p = NULL;
}

int main()
{
    int op, c = 1;
    Apontador No, Topo;
    TipoRegistro x;

    Topo = NULL;

    //No = Topo;

    do      //while(c != 0)
    {
        cout<<"Escolha Uma das opcoes abaixo"<<endl;
        cout<<"\t1. Inserir Produtos:  \n\t2. Buscar Produtos \n\t3. SAIR"<<endl;
        cin>>op;


        switch (op)
        {

            case 1 :
                cout<<"DIGITE O CODIGO : ";
                cin>>x.Chave;
                cout<<"DIGITE O NOME DO PRODUTO : ";
                cin>>x.Nome;
                cout<<"DIGITE O PRECO DO PRODUTO : ";
                cin>>x.Preco;
                cout<<"DIGITE A QUANTIDADE DISPONIVEL NO ESTOQUE : ";
                cin>>x.QuantEstoque;

                cout << x.Chave << endl;
                cout << (Topo == NULL) << endl;

                Insere(x, &Topo);

                cout << Topo->Reg.Chave;


                Pesquisa(x, &Topo);

                break;

            case 2 :
                cout<<"DIGITE O CODIGO OU NOME A SER BUSCADO : ";
                cin>>x.Chave;
                Pesquisa(x, &Topo);
                break;

            case 3 :
                cout<<"VOCE ESTA SAINDO\n";
                c = 0 ;
                break;

            default :
                cout<<"OPCAO INVALIDA";
                break;
        }

    }while(op !=3 );

    ImprimeEmOrdem(Topo);
}
    
asked by anonymous 06.11.2014 / 13:49

1 answer

4

Initialization

First, the Inicializa(No) function assigns the value null to the variable passed by parameter. However, this is an input-only argument, so the value is not reflected outside the scope of the function.

Thus, the No variable before the function has memory garbage, and after the function continues to have memory garbage. To correct this, you must transform the parameter p of the function into an input and output parameter. This can be done in two ways (the former can be used in C or C ++, but the latter is recommended to be used only in C ++):

C / C ++:

void Inicializa(Apontador *p) {
    *p = NULL;
}

C ++:

void Inicializa(Apontador &p) {
    p = NULL;
}

So, the call Inicializa(No) , will correctly initialize the value of the No variable.

The second boot problem in your code is in the if ( c = 1 ) Topo = No; line. The meaning of this line for the compiler is:

  • Assign 1 to variable c ;
  • Verify that c is true;
  • Assign No to Topo .
  • By 1 step, the 2 step will be evaluated as always true, and therefore in every iteration of your looping, assignment of No to Topo . Therefore:

    if ( c = 1 ) Topo = No;
    

    Do the same as simply:

    Topo = No;
    

    The c variable is not used elsewhere in your code. I believe this is not your goal. If it is, as you can see, you can remove it without semantic and logical problems.

    Insertion

    I think at least the first boot error has been fixed.

    After reading the value to be inserted in your tree, you call the command Insere passing the value read x.Chave and the variable Topo . It suffers from the same problem as the Inicializa function:

    The variable Topo is passed in the p parameter only as input argument, so any changes made to it within the Insere function are not reflected outside its scope.

    The correction can be done in the same way as the Inicializa function, and it will be a correction exercise (it is a bit more boring, since the p variable is used in recursive calls; is the same, and is a great exercise on pointers).

    Apparently, these are the fixes that answer your question.

    Note

    In the explanation of the transformation of the parameter p into the function Inicializa into an input and output parameter, there is some discussion about which of the two methods should be used, since both through a pointer and through of a reference, the parameter can be passed as input and output.

    In any case, I will not pay attention to this because this is a question about good practices, and widely open to opinions. So I put the two methods and I did not suggest any of them.

        
    06.11.2014 / 17:14