Arvore Binaria

1. Arvore Binaria

Caio
feholy

(usa Outra)

Enviado em 19/06/2016 - 16:43h

Preciso inserir uma lista automatica em uma arvore binaria e imprimi-la. estou com um pouco de dificuldade ja que nao domino muito a função rand

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>

struct Arvore
{
int matricula;
char nome[100];
char curso[100];
struct Arvore *esq, *dir;
};

typedef struct Arvore *pArvore;

//variavel para a raiz da arvore
pArvore raiz = NULL;

//prototipação da função
void Inserir(pArvore *p, int x);
int Remover(pArvore *p, int x);
pArvore maior(pArvore *p);
pArvore Buscar(pArvore p, int x);

//essa funcao ira fazer de forma recursiva a inclusao
void Inserir(pArvore *p, int x)
{
// procura se a arvore esta vazia
if((*p) == NULL)
{
*p = (pArvore)malloc(sizeof(struct Arvore));
(*p)->esq=NULL;
(*p)->dir=NULL;
(*p)->matricula=x;
}
else
{
if(x <((*p)->matricula))
//função recursiva se o numero for menor do que o numero da raiz
Inserir(&((*p)->esq), x);
else
//função recursiva se o numero for maior do que o numero da raiz
Inserir(&((*p)->dir), x);
}
}




int Remover(pArvore *p, int x)
{
if(*p == NULL)
//verifica se a arvore esta vazia
return 1;
else {
pArvore aux = *p;
if((*p)->matricula == x) //achou o elemento
{//apenas o subno da direita
if((*p)->esq ==NULL){
*p = (*p)->dir;
free(aux);
}
else
//apenas quando tem o subno da esquerda
if((*p)->dir==NULL){
*p = (*p)->esq;
free(aux);
}else{
//quando possui dois subnos, chama a função maior
aux = maior(&((*p)->dir));
free(aux);
}
}else{
if(x < (*p)->matricula)
return Remover(&((*p)->esq), x);
else
return Remover(&((*p)->dir), x);
}
return 0; //retorna 0 caso tenha tido sucesso ao remover o elemento
}

}

pArvore maior(pArvore *p){
pArvore aux = *p;
if(aux->esq==NULL){
*p = (*p)->dir;
return aux;
}
else{
return maior(&((*p)->esq));
}
}

void randomiza(pArvore *p, int x)
{
int i;
srand(time(NULL));
if(*p == NULL)
return 1;
else{
i = rand() % 100;
return 0;}

}



//Procura um elemento na arvore

pArvore Buscar(pArvore p, int x){
if(p==NULL)return 0;
else{
if(p->matricula == x) return p->matricula;
else{
if(x < p->matricula)
return Buscar(p->esq, x);
else
return Buscar(p->dir, x);
}
}
}

int imprime_insere(pArvore *p, int x)
{
int i;
if(*p == NULL)
return 1;
else{
printf("%d\n", *p);
return 0;
}
}

int main(void){

char opcao;
int x, aux;
clock_t inicio,fim;
double time_insere=0,time_remove=0,time_Busca=0;

do{
printf("==============================\n");
printf("||===== Arvore Binaria =====||\n");
printf("||==========================||\n");
printf("||=== O que deseja fazer? ==||\n");
printf("||= (1) Inserir um novo no =||\n");
printf("||= (2) Remover um no ======||\n");
printf("||= (3) Buscar um no =======||\n");
printf("==============================\n");
scanf("%d",&opcao);
if(opcao<1||opcao>3);{
exit(1);
}
switch(opcao){

case 1:
randomiza(&raiz, x);
inicio=clock();
Inserir(&raiz, x);
fim=clock();
time_insere = ((double)(fim-inicio))/CLK_TCK;
imprime_insere(&raiz, x);
break;

case 2:
randomiza(&raiz, x);
inicio=clock();
Remover(&raiz, x);
fim=clock();
time_remove = ((double)(fim-inicio))/CLK_TCK;

case 3:
randomiza(&raiz, x);
inicio=clock();
Busca(&raiz, x);
fim=clock();
time_Busca = ((double)(fim-inicio))/CLK_TCK;


}
}while(opcao>0||opcao<3);
return 0;
}











  


