lista de exercícios de algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · lista de...

24
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

Upload: trinhkhanh

Post on 01-Dec-2018

247 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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

Page 2: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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.

Page 3: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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.

Page 4: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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.

Page 5: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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.

Page 6: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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);

}

Page 7: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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.

Page 8: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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.

Page 9: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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.

Page 10: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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.

Page 11: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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;

}

Page 12: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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;

}

Page 13: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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));

Page 14: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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++){

Page 15: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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;

}

Page 16: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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;

Page 17: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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;

Page 18: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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;

Page 19: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

}

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

Page 20: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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;

}

Page 21: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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;

}

Page 22: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

}

//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':

Page 23: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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

Page 24: Lista de Exercícios de Algoritmos e ... - del.ufrj.brheraldo/eel470_lista2_nova.pdf · Lista de Exercícios de Algoritmos e Estruturas de Dados Segunda Lista Universidade Federal

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.