Baixe Programação em C: Pilhas e Árvores Binárias e outras Notas de estudo em PDF para Sistemas de Informação, somente na Docsity!
Sumário
Introdução
1- Programa Rota de Viagem :
3-Pilhas
a) Breve explicação
b) Implementação em um vetor 7
4- Árvore Binária
a) Breve explicação
b) Árvores e subárvores 8
c) Endereço de uma árvore e definição recursiva
d) Varredura esquerda-raíz-direita 9
5- Bibliografía
1- Introdução
Antes de qualquer coisa, é preciso entender o que é um grafo. Um grafo é
uma estrutura matemática usada para representar as relações entre as coisas
(pode-se chamar de objeto). Esta estrutura pode ser usada em campos da
matemática e da informática.
Podemos imaginar como, desde mapa rodoviário, até o relacionamento
social entre as pessoas.
No ramo da programação, o estudo em teoria do grafo é muito simples,
porém, aplicada em prática torna-se algo amplo e um pouco complexo, na
qual outros tipos de teorias estão envolvidas, como é o caso da pilha e da
árvore binária.
A seguir, mostraremos o programa e breve explicações sobre pilha e
árvore binária para o melhor entendimento.
2- Programa Rota de Viagem:
#include <stdio.h> #include <conio.h> #include <string.h> #define MAX 100 struct RT { char ori[20]; < vetor de origem> char para[20]; < vetor do destino> int dist;//distancia 1 char pular; }; struct RT voo[MAX];//estrutura do banco de dados int en=0; <entrada no “banco de dados”> int pesen=0; < índice de pesquisa> int top=0; < topo da pilha>
struct pilha{ char ori[20]; char para[20];
ROTEIRO("a","b",1200); ROTEIRO("b","c",1900); ROTEIRO("c","d",1000); ROTEIRO("b","e",600); ROTEIRO("b","d",200); ROTEIRO("e","c",1200); ROTEIRO("e","d",1900); ROTEIRO("d","a",1000); ROTEIRO("d","b",600); ROTEIRO("e","a",200); ROTEIRO("d","a",1200); } void ROTEIRO( char *ori, char *para, int di){ if (en<MAX){ strcpy(voo[en].ori,ori); strcpy(voo[en].para,para); voo[en].dist = di; voo[en].pular = 0; en++; } else printf ("BANCO DE DADOS CHEIO\n"); } void ACESSOBD(){ <Reinicializa o campo com todos os nós> int t; for (t=0;t<en;t++) voo[t].pular = 0; } void RETRAIR( char *ori, char *para) { int t; for (t=0;t<en;t++){ if (!strcmp(voo[t].ori,ori)&& !strcmp(voo[t].para,para)) { strcpy(voo[t].ori," "); return ; }} } void ROTA( char *para) { int t,di; di=0; t=0; if (t<top) { while (t<top){ printf (" %s para ",vpilha[t].ori); di += vpilha[t].di; t++; } printf ("%s",para); printf ("\n\n A distancia %c : %d.\n\n\n", 130, di);
else { printf ("========================================="); printf ("\n %c N%co h%c mais rotas para este destino %c",3, 198, 160, 3); printf ("\n========================================="); } }
int CAMPO( char *ori, char *lugar) { pesen = 0; while (pesen<en){ if (!strcmp(voo[pesen].ori,ori) && !voo[pesen].pular){ strcpy(lugar,voo[pesen].para); voo[pesen].pular=1; return voo[pesen].dist; } pesen++; } return 0; } <se há o vôo de para, devolve distancia. Se não, devolve 0> int PARTIDA( char *ori, char *para){ int t; for (t=en-1;t>-1;t--) if (!strcmp(voo[t].ori,ori) && !strcmp(voo[t].para,para)) return voo[t].dist; return 0; <não encontrou> } void EVOO( char *ori, char *para){ int d,di; char lugar[20]; if (d=PARTIDA(ori,para)){ push (ori,para,d); return ; } if (di=CAMPO(ori,lugar)){ push(ori,para,di); EVOO(lugar,para); } else if (top>0){ pop(ori,para,&di); EVOO(ori,para); } } void push( char *ori, char *para, int di){ if (top<MAX){ strcpy(vpilha[top].ori,ori);
4 –Árvore Binária
a) Breve explicação
Uma árvore binária é uma estrutura de dados mais geral que uma lista encadeada.
Nós e filhos:
Uma árvore binária (binary tree) é um conjunto de registros que satisfaz certas
condições. (As condições não serão dadas explicitamente, mas elas ficarão
implicitamente claras no contexto.) Os registros serão chamados nós (poderiam
também ser chamados células). Cada nó tem um endereço. Suporemos por enquanto
que cada nó tem três campos: um número inteiro e dois ponteiros para nós. Os nós
podem, então, ser definidos assim:
conteudo 999
esq dir struct cel { int conteudo; <conteúdo> struct cel *esq; struct cel *dir; }; typedef struct cel no ; <nó>
O campo conteúdo é a "carga útil" do nó; os outros dois campos servem apenas para
dar estrutura à árvore. O campo esq de todo nó contém o endereço de outro nó ou
NULL. A mesma hipótese vale para o campo dir. Se o campo esq de um nó X é o
endereço de um nó Y , diremos que Y é o filho esquerdo de X.
Analogamente, se X.dir é igual a &Y então Y é o filho direito de X.
Se um nó Y é filho (esquerdo ou direito) de X, diremos que X é o pai de Y. Uma
folha (leaf) é um nó que não tem filho algum.
É muito conveniente confundir cada nó com seu endereço. Assim, se x é um ponteiro
para um nó (ou seja, se X é do tipo *no), dizemos simplesmente "considere o nó X "
em lugar de "considere o nó cujo endereço é X ".
b) Árvores e subárvores
Suponha que X é (o endereço de) um nó. Um descendente de X é qualquer nó que
possa ser alcançada pela iteração dos comandos X = X->esq e X= X->dir em
qualquer ordem. (É claro que esses comandos só podem ser iterados enquanto x for
diferente de NULL. Estamos supondo que NULL é de fato atingido mais cedo ou mais
tarde.)
Um nó x juntamente com todos os seus descendentes é uma árvore binária. Dizemos
que X é a raiz ( root ) da árvore. Se x tiver um pai, essa árvore é uma subárvore de
alguma árvore maior. Se x é NULL, a árvore é vazia.
Para qualquer nó X, X->esq é a raiz da subárvore esquerda de X e X->dir é a raiz
da subárvore direita de X.
c) Endereço de uma árvore e definição recursiva
O endereço de uma árvore binária é o endereço de sua raiz. É conveninente confundir
árvores com seus endereços: dizemos "considere a árvore r" em lugar de "considere a
árvore cuja raiz tem endereço r".
Essa convenção sugere a introdução do nome alternativo arvore para o tipo-de-dados
ponteiro-para-nó:
typedef no * arvore ; /* árvore */
A convenção permite formular a definição deárvore binária de maneira recursiva: um
objeto r é uma árvore binária se
1. r é NULL ou
2. r->esq e r->dir são árvores binárias.
d) Varredura esquerda-raiz-direita
Ao contrário de uma lista encadeada, uma árvore binária pode ser percorrida de
muitas maneiras diferentes. Uma maneira particularmente importante é a ordem
esquerda-raiz-direita. Na varredura e-r-d ( inorder traversal ), visitamos
1. a subárvore esquerda da raiz, em ordem e-r-d ;
2. depois a raiz;
3. depois a subárvore direita da raiz, em ordem e-r-d.
Na figura abaixo, os nós estão numeradas na ordem da varredura e-r-d.
/ \
/ \ / \
/ \ \
Exemplo uma função recursiva que faz a varredura e-r-d de uma árvore binária r :
<Recebe a raiz r de uma árvore binária.>
< Imprime os conteúdos dos nós em ordem e-r-d .>
Pilhas
Pilha,Feofiloff, Paulo, 18 Outrubro 2010 <http://www.ime.usp.br/~pf/ algoritmos/aulas/pilha.html> Acesso em 19 Novembro 2010
Árvore Binária
Árvore Binária, Feofiloff, Paulo, 18 Outubro 2010 <http:www.ime.usp.br/
~pf/algoritmos/aulas/bint.html> Acesso em 10 Novembro 2010