2. Re: Arvore Binaria

Paulo
paulo1205

(usa Ubuntu)

Enviado em 20/06/2016 - 09:00h

O uso de números aleatórios com rand() é muito simples:

1) No início do programa (portanto apenas uma vez), você chama srand() para inicializar a semente aleatória. Tipicamente se faz algo como “srand(time(NULL));” ou coisa parecida.

2) Para cada número aleatório que você quiser sortear, basta fazer “var_aleat=rand();”. Isso vai colocar ná variável um valor inteiro na faixa que vai de 0 a RAND_MAX, inclusive. RAND_MAX é uma constante inteira definida em <stdlib.h>.

3) Se você quiser ajustar o valor da variável aleatória para uma faixa [MIN, MAX], pode aplicar uma fórmula: “var_aleat=MIN+(double)rand()/(double)RAND_MAX*(MAX-MIN);”.

3.1) Se o valor da variável aleatória for inteiro, coloque a fórmula acima do seguinte modo: “var_aleat=floor(0.5+MIN+(double)rand()/(double)RAND_MAX*(MAX-MIN));”.

ATENÇÃO: Provavelmente você vai ver por aí implementações que fazem, para variáveis aleatórias inteiras, algo do tipo “var_aleat=MIN+rand()%(MAX-MIN+1);” (frequentemente com MIN=0, resultando em algo como “var_aleat=rand()%(MAX+1);”). NÃO USE ESSA FORMA, pois muitas implementações de rand() usam uma fórmula interna que tem relativamente pouca aleatoriedade nos bits de baixa ordem, e a operação de extrair o resto da divisão acaba, em muitos casos, usando apenas os bits de baixa ordem e desprezando a maior aleatoriedade dos bits de ordem mais alta. Usando a forma com divisão de ponto flutuante, você consegue aproveitar todos os bits do número sorteado.



3. Re: Arvore Binaria

Caio
feholy

(usa Outra)

Enviado em 20/06/2016 - 09:20h

Mas não era para meu algoritmo estar funcionando? nao entendo o que estou fazendo de errado.. Ja tentei n formas diferentes mas nao consigo faze-lo funcionar.


4. Re: Arvore Binaria

Paulo
paulo1205

(usa Ubuntu)

Enviado em 20/06/2016 - 10:51h

feholy escreveu:

Mas não era para meu algoritmo estar funcionando? nao entendo o que estou fazendo de errado.. Ja tentei n formas diferentes mas nao consigo faze-lo funcionar.


Para saber se está funcionando ou não, seria bom saber o que você tem de fazer, para poder comparar com o que você está obtendo.

Olhando seu programa sem me aprofundar demais, eis o que me pareceu:

- A função de inserção na árvore parece OK.

- A função de remoção está estranha. Em particular, não entendi o tratamento que você deu ao nó quando ele tem subárvores nos dois ramos.

- A função randomiza() viola a receita de bolo que eu mencionei anteriormente. Além disso, ela não depende da árvore, logo ela não deveria receber um nó da árvore como parâmetro. Se você quer dar um tratamento inicial ao primeiro nó, faça isso fora da função.

- A função de busca diz que retorna um ponteiro para nó da árvore, mas os comandos internos estão retornando valores inteiros, o que está claramente errado.

- Não entendi o propósito de imprime_insere(). Ademais, a string de formatação de printf() está incompatível com o tipo do argumento que a segue. Se você quer imprimir o valor de um ponteiro, use "%p", nunca uma conversão de inteiro.

- Em main(), o tipo de opcao, que é char, não combina com a conversão usada em scanf(), que é de dado do tipo int.


Eu acho que o que o enunciado pediu deve ser diferente daquilo que você fez. Como você está medindo tempos de execução, eu imagino que faria mais sentido você medir o tempo médio de uma série de inserções (i.e. tempo total dividido pelo número de inserções) do que medir o tempo de cada inserção -- até porque, num computador típico, o tempo de inserção de um único nó na árvore tem grandes chances de ser menor do que a resolução do relógio, principalmente se forem os primeiros nós da árvore. O mesmo vale para a remoção e para a busca.


5. Re: Arvore Binaria

Caio
feholy

(usa Outra)

Enviado em 20/06/2016 - 10:57h

paulo1205 escreveu:

feholy escreveu:

Mas não era para meu algoritmo estar funcionando? nao entendo o que estou fazendo de errado.. Ja tentei n formas diferentes mas nao consigo faze-lo funcionar.


Para saber se está funcionando ou não, seria bom saber o que você tem de fazer, para poder comparar com o que você está obtendo.

Olhando seu programa sem me aprofundar demais, eis o que me pareceu:

- A função de inserção na árvore parece OK.

- A função de remoção está estranha. Em particular, não entendi o tratamento que você deu ao nó quando ele tem subárvores nos dois ramos.

- A função randomiza() incorre viola as receita de bolo que eu mencionei anteriormente. Além disso, ela não depende da árvore, logo ela não deveria receber um nó da árvore como parâmetro. Se você quer dar um tratamento inicial ao primeiro nó, faça isso fora da função.

- A função de busca diz que retorna um ponteiro para nó da árvore, mas os comandos internos estão retornando valores inteiros, o que está claramente errado.

- Não entendi o propósito de imprime_insere(). Ademais, a string de formatação de printf() está incompatível com o tipo do argumento que a segue. Se você quer imprimir o valor de um ponteiro, use "%p", nunca uma conversão de inteiro.

- Em main(), o tipo de opcao, que é char, não combina com a conversão usada em scanf(), que é de dado do tipo int.


Eu acho que o que o enunciado pediu deve ser diferente daquilo que você fez. Como você está medindo tempos de execução, eu imagino que faria mais sentido você medir o tempo médio de uma série de inserções (i.e. tempo total dividido pelo número de inserções) do que medir o tempo de cada inserção -- até porque, num computador típico, o tempo de inserção de um único nó na árvore tem grandes chances de ser menor do que a resolução do relógio, principalmente se forem os primeiros nós da árvore. O mesmo vale para a remoção e para a busca.


este e o enunciado do exercicio.

irei tentar corrigir os pontos que vc colocou. muito obrigado pela resposta. irei tentar corrigir e postarei os resultados....

Considere a estrutura de dados Aluno
Aluno
Matrícula
Nome
Curso
&#61623; Considere uma lista de alunos que deve ser inserida de forma automática e randômico:
o A matricula pode ser randômica;
o O algoritmo deve garantir que não existam duas matrículas iguais.
o Nome e curso podem ser fixos com até 100 caracteres.
&#61623; Implemente as estruturas de dados, considerando a chave a matrícula:
o Árvore Binária de Pesquisa
o Hash com endereçamento aberto.
&#61607; A Hash deve ter um tamanho maior que a quantidade de registros que será inserido, e esse tamanho deve ser um número primo.
&#61623; Faça uma função que defina esse tamanho da hash.
o Devem ser implementadas as funções básicas destas estruturas que permitam a Inserção, Retirada e Pesquisa das estruturas de dados Aluno.
&#61623; Testes
o Devem ser feitos testes com diferentes quantidades de registros de Alunos
&#61607; 1.000, 5.000 e 10.000 registros
o Execute testes de pesquisa nas duas estruturas de dados de forma automática:
&#61607; Crie uma pesquisa randômica por chave para medir para cada estrutura
&#61623; Quantidade de comparações
&#61623; Tempo em milissegundos
&#61607; Faça testes de pesquisa:
&#61623; 100, 500 e 1000 registros


6. Re: Arvore Binaria

Paulo
paulo1205

(usa Ubuntu)

Enviado em 20/06/2016 - 13:41h

O enunciado confirmou minha expectativa. Que bom que algumas coisas no mundo ainda fazem sentido. ;)

Corrija os pontos que estavam errados e ajeite seu programa para fazer o que foi pedido.

Não deixe de informar aqui o seu progresso e o eventual sucesso.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts