Ian Varejao
-
Posts
15 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Fabricantes
Livros
Cursos
Análises
Fórum
posts postados por Ian Varejao
-
-
Ok, depois de tanto tempo, o código já está muito melhor, porém continuo com a dúvida de o que colocar no arvore.h e o que colocar no fila.h.
O grande problema é que no arvore.h há funcoes de arvore que usam a estrutura de fila,e por isso o arvore.h deve conhecer a estrutura de fila, e a mesma coisa acontece para o fila.h, que usa a estrutura de arvores.
o que fazer quando dois header files possuem dependencia mutua?O unico jeito é juntar tudo num unico header file?
ps.: Desculpa ressucitar um topico antigo, mas tenho coisa a acrescentar e ainda tenho duvida.
arvore.h:
/**********************************Arvore Binaria de Busca com Fila**versao Recursiva **arvore.h HEADER FILE **********************************///Estrutura de Dados typedef struct arvore { int elem; int N; struct arvore *esq,*dir; }arvore; typedef struct fila { arvore* node; struct fila *prox; }fila;//Prototipos//Arvore //Funcoes essenciais arvore* Cria(int); void Destroi(arvore**); //Funcoes de Insercao void Insere(arvore **,int); void Preenche(arvore **,int,int); //Funcoes de Remocao void Remove(arvore **,int); //Funcoes de Percurso void PreOrdem(arvore*); void EmNiveis(arvore*,fila**); void fEmNiveis(FILE*,arvore*,fila**); //Funcoes de Busca int Existe(arvore*,int); int Menor(arvore*); //Outras Funcoes void setN(arvore*);//Fila //Essenciais fila* CriaFila(arvore*); void DestroiFila(fila**); //Insercao void Enfileira(fila**,arvore*); //Remocao arvore* Desenfileira(fila**); void ImprimeFila(fila*);
fila.h:
/**************************FILA PARA USO EM ARVORES**HEADER FILE **************************///Estrutura de Dados typedef struct fila { arvore* node; struct fila *prox; }fila;//Prototipos das Funcoes //Essenciais fila* CriaFila(arvore*); void DestroiFila(fila**); //Insercao void Enfileira(fila**,arvore*); //Remocao arvore* Desenfileira(fila**);
arvore.c:
/*************************Arvore Binaria de Busca**versao Recursiva **arvore.c SOURCE FILE *************************///Headers#include <stdio.h>#include <stdlib.h>#include "arvore.h"//Funcoes essenciaisarvore* Cria(int x){ arvore *novo=(arvore*) malloc(sizeof(arvore)); novo->elem=x; novo->N=1; novo->esq=novo->dir=NULL;}void Destroi(arvore **p){ if(*p != NULL) { Destroi(&(*p)->esq); Destroi(&(*p)->dir); (*p)->esq=(*p)->dir=NULL; free(*p); }}//Funcoes de Insercaovoid Insere(arvore **A,int x){ arvore *p=(*A); if(p!=NULL) { if(p->elem > x) Insere(&p->esq,x); else if(p->elem < x) Insere(&p->dir,x); else printf("Elemento já existente!\n"); } else { p=Cria(x); (*A)=p; }}void Preenche(arvore **A,int x,int y){ if(x<y) { int meio= (x+y)/2; Insere(A,meio); Preenche(&(*A)->esq,x,meio); Preenche(&(*A)->dir,meio+1,y); }}//Funcoes de Remoçaovoid Remove(arvore **A,int x){ arvore *p=(*A); if(p!=NULL) { if(p->elem != x) { if(p->elem > x) Remove(&p->esq,x); else Remove(&p->dir,x); } else { if(p->esq == p->dir) { (*A)=NULL; free(p); } else if(p->esq == NULL) { (*A)=p->dir; free(p); } else if(p->dir == NULL) { (*A)=p->esq; free(p); } else { int y=Menor(p->dir); Remove(&p->dir,y); p->elem=y; } } }} //Funcoes de Percursovoid PreOrdem(arvore *p){ if(p!=NULL) { printf("Elemento: %d \tTamanho: %d\n",p->elem,p->N); PreOrdem(p->esq); PreOrdem(p->dir); }}void EmNiveis(arvore *p,fila **F){ if(p!=NULL) { if(*F==NULL) Enfileira(F,NULL); Enfileira(F,p->esq); Enfileira(F,p->dir); printf("%d ",p->elem); p=Desenfileira(F); if(p==NULL && *F!=NULL) { printf("\n"); p=Desenfileira(F); Enfileira(F,NULL); } EmNiveis(p,F); }}void fEmNiveis(FILE *fp,arvore *p,fila **F){ if(p!=NULL) { if(*F==NULL) Enfileira(F,NULL); Enfileira(F,p->esq); Enfileira(F,p->dir); fprintf(fp,"%d ",p->elem); p=Desenfileira(F); if(p==NULL && *F!=NULL) { fprintf(fp,"\n"); p=Desenfileira(F); Enfileira(F,NULL); } fEmNiveis(fp,p,F); }} //Funcoes de Buscaint Existe(arvore *p,int x){ if(p!=NULL) { int y=p->elem; if(y!=x) { if(y > x) Existe(p->esq,x); else Existe(p->dir,x); } else return 1; } else return 0;}int Menor(arvore *p){ if(p!=NULL) { if(p->esq!=NULL) Menor(p->esq); else return p->elem; }}//Outras Funcoesvoid setN(arvore *p){ if(p!=NULL) { if(p->esq != NULL) { setN(p->esq); p->N+=p->esq->N; } if(p->dir != NULL) { setN(p->dir); p->N+=p->dir->N; } }}
fila.c:
/**************************FILA PARA USO EM ARVORES**SOURCE FILE **************************///Header Files#include <stdio.h>#include <stdlib.h>#include "arvore.h"//Funcoes Essenciaisfila* CriaFila(arvore *A){ fila *novo= (fila*) malloc(sizeof(fila)); novo->prox=NULL; novo->node=A;}void DestroiFila(fila **F){ if(*F!=NULL) { DestroiFila(&(*F)->prox); free(*F); (*F)=NULL; }}//Funcoes de Insercaovoid Enfileira(fila **F,arvore *A){ if(*F!=NULL) { fila *novo=CriaFila(A); novo->prox=(*F); (*F)=novo; } else (*F)=CriaFila(A);}//Funcoes de Remocaoarvore* Desenfileira(fila **F){ if(*F!=NULL) { if((*F)->prox!=NULL) Desenfileira(&(*F)->prox); else { arvore *A=(*F)->node; free(*F); (*F)=NULL; return A; } }}//Funcoes de Percursovoid ImprimeFila(fila *F){ if(F!=NULL) { if(F->node != NULL) printf("%d ",F->node->elem); ImprimeFila(F->prox); } else printf("\n");}
-
voce está usando a biblioteca math?
se sim, algumas versões do gcc precisam de -lm para incluir a biblioteca.
gcc prog.c -lm (inclui a libmath)
-
Observe que como vetor deve ter no mínimo Tamanho(vetor1) + Tamanho(vetor2) na hora que é criado, ou você estará acessando memoria que não devia acessar. Só usar int vetor[8] e não terá erro.O valor de N é alterado na função através de seu apontador, portando passe o endereço de N (&N) como argumento.exemplo:Insere(vetor3,vetor1,0,&N);void Insere(int *vetor,int x,int pos,int *N)
{
if(pos<(*N))//Enquanto não tiver percorrido todo o vetor
{
if(vetor[pos]!=x) Insere(vetor,x,pos+1,N);//Verifique se encontrou x
} //Se encontrou, não faça nada(sem repetição)
else//Varreu todo o vetor e não encontrou x?
{
vetor=x;//Insere o x na ultima posição do vetor
(*N)++;//E aumenta o tamanho N do vetor
}
}
-
gets() serve para ler string. Em C uma string é uma cadeia de caracteres terminada por '\0'.OU SEJA, 'a' é char e "a\0" não é char.
getchar() le um único caractere, e retorna o caractere lido.
ou seja
char c;
c=getchar();
vai ler um caracter e atribui-lo à variável c.
scanf("%c",&c); também pode ser usado para ler um caractere e atribui-lo a variável c.
note, porém, que '\n' (new line ou ENTER) é um caractere, e portanto será lido, então faça o tratamento correto da leitura.
char c;int LINHAS,COLUNAS,i,j;printf("digite o numero de linhas e de colunas: ");scanf("%d %d",LINHAS,COLUNAS);//Cria a matrizchar MATRIZ[LINHAS][COLUNAS];for(i=0;i<LINHAS;i++)//note que começa do 0 e não do 1.{ for(j=0;j<COLUNAS;j++) { while((c=getchar())=='\n');//vai procurar por um caractere diferente de \n ate achar MATRIZ[i][j]=c; }}
-
Melhorou, mais ainda não está 100%.
voce declarou duas variaveis (s e n) do tipo char, mas não as usa em nenhum momento.
Observe também que voce nao as inicializa ( nao atribui nada a elas ) então elas ficam com "lixo de memoria".
O código está correto, mas veja se é isso que voce pensou:
char s='s',n='n',estado;if(estado == s)if(estado == n)
Neste caso, voce estaria comparando duas variáveis do tipo char.
É muito bom que você desde cedo já comenta seu código, continue com essa boa prática, mas lembre-se também de endentar o código.
-
Acho que ele quis forçar a usar alocaçao estatica, que é até mais fácil, basta saber o tamanho da matriz ( que o usuario vai inserir como entrada) no momento de declarar a matriz.Então, nao se preocupe com isso de nao poder usar stdlib.h.
Para percorrer uma matriz voce pode usar dois for():
int i,j;
for(i=0; i<Numero_de_linhas; i++)
{
printf("linha %d:",i);
for(j=0;j< Numero_de_Colunas; j++)
printf(" %d",M[j]);
printf("\n");
}
Alguns compiladores (g++ e versões atualizadas do gcc) permitem declarar a variavel dentro do for: for(int i=0;i<10;i++);
Me diga exatamente onde você não está conseguindo para eu ajudar mais facilmente.Nao posso dar a resposta, voce tem que conseguir por si mesmo.
-
Qual é a forma mais rápida de se executar operação de troca de variáveis?
1.Usando uma variavel auxiliar.
2.Usando multiplos XOR ( operador ^ em C)
3.Usando a stack com comandos in line Assembly ( só funciona para variaveis Globais)
4.Usando a stack em Assembly puro, e juntando a função ao código em C na compilação.
- 1
-
Um livro que me ajudou muito foi Linguagem C, do Luís Damas, é bem didatico e vem com exercicios, alguns resolvidos, outros para treinar.Para realmente aprender C só treinando bastante e fuçando em tudo que a linguagem tem a oferecer por pura curiosidade.
Um site bom que sempre uso quando esqueço algo ou vejo algo que não conhecia ainda, é o cplusplus.com, é otimo para rever informações muito especificas como o tipo de retorno de uma função.
Um forum bom para tirar ocasionais duvidas, creio que você já conheça algum.
-
arvore.h:
struct NoArvore{ int elem; struct NoArvore *esq,*dir;};struct Arvore { int niveis; struct NoArvore * raiz;};void inserir(struct NoArvore * a_inserir, struct Arvore * arvore);void remover(struct NoArvore * a_remover, struct Arvore * arvore);void pesquisar(int elemento, struct Arvore * arvore);void percurso_em_nivel(struct Arvore * arvore);
Lista.h:
#ifndef _ARVORE_#define _ARVORE_#include "arvore.h"#endifstruct NoLista { struct NoArvore * p; // Aqui será armazenado o endereço do elemento. struct NoLista * proximo;};void lista_inserir(struct NoLista * a_inserir, struct NoLista * pai);void lista_remover(struct NoLista * a_remover);void lista_exibir(struct NoLista * origem);
No main você pode usar o mesmo truque das macros p/ evitar inclusão duplicada.
Note que você poderia meio que se livrar de incluir a lógica do armazenamento na lista na função percurso_em_nivel se passar um ponteiro p/ função (só dê uma olhada nos efeitos de se passar NULL pra esse tipo de coisa, porque não lembro se existe algum problema):
void percurso_em_nivel(struct Arvore * arvore, void (*store_traversal_function) (void *, void *)) { // Lógica do percurso na árvore // A cada nó visitado é possível executar a função store_traversall_function com // store_traversal_function(no_visitado, lista) // No seu caso, seria a função de inserção na lista. if (store_traversal_function) { struct NoLista * n = malloc(sizeof(struct NoLista)); // Verificação do retorno AQUI store_traversal_function(n, lista); }}
No main a chamada seria percurso_em_nivel(arvore, lista_inserir);
http://www.geeksforgeeks.org/level-order-tree-traversal/
Edit: falei lista, mas é fila.
Sim, o professor mostrou na aula essa versao com ponteiro para ponteiro no lugar de ficar comparando toda hora se é maior ou menor.
Eu vou tentar desse seu jeito, porque do jeito que eu fiz o codigo funciona como esperado porém na compilaçao aparece aviso: e um erro estranho que nao faz o menor sentido.
-
Usa fila p/ exibir os dados? você não quer dizer percurso em pré-ordem?
https://en.wikipedia.org/wiki/Tree_traversal#Pre-order
Se for isso não é necessário criar uma estrutura fila, a não ser que você queira armazenar a sequência do percurso. E mesmo nesse caso, a fila não se relaciona com a árvore.
Não, eu me refro ao percurso em niveis, onde voce percorre nivel por nivel, e visita os elementos na ordem em que aparecem no nivel, da esquerda pra direita.
Exemplo:
A
B C
D E F G
H I J K L M N O P
...
onde eu uso o No NULL para indicar que devo inserir '\n'.
-
Uma arvore binaria de busca, que usa fila para executar o percurso em niveis.
-
Tenho 1 arquivo.c
Quero separar ele em 3 codigos fontes:
1 com a main
1 com a Arvore
1 com a Fila
#include <stdio.h>#include <stdlib.h>typedef struct NoA{ int elem; struct NoA *esq,*dir,*pai;}NoA;typedef struct Arvore{ int N,H; NoA *raiz;}Arvore;typedef struct NoF{ NoA* elem; struct NoF *prox,*ant;}NoF;typedef struct Fila{ int Tamanho; NoF *primeiro,*ultimo;}Fila;void ConstroiA(Arvore *);void DestroiA(Arvore *,NoA *);NoA* Busca(Arvore *,int );NoA* BuscaMenor(NoA *);void Insere(Arvore *,int);void Remove(Arvore *,int);void Enumera(Arvore *);void ConstroiF(Fila *);void DestroiF(Fila *);void Enfileira(Fila *, NoA *);NoA* Desenfileira(Fila *);//MAINint main(){ printf("Testando a Arvore!\n"); Arvore A; ConstroiA(&A); int i,N=3000; Insere(&A,22); for(i=1;i<=N;i++) Insere(&A,i%2?i*2:i*3); Enumera(&A); for(i=1;i<=N;i++) Remove(&A,i%2?i*2:i*3); for(i=1;i<N;i++) Insere(&A,i%2?i*2:i*3); DestroiA(&A,A.raiz); return 0;}//Funcoesvoid ConstroiA(Arvore *A){ A->N=A->H=0; A->raiz=NULL;}void DestroiA(Arvore *A,NoA *{ if(B!=NULL){ DestroiA(A,B->esq); DestroiA(A,B->dir); free(;}}NoA* Busca(Arvore *A,int x){ NoA *pai,*prox=A->raiz; if(prox == NULL){ printf("A arvore está vazia!\n"); return NULL;} while(prox->elem != x){ pai=prox; if(x > prox->elem) prox=prox->dir; else prox=prox->esq; if(prox == NULL) return pai;} return prox;}NoA* BuscaMenor(NoA *A){ while(A->esq!=NULL) A=A->esq; return A;}void Insere(Arvore *A,int x){ NoA *novo,*pai; novo=(NoA *) malloc(sizeof(NoA)); novo->elem=x; novo->esq=NULL; novo->dir=NULL; if(A->raiz == NULL){ A->raiz=novo; novo->pai=NULL; return;} pai=Busca(A,x); if(x > pai->elem) pai->dir=novo; else if(x < pai->elem) pai->esq=novo; else{ printf("%d ja esta na Arvore!\n",x); return;} novo->pai=pai; A->N++;}void Remove(Arvore *A,int x){ //printf("%d\n",x); NoA *r,*pai; int f,isroot=0; r=Busca(A,x); if(r==NULL || r->elem != x) return; if(r->pai!=NULL){ pai=r->pai; f=x>pai->elem;} else isroot=1; if(r->esq == NULL && r->dir == NULL){//r nao tem filhos if(isroot) A->raiz=NULL; else if(f) pai->dir=NULL; else{ pai->esq=NULL;} free(r);} else if(r->esq == NULL){//r tem 1 filho(dir) if(isroot){ A->raiz=r->dir; r->dir->pai=NULL;} else{ if(f){ pai->dir=r->dir; r->dir->pai=pai;} else{ pai->esq=r->dir; r->dir->pai=pai;} free(r);}} else if (r->dir == NULL){//r tem 1 filho(esq) if(isroot){ A->raiz=r->esq; r->esq->pai=NULL;} else if(f){ pai->dir=r->esq; r->esq->pai=pai->dir;} else{ pai->esq=r->esq; r->esq->pai=r->dir;} free(r);} else{//r tem 2 filhos(esq e dir) pai=BuscaMenor(r->dir);//Busca pelo menor elemento na subarvore a direita de r f=pai->elem;//coloca o elemento encontrado em f Remove(A,f);//Remove f r->elem=f;//Troca f pelo elemento em r, desse jeito a arvore mantem sua logica return;} A->N--;}//Enumera Em Niveisvoid Enumera(Arvore *A){ printf("Imprimindo Arvore em \"ArvoreSaida.txt\"!\n"); FILE *fp=fopen("ArvoreSaida.txt","w"); NoA *prox=A->raiz; Fila F; int i=1; NoA *node=(NoA *) malloc(sizeof(NoA)); node->elem=0; node->esq=node->dir=NULL; ConstroiF(&F); Enfileira(&F,prox); Enfileira(&F,NULL); fprintf(fp,"nivel %d: ",i++); while(F.Tamanho){ prox=Desenfileira(&F); if(prox==NULL){ if(F.primeiro->elem==F.primeiro->ant->elem) if(!F.Tamanho) break; fprintf(fp,"\nnivel %d: ",i++); Enfileira(&F,NULL);} else{ if(!prox->elem) fprintf(fp,"X "); else{ fprintf(fp,"%d ",prox->elem); if(prox->esq!=NULL) Enfileira(&F,prox->esq); else Enfileira(&F,node); if(prox->dir!=NULL) Enfileira(&F,prox->dir); else Enfileira(&F,node);}}} free(node); fflush(fp); fclose(fp);}//Fila //Constroi void ConstroiF(Fila *F){ F->Tamanho=0; F->primeiro=F->ultimo=NULL;} //Destroi void DestroiF(Fila *F){ while(F->Tamanho--) Desenfileira(F);} //Enfileira void Enfileira(Fila *F,NoA* x){ NoF *novo; novo=(NoF *) malloc(sizeof(NoF)); novo->elem=x; novo->ant=novo; novo->prox=F->ultimo; if(F->Tamanho){ F->ultimo->ant=novo; F->ultimo=novo;} else{ F->ultimo=novo; F->primeiro=novo;} F->Tamanho++;} //Desenfileira NoA* Desenfileira(Fila *F){ NoF *p; NoA *x; p=F->primeiro; F->primeiro=p->ant; x=p->elem; free(p); F->Tamanho--; return x;}
-
Experimente utilizar algum método para tratamento de exceção: http://www.vivaolinux.com.br/artigo/Tratamento-de-excecoes-na-linguagem-C
Acho que e isso que estava procurando.No python havia o try, mas em C nao sabia como fazer.
Quando tiver tempo tentarei corrigir o problema, dai eu posto o codigo correto aqui, e digo se foi resolvido ou nao.
-
Este é o código:
#include <stdio.h>#define CONST 30double pot(double a, int { double c=1; for(b;b>0;b--) { c=c*a; } return c;}double raiz(double a,int k){ double x=1; int n; for(n=CONST;n>0;n--) { x=(1.0/k)*((k-1)*x+(a/pot(x,(k-1)))); } return x;}main(){ int b,resp; double a,c; printf("1-Potenciaçao\n2-Radiciaçao\n3-sair\n>"); scanf(" %d", &resp); while(resp!=3) { if(resp==1) { printf("potencia= a^b\ndigite a: "); scanf(" %lf", &a); printf("digite b: "); scanf(" %d", &; printf("\nCalculando...\n\n"); c=pot(a,; printf(" %lf^%d=%lf\n", a, b, c); } if(resp==2) { printf("radiciaçao= b-esima raiz de a\ndigite a: "); scanf(" %lf", &a); printf("digite b: "); scanf(" %d", &; printf("\nCalculando...\n\n"); c=raiz(a,; printf("A %d raiz de %lf é=%lf\n", b, a, c); } if(resp!=1 && resp!=2) { printf("Digite apenas 1 ou 2 ou 3\n>"); } printf("Fazer outra operaçao?(1-potenciaçao,2-radiciaçao,3-sair)\n>"); scanf(" %d", &resp); } }
Se eu digito um caracter especial quando vem o prompt pedindo para escolher a operaçao a ser realizada, o programa entra em loop infinito, repetindo os valores da ultima execucao.
Só quero saber como alterar meus inputs/outputs para que isso jamais aconteça.
O professor nao responde minhas mensagens, então to postando aqui.
Sobre o Clube do Hardware
No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais
Direitos autorais
Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais
Duvida em função simples
em C/C#/C++
Postado
Não apenas isso, também há problema no scanf.
Quando você quer mudar o conteúdo da variável em outra função você precisa passar o endereço dela.
Se não você estará passando apenas uma cópia do conteúdo, que pertencerá a outro endereço de memoria usado apenas pela função que foi chamada.
A função scanf altera o counteudo da variável com o valor lido pelo input, portanto ela necessita que seja passado o endereço da variável.
tente assim:
scanf("%d", endereço_da_variavel);
Para obter o endereço de uma variável utilize o operador &, assim: &variável=endereço.