Lista de Exercícios de Algoritmos e Estruturas de Dados

Propaganda
Lista de Exercícios de Algoritmos e Estruturas de Dados
Segunda Lista
Universidade Federal do Rio de Janeiro – UFRJ
Professor Heraldo L. S. de Almeida, D.Sc.
Monitor Carlos Eduardo Marciano
18/07/2016
Elaborada por Carlos Eduardo Marciano
Observações Iniciais
Esta disciplina é lecionada em linguagem C. Para todos os exemplos de código,
assuma que os devidos headers já estão inclusos. As respostas aqui encontradas não
são necessariamente as únicas possíveis.
Índice
1. Pilhas ---------------------------------------------------------------------- Pág. 2
2. Filas ------------------------------------------------------------------------ Pág. 4
3. Listas ---------------------------------------------------------------------- Pág. 6
4. Árvores ------------------------------------------------------------------- Pág. 9
A. Anexo A: Respostas --------------------------------------------------- Pág. 11
A.1 Pilhas ------------------------------------------------------------ Pág. 11
A.2 Filas -------------------------------------------------------------- Pág. 13
A.3 Listas ------------------------------------------------------------- Pág. 16
A.4 Árvores ---------------------------------------------------------- Pág. 21
B. Bibliografia -------------------------------------------------------------- Pág. 24
1. Pilhas
1.1) [Pilha sequencial] Projete uma estrutura do tipo pilha (stack/LIFO) sequencial de
10 espaços para guardar informações de páginas da web visitadas. Essas informações
estarão contidas na seguinte struct:
#define MAX 10
typedef struct{
char adress[30];
int connectionType;
}PageData;
Ao final do projeto, seu programa deve rodar as seguintes funções. Note que algumas
delas retornam um código de erro. O output pode ser visto na imagem abaixo:
Stack* inicializarPilha();
int push(Stack* pilha, char* adress, int connectionType);
int pop(Stack* pilha);
int main(){
int errorCode;
Stack* pilha;
pilha = inicializarPilha(); //Pilha criada
errorCode = push(pilha, "http://fisica4.if.ufrj.br", 2);
errorCode = push(pilha, "http://www.youtube.com", 2);
errorCode = push(pilha, "https://www.facebook.com", 1);
errorCode = pop(pilha);
errorCode = push(pilha, "https://drive.google.com", 1);
errorCode = pop(pilha);
errorCode = pop(pilha);
errorCode = pop(pilha);
}
a) Crie uma struct para abrigar a pilha e defina-a como tipo Stack. Essa struct
deve conter o array correspondente à LIFO e um int para guardar o topo da pilha.
b) Escreva a função inicializarPilha que aloca memória para a pilha.
c) Escreva a função push para adicionar um elemento à pilha. Se necessário,
utilize a função strcpy(char* destino, const char* origem), da biblioteca padrão, para
copiar strings.
d) Escreva a função pop para remover e mostrar o último endereço da pilha.
1.2) [Pilha encadeada] Projete uma estrutura do tipo pilha (stack/LIFO) encadeada
para guardar números do tipo int. Utilize o código inicial abaixo:
typedef struct Node{
int valor;
struct Node* pProx;
}Element;
A ideia é criar as funções declaradas abaixo que permitam a execução do seguinte
programa, resultando em um output similar ao da janela ao lado do código:
void printPilha(Element* inicio);
void push(Element** inicio, int valor);
int pop(Element** inicio);
int main(){
int dado;
Element* pilha = NULL; //Pilha criada
push(&pilha, 3);
push(&pilha, 2);
push(&pilha, 7);
push(&pilha, 5);
printPilha(pilha);
dado = pop(&pilha);
dado = pop(&pilha);
printPilha(pilha);
push(&pilha, 9);
printPilha(pilha);
}
a) Escreva a função printPilha para ler os itens da pilha.
b) Escreva a função push para adicionar um elemento à pilha.
c) Escreva a função pop para remover um elemento da pilha e retornar seu
valor associado.
2. Filas
2.1) [Fila sequencial] Projete uma estrutura do tipo fila (queue/FIFO) sequencial de 20
espaços para guardar requerimentos de impressão para uma empresa de fotocópias.
Essas informações estarão contidas na seguinte struct:
#define MAX 20
typedef struct{
int customerId;
double price;
}PrintingData;
Ao final do projeto, seu programa deve rodar as seguintes funções. Note que algumas
delas retornam um código de erro. O output pode ser visto na imagem abaixo:
Queue* inicializarFila();
int inserir(Queue* fila, int customerId, double price);
int remover(Queue* fila);
int main(){
int errorCode;
Queue* fila;
fila = inicializarFila(); //Fila criada
errorCode = inserir(fila, 1, 9.35);
errorCode = inserir(fila, 2, 5.45);
errorCode = inserir(fila, 3, 1.50);
errorCode = remover(fila);
errorCode = inserir(fila, 4, 3.40);
errorCode = remover(fila);
errorCode = inserir(fila, 5, 6.10);
errorCode = remover(fila);
errorCode = remover(fila);
errorCode = remover(fila);
}
a) Crie uma struct para abrigar a fila e defina-a como tipo Queue. Essa struct
deve conter o array correspondente à FIFO e um int para guardar o fim da fila.
b) Escreva a função inicializarFila que aloca memória para a fila.
c) Escreva a função inserir para adicionar um elemento à fila.
d) Escreva a função remover para extrair um elemento da fila e mostrar seu
conteúdo.
2.2) [Fila circular] Projete uma estrutura do tipo fila (queue/FIFO) circular de tamanho
variável para guardar o ID dos usuários que esperam, por ordem de chegada, para
comprar ingressos online para um dado show. O array users guarda IDs de clientes do
tipo int. A estrutura da fila, portanto, é a seguinte:
typedef struct{
int* users;
int inicio, fim;
int capacidade; //Tamanho total da fila
int count; //Numero de usuarios na fila
}CircQueue;
Ao final do projeto, seu programa deve rodar as seguintes funções. Note que algumas
delas retornam um código de erro. O output pode ser visto na imagem abaixo:
CircQueue* inicializarFila(int capacidade);
int inserir(CircQueue* fila, int userId);
int remover(CircQueue* fila);
int main(){
int errorCode;
CircQueue* fila;
fila = inicializarFila(3); //Fila criada
errorCode = inserir(fila, 12342);
errorCode = inserir(fila, 23511);
errorCode = inserir(fila, 35234);
errorCode = remover(fila);
errorCode = remover(fila);
errorCode = inserir(fila, 43692);
errorCode = inserir(fila, 54217);
errorCode = remover(fila);
errorCode = remover(fila);
errorCode = inserir(fila, 66234);
errorCode = remover(fila);
errorCode = remover(fila);
}
a) Escreva a função inicializarFila que aloca memória para a fila e para seu
array de elementos.
b) Escreva a função inserir para adicionar um usuário à fila.
c) Escreva a função remover para extrair um usuário da fila e permiti-lo
comprar seu ingresso.
3. Listas
3.1) [Lista Sequencial Ordenada] Projete uma estrutura do tipo lista sequencial
ordenada de 20 espaços para abrigar os inimigos ativos de um jogo de computador em
ordem crescente de dificuldade (com relação ao número de pontos de vida). A
estrutura que abriga essas informações é a seguinte:
#define MAX 20
typedef struct{
int vida;
double ataque;
}EnemyData;
Deve ser possível adicionar ou remover um inimigo da lista à medida que este nasce ou
é morto pelo jogador, através das funções e comandos abaixo:
OrdList* inicializarLista();
int inserir(OrdList* lista, int vida, double ataque);
int localizar(OrdList* lista, int vida);
int dealDamage(OrdList* lista, int vida);
int main(){
int errorCode;
OrdList* lista = inicializarLista(); //Lista criada
errorCode = inserir(lista, 100, 4.42);
errorCode = inserir(lista, 50, 9.67);
errorCode = inserir(lista, 200, 2.56);
errorCode = inserir(lista, 150, 8.45);
printLista(lista);
errorCode = dealDamage(lista, 100);
errorCode = dealDamage (lista, 150);
printLista(lista);
errorCode = dealDamage (lista, 50);
errorCode = dealDamage (lista, 200);
printLista(lista);
}
A função dealDamage é equivalente à função “remover”, porém adaptada ao jogo: se
um golpe de 100 pontos for desferido, o inimigo com esta vida deverá desaparecer. A
fim de facilitar seu projeto, utilize a seguinte função para mostrar na tela todos os
elementos da lista em um dado momento:
void printLista(OrdList* lista){
int i;
if (lista->count == 0){
printf("Lista vazia: nenhum inimigo ativo!\n\n");
} else {
printf("Conteudo da lista:\n");
for (i=0; i<lista->count; i++){
printf("-Inimigo %d com %.2f de vida.\n", lista>enemies[i].enemyId, lista->enemies[i].vida);
}
printf("\n");
}
}
a) Crie uma struct para abrigar a lista e defina-a como tipo OrdList. Essa struct
deve conter o array correspondente à lista e um int para guardar o número de
inimigos dentro da lista.
b) Escreva a função inicializarLista que aloca memória para a lista.
c) Escreva a função inserir para adicionar um inimigo à lista. Neste primeiro
momento, não há problema em inserir inimigos repetidos.
d) Escreva a função localizar que retorna a posição, de 0 a count-1, em que o
inimigo com dada vida se encontra na lista. Sua complexidade assintótica deve ser de
O(logn), ou seja: implemente a busca binária. Caso não seja encontrado inimigo
correspondente, a função retorna -1.
e) Modifique a função inserir para que, através de uma chamada à função
localizar, ela impeça a inserção de inimigos com vidas repetidas.
f) Escreva a função dealDamage que, utilizando a função localizar, remove da
lista um inimigo com a vida correspondente e comunica ao jogador o resultado.
3.2) [Lista Duplamente Encadeada] Projete uma estrutura do tipo lista
duplamente encadeada para abrigar os IDs dos usuários ativos em uma certa
aplicação. A estrutura de um nó da lista é a seguinte:
typedef struct Node{
int userId;
struct Node* pProx;
struct Node* pAnt;
}Element;
Ao final do projeto, seu programa deve rodar as seguintes funções. Note que algumas
delas retornam um código de erro. O output pode ser visto na imagem abaixo:
int inserir(Element** lista, int userId);
int remover(Element** lista, int userId);
void printLista(Element* lista);
int main(){
Element* lista = NULL; //Lista criada
int errorCode;
errorCode = inserir(&lista, 89);
errorCode = inserir(&lista, 45);
errorCode = inserir(&lista, 76);
errorCode = inserir(&lista, 21);
printlista(lista);
errorCode = remover(&lista, 21);
errorCode = remover(&lista, 89);
printlista(lista);
errorCode = inserir(&lista, 75);
printlista(lista);
}
a) Escreva a função inserir, que cria e insere um nó na primeira posição da lista
duplamente encadeada. Para simplificar o projeto, não se preocupe em casos de
inserção de um ID repetido.
b) Escreva a função printLista, que mostra na tela todos os IDs dos usuários
ativos num dado momento.
c) Escreva a função remover, que exclui um certo ID de usuário da lista e
mostra na tela o ID removido.
4. Árvores
4.1) [Árvore Binária de Busca] Projete uma estrutura do tipo Árvore Binária de Busca
para armazenar produtos de uma loja de conveniência. A árvore será ordenada pelo
número de matrícula dos produtos, que serão guardados na seguinte struct:
struct Produto{
int matricula;
float preco;
};
Ao final do projeto, você deve ser capaz de executar o seguinte código. O output
encontra-se na imagem abaixo:
int adicionar (No** arv, int matricula, float preco);
int preco(No** arv, int matricula);
int main(){
No* arv = NULL;
int errorCode;
errorCode = adicionar(&arv, 100, 5.90);
errorCode = adicionar (&arv, 200, 8.40);
errorCode = adicionar (&arv, 250, 2.20);
errorCode = adicionar (&arv, 500, 3.80);
errorCode = adicionar (&arv, 400, 5.60);
errorCode = adicionar (&arv, 150, 7.90);
errorCode = preco(&arv, 400);
errorCode = preco(&arv, 240);
errorCode = preco(&arv, 150);
}
a) Crie uma struct para abrigar um nó da árvore e defina-a como tipo No. Esta
struct deve conter um produto e os dois ponteiros correspondentes aos nós filhos.
b) Escreva a função adicionar, que cria e insere um nó na árvore binária,
indexando o produto pelo número de sua matrícula.
c) Escreva a função preco, que busca na árvore binária pelo número de
matrícula do produto desejado e imprime na tela seu preço correspondente.
4.2) [Ordem de Busca] Suponha que produtos com códigos 770, 875, 007, 059, 068,
682, 588, 067, 234, 411, 191 e 512 sejam inseridos, nesta ordem, em uma estrutura
vazia do tipo Árvore Binária de Busca.
a) Desenhe a árvore resultante (grafo) após a inserção de todos os itens,
representando o código do produto dentro de cada nó.
b) Determine em que sequência esses elementos seriam processados por um
algoritmo que execute um percurso em pré-ordem.
c) Determine em que sequência esses elementos seriam processados por um
algoritmo que execute um percurso em pós-ordem.
d) Determine em que sequência esses elementos seriam processados por um
algoritmo que execute um percurso em ordem simétrica.
A. Respostas
A.1 Pilhas
1.1) a)
typedef struct{
PageData itens[MAX];
int topo;
}Stack;
b)
Stack* inicializarPilha(){
Stack* pilha;
pilha = malloc(sizeof(Stack));
if (pilha == NULL){
printf("Erro ao inicializar pilha!\n\n");
}
pilha->topo = 0;
return pilha;
}
c)
int push(Stack* pilha, char* adress, int connectionType){
if (pilha == NULL){
printf("Pilha nao inicializada!\n\n");
return -1;
}
if (pilha->topo == MAX){
printf("Pilha cheia! Impossivel inserir\n\n");
return -2;
}
strcpy(pilha->itens[pilha->topo].adress, adress);
pilha->itens[pilha->topo].connectionType = connectionType;
pilha->topo++;
return 1;
}
d)
int pop(Stack* pilha){
if (pilha == NULL){
printf("Pilha nao inicializada!\n\n");
return -1;
}
if (pilha->topo == 0){
printf("Pilha vazia! Impossivel remover\n\n");
return -2;
}
pilha->topo--;
printf("Endereco removido: %s, conectado com tipo %d\n\n", pilha->itens[pilha>topo].adress, pilha->itens[pilha->topo].connectionType);
return 1;
}
1.2) a)
void printPilha(Element* inicio){
Element* temp = inicio;
if (temp == NULL){ //Caso de pilha vazia
printf("Pilha vazia!\n\n");
} else {
printf("Dados da pilha: ");
while (temp != NULL){
printf("%d, ", temp->valor); //Percorre a pilha
temp = temp->pProx;
}
printf("\b\b.\n\n");
}
}
b)
void push(Element** inicio, int valor){
Element* nextNode;
//Aloca e configura o novo elemento:
nextNode = malloc(sizeof(Element));
if (nextNode == NULL){
printf("Erro ao inicializar no!\n\n");
return;
}
nextNode->valor = valor;
//Faz a cirurgia na fila, adicionando na 1a posicao:
nextNode->pProx = *inicio;
*inicio = nextNode;
return;
}
c)
int pop(Element** inicio){
Element* temp;
temp = *inicio;
if (temp == NULL){ //Caso de pilha vazia
printf("Pilha vazia: nao ha nada a remover.\n\n");
return 0;
} else {
int valor = temp->valor;
*inicio = temp->pProx;
free(temp);
printf("Valor %d removido com sucesso.\n\n", valor);
return valor;
}
}
A.2 Filas
2.1) a)
typedef struct{
PrintingData itens[MAX];
int fim;
}Queue;
b)
Queue* inicializarFila(){
Queue* fila;
fila = malloc(sizeof(Queue));
if (fila == NULL){
printf("Erro ao inicializar fila!\n\n");
}
fila->fim = 0;
return fila;
}
c)
int inserir(Queue* fila, int customerId, double price){
if (fila == NULL){
printf("Fila nao inicializada!\n\n");
return -1;
}
if (fila->fim == MAX){
printf("Fila cheia! Impossivel inserir\n\n");
return -2;
}
fila->itens[fila->fim].customerId = customerId;
fila->itens[fila->fim].price = price;
fila->fim++;
return 1;
}
d)
int remover(Queue* fila){
if (fila == NULL){
printf("Fila nao inicializada!\n\n");
return -1;
}
if (fila->fim == 0){
printf("Fila vazia! Impossivel remover\n\n");
return -2;
}
fila->fim--;
printf("Imprimindo para cliente %d por R$%.2f.\n\n", fila->itens[0].customerId,
fila->itens[0].price);
int temp;
for (temp = 0; temp<(fila->fim); temp++){
fila->itens[temp] = fila->itens[temp+1];
}
return 1;
}
2.2) a)
CircQueue* inicializarFila(int capacidade){
CircQueue* fila;
fila = malloc(sizeof(CircQueue));
if (fila == NULL){
printf("Erro ao inicializar fila!\n\n");
}
fila->inicio = 0; //Inicio sempre marca o primeiro elemento ocupado
fila->fim = 0; //Fim sempre marca o proximo elemento vazio
fila->count = 0;
fila->capacidade = capacidade;
if (capacidade > 0) {
fila->users = malloc(capacidade*sizeof(*(fila->users)));
} else {
printf("Capacidade invalida!");
}
if (fila->users == NULL){
printf("Erro ao alocar espaço para a fila!\n\n");
}
return fila;
}
b)
int inserir(CircQueue* fila, int userId){
if (fila == NULL){
printf("Fila nao inicializada!\n\n");
return -1;
}
if (fila->count == fila->capacidade){
printf("Fila cheia! Impossivel inserir\n\n");
return -2;
}
fila->users[fila->fim] = userId;
fila->count++;
fila->fim++;
if (fila->fim == fila->capacidade){ //Caso em que indice saiu do array
fila->fim = 0;
}
return 1;
}
c)
int remover(CircQueue* fila){
if (fila == NULL){
printf("Fila nao inicializada!\n\n");
return -1;
}
if (fila->count == 0){ //Checagem de fila vazia
printf("Fila vazia! Impossivel remover\n\n");
return -2;
}
//Imprime o inicio da fila:
printf("Usuario %d autorizado a comprar.\n\n", fila->users[fila->inicio]);
fila->count--;
fila->inicio++;
//Se o inicio da fila estourou o array, volta com ele pro indice zero:
if (fila->inicio == fila->capacidade){
fila->inicio = 0;
}
return 1;
}
A.3 Listas
3.1) a)
typedef struct{
EnemyData enemies[MAX];
int count;
}OrdList;
b)
OrdList* inicializarLista(){
OrdList* lista;
lista = malloc(sizeof(OrdList));
if (lista == NULL){
printf("Erro ao inicializar lista!\n\n");
}
lista->count = 0;
return lista;
}
c)
int inserir(OrdList* lista, int vida, double ataque){
if (lista == NULL){
printf("Lista nao inicializada!\n\n");
return -1;
}
if (lista->count == MAX){
printf("Lista cheia! Impossivel inserir\n\n");
return -2;
}
//Busca comecando do fim. Se a vida do elemento i for maior, move este para a
direita:
int i;
for (i=(lista->count)-1; lista->enemies[i].vida>vida && i>=0; i--){
lista->enemies[i+1].vida = lista->enemies[i].vida;
lista->enemies[i+1].ataque = lista->enemies[i].ataque;
}
//Quebra o loop caso o elemento i tiver uma vida menor. Logo, precisamos inserir
em i+1:
lista->enemies[i+1].vida = vida;
lista->enemies[i+1].ataque = ataque;
//Incrementa o numero de itens da lista:
lista->count++;
return 1;
}
d)
int localizar(OrdList* lista, int vida) {
int i=0, f=(lista->count)-1, m, c;
while (i <= f) {
m = (i+f)/2;
c = lista->enemies[m].vida - vida;
if (c == 0){
return m;
} else if (c > 0) {
f = m-1;
} else {
i = m+1;
}
}
return -1;
}
Idealisticamente, seria bom que esta função já retornasse a posição de inserção
de um inimigo quando não encontrasse um resultado. Isto nos pouparia trabalho no
item seguinte, que pede uma modificação na função de inserir. Porém, para manter
certa simplicidade ao projeto, a função apenas retorna -1 nestes casos.
e) Após a checagem de lista cheia, insira as seguintes linhas:
if (localizar(lista, vida) != -1){
printf("Inimigo ja existente!\n\n");
return -3;
}
f)
int dealDamage(OrdList* lista, int vida){
if (lista == NULL){
printf("Lista nao inicializada!\n\n");
return -1;
}
if (lista->count == 0){
printf("Lista vazia! Impossivel dealDamage\n\n");
return -2;
}
//Busca pela posicao do inimigo:
int i = localizar(lista, vida);
if (i == -1){
printf("Nao acertou nenhum inimigo!\n\n");
return -3;
}
printf("Inimigo com %d de vida derrotado com sucesso!\n\n", lista>enemies[i].vida);
//Traz o restante da fila uma posicao para tras:
while (i<(lista->count-1)){
lista->enemies[i].vida = lista->enemies[i+1].vida;
lista->enemies[i].ataque = lista->enemies[i+1].ataque;
i++;
}
lista->count--;
return 1;
}
3.2) a)
int inserir(Element** lista, int userId){
Element *nextNode;
//Aloca o proximo elemento:
nextNode = malloc(sizeof(Element));
if (nextNode == NULL){
printf("Falha ao alocar proximo no!\n\n");
return -1;
}
nextNode->userId = userId;
//Faz com que nextNode aponte para o primeiro elemento:
if (*lista == NULL){
//Caso lista vazia
nextNode->pProx = NULL;
} else {
nextNode->pProx = *lista;
(*lista)->pAnt = nextNode;
}
//Torna nextNode o primeiro elemento da lista:
nextNode->pAnt = NULL;
*lista = nextNode;
return 1;
}
b)
void printLista(Element* lista){
Element* temp = lista;
if (temp == NULL){ //Caso de lista vazia
printf("Lista vazia!\n\n");
} else {
printf("Usuarios na lista: ");
while (temp != NULL){
printf("%d, ", temp->userId);
temp = temp->pProx; //Percorre a lista
}
printf("\b\b.\n\n");
}
}
c)
int remover(Element** lista, int userId){
Element* temp = *lista;
//Repete ate chegar no fim da fila:
while (temp != NULL){
//Testa se o usuario foi encontrado:
if (temp->userId == userId){
//Faz a cirurgia na lista:
if (temp->pAnt == NULL){
//Caso primeiro elemento da fila:
*lista = temp->pProx;
if (temp->pProx != NULL) temp->pProx->pAnt = NULL;
} else {
//Proxima linha somente ocorre se temp nao for o ultimo elemento:
if (temp->pProx != NULL) temp->pProx->pAnt = temp->pAnt;
temp->pAnt->pProx = temp->pProx;
}
printf("Usuario %d removido da lista.\n\n", userId);
free(temp);
return 1;
} else {
temp = temp->pProx;
}
}
printf ("Usuario nao encontrado para remocao!\n\n");
return -1;
}
A.4 A rvores
4.1) a)
typedef struct Elemento{
struct Produto produto;
struct Elemento* esq;
struct Elemento* dir;
}No;
b)
int adicionar(No** arv, int matricula, float preco){
No* newNode;
//Aloca memoria para o no:
newNode = malloc(sizeof(No))
if (newNode == NULL){
printf("Falha ao alocar novo no!\n\n");
return -1;
}
//Configura os dados do no:
newNode->produto.matricula = matricula;
newNode->produto.preco = preco;
newNode->esq = NULL;
newNode->dir = NULL;
//Checa se a arvore esta vazia e, se sim, adiciona o no:
if (*arv == NULL){
*arv = newNode;
return 1;
}
//Procura onde adicionar o elemento:
No* atual = *arv;
No* anterior = atual;
while (atual != NULL){
anterior = atual;
if (atual->produto.matricula > matricula){
//Indo pelo no da esquerda
atual = atual->esq;
} else {
//Indo pelo no da direita
atual = atual->dir;
}
}
//Saimos do loop para estabelecer se o no anterior deve apontar para esquerda ou
para a direita. De quebra, ainda adicionamos uma checagem de produto repetido:
if (anterior->produto.matricula > matricula){
anterior->esq = newNode;
return 1;
} else if (anterior->produto.matricula < matricula){
anterior->dir = newNode;
return 1;
} else {
printf("Produto ja cadastrado!\n\n");
return -2;
}
}
c)
int preco(No** arv, int matricula){
//Checa se a arvore esta vazia:
if (*arv == NULL){
printf("Erro: Arvore vazia!\n\n");
return 0;
}
//Prepara para pesquisar na arvore:
No* atual = *arv;
No* anterior = atual;
while (atual->produto.matricula != matricula){
anterior = atual;
if (atual->produto.matricula > matricula){
//O percurso segue pelo no esquerdo
atual = atual->esq;
} else if (atual->produto.matricula < matricula){
//O percurso segue pelo no direito
atual = atual->dir;
}
//Caso em que chegamos em um no inexistente e portanto o item nao foi
encontrado:
if (atual == NULL){
printf("Erro: Produto %d nao encontrado!\n\n", matricula);
return 0;
}
}
//Quando o loop quebra, o item foi encontrado e esta sendo apontado pela
variavel 'atual':
printf("O produto %d custa R$%.2f.\n\n", matricula, atual->produto.preco);
return 1;
}
4.2) a) O esquema representando a árvore pode ser visto abaixo:
b) Em pré-ordem, leríamos os elementos desta forma:
770 → 007 → 059 → 068 → 067 → 682 → 588 → 234 → 191 → 411 → 512 → 875
c) Em pós-ordem, leríamos os elementos desta forma:
067 → 191 → 512 → 411 → 234 → 588 → 682 → 068 → 059 → 007 → 875 → 770
d) Em ordem simétrica, leríamos os elementos desta forma:
007 → 059 → 067 → 068 → 191 → 234 → 411 → 512 → 588 → 682 → 770 → 875
B. Bibliografia


CORMEN, Thomas H.; LEISERSON, Charles E.; RIVEST, Ronald L.; STEIN, Clifford.
Algoritmos: Teoria e Prática. Tradução de: Introduction to Algorithms, 3rd ed.
Rio de Janeiro: Elsevier, 2012.
Slides do professor Heraldo L. S. de Almeida. Disponível em:
<http://www.del.ufrj.br/~heraldo/eel470.html>. Acessado em: 16/07/2016.
Download