paulo1205
(usa Ubuntu)
Enviado em 01/06/2017 - 13:46h
almeidajr escreveu:
Eu deveria criar então:
void inserir (arvore **raiz, char name[], int key)
É o mais comum, especialmente para quem vem do C. Mas uma alternativa seria fazer do seguinte modo.
void inserir(arvore * &raiz, const char *name, int key)
raiz é uma referência para ponteiro para
arvore. O compilador cuida de criar a passagem por referência, sem que você tenha de obter explicitamente o endereço do objeto a ser alterado. Já o atributo
const, aplicado ao nome, é para deixar claro que a função não vai modificar o conteúdo apontado pelo ponteiro recebido pelo parâmetro
name.
Na hora de chamar a função que recebe a referência, eis como poderia ficar.
arvore *raiz;
char nome[20];
int chave;
/* ... */
inserir(raiz, nome, chave); // Note que eu NÃO disse “&raiz”.
Também, no corpo da função, você não precisaria se preocupar com o duplo grau de ponteiros, pois a referência abstrai isso para você, de modo que o parâmetro
raiz se comporta como se fosse um simples ponteiro para
arvore.
{
if (*raiz == NULL)
{
arvore *aux;
aux = new (arvore);
strcpy (*raiz->nome, name);
aux->chave = key;
aux->dir = NULL;
aux->dir = NULL;
*raiz = aux;
}
Não precisa da variável auxiliar; você poderia operar diretamente sobre o ponteiro recebido.
if(raiz==nullptr)
return; // Com ponteiro de ponteiro, é importante garantir que o ponteiro mais externo é valido.
if(*raiz==nullptr){
*raiz=new arvore; // Sem parênteses desnecessários (e potencialmente perigosos).
// É necessário usar parênteses em volta de “*raiz” porque o operador “->” tem precedência maior
// que o operador unário “*”.
(*raiz)->chave=key;
strncpy((*raiz)->nome, name, 19); // Garante que nome não vai exceder tamanho máximo.
(*raiz)->nome[19]='\0'; // E garante a presença do terminador da string nesse nome.
(*raiz)->dir=(*raiz)->esq=nullptr;
}
Se, contudo, você adotar a versão com referência, o primeiro teste se torna desnecessário (uma referência terá sempre um objeto associado, nunca será um ponteiro nulo), e a sintaxe do restante fica bem mais simples.
if(raiz==nullptr){
raiz=new arvore;
raiz->chave=key;
strncpy(raiz->nome, name, 19);
raiz->nome[19]='\0';
raiz->dir=raiz->esq=nullptr;
}
else
{
if (key > *raiz->chave)
{
inserir (*raiz->dir, name, key);
}
else
{
inserir (*raiz->esq, name, key);
}
}
As invocações acima estão erradas. O certo seria o seguinte.
else if(key > (*raiz)->chave)
inserir(&(*raiz)->dir, name, key); // Operador de obtenção de endereço é “&”, não “*”.
else
inserir(&(*raiz)->esq, name, key);
Se você preferir fazer com referência com o parâmetro, de novo as ocorrências de “
(*raiz)” se tornam apenas “
raiz”, e o “
&” some.
else if(key > raiz->chave)
inserir(raiz->dir, name, key); // Operador de obtenção de endereço é “&”, não “*”.
else
inserir(raiz->esq, name, key);
}
E dentro da função principal chamar a função como:
for (i = 0; i < 8; i++)
{
inserir (&raiz, name[i], key[i]);
}
OK aí, a não ser que você decida usar o parâmetro como referência para ponteiro. Nesse caso, a chamada a
inserir ficaria do seguinte modo.
inserir(raiz, name[i], key[i]);
De novo, porém, eu convido você a tratar seus dados como objetos.
Tome os passos necessários para inicializar um nó dentro de um construtor do tipo
arvore, como eu mostrei na primeira mensagem (o único erro daquele mensagem foi não ter percebido que o primeiro parâmetro de
inserir() estava sendo passado por valor — aliás, eu editei aquela postagem para mostrar o recebimento do parâmetro por referência). Fazendo isso, veja como
inserir() ficou enxuta.