Professional Documents
Culture Documents
Cincia da Computao
Estruturas de Dados
Listas de Exerccios
Paulo Costa
19 Agosto 2013
Sumrio
Parte 1 Listas de exerccios ........................................................................... 1
1.
Recurso ................................................................................................................. 1
2.
Abstrao de dados................................................................................................ 3
3.
Vetores ................................................................................................................... 4
4.
5.
6.
Complexidade....................................................................................................... 13
7.
Ordenao ............................................................................................................ 20
8.
rvores ................................................................................................................. 21
9.
Heaps .................................................................................................................... 26
Recurso ............................................................................................................... 32
2.
Abstrao de dados.............................................................................................. 34
3.
Vetores ................................................................................................................. 36
4.
5.
6.
Complexidade....................................................................................................... 42
7.
Ordenao ............................................................................................................ 54
8.
rvores ................................................................................................................. 55
9.
Heaps .................................................................................................................... 59
Exerccio 1.2
Escreva as funes a seguir. Todas tomam como entrada dois inteiros no negativos a e b (a, b 0).
a)
b)
c)
d)
Exerccio 1.3
Escreva a funo recursiva menorDigito que toma um inteiro no negativo e retorna o menor de
todos os seus dgitos. No use laos (for, while) nem declare variveis locais.
Exerccio 1.4
Escreva a funo recursiva maiorDigito que toma um inteiro no negativo e retorna o maior de todos
os seus dgitos. No use laos (for, while) nem declare variveis locais.
Exerccio 1.5
Tente reescrever as funes do exerccio 1.2 obedecendo todos os critrios abaixo:
a) No utilize qualquer operador aritmtico alm de incremento (++) ou decremento (--).
b) No passe qualquer parmetro alm dos dois operandos (a e b).
c) No declare qualquer varivel local, nem mesmo para o valor a ser retornado.
Se no for possvel obedecer todos para alguma funo, fornea uma soluo que viole s um critrio.
Exerccio 1.6
Escreva uma funo recursiva que toma um inteiro no negativo e retorna a soma de seus dgitos. No
use laos (for, while) nem variveis locais. Sugesto: n%10 produz o dgito mais direita de n, e
n/10 produz todos os dgitos de n exceto aquele mais direita.
Exerccio 1.7
Escreva uma funo recursiva que toma um inteiro no negativo e retorna a quantidade de dgitos que
ele contm. No use laos (for, while) nem declare variveis locais.
Exerccio 1.8
Calcule o nmero de adies necessrias para computar
iterativo e recursivo implementados a seguir:
Ai(n)
Ar(n)
(int n) {
f1=0, f2=1, f3=0;
= 2; i <= n; i++) {
f1 + f2; f1 = f2; f2 = f3;
1
2
(f3);
4
5
6
7
8
9
10
Exerccio 1.9
O mximo divisor comum (MDC) de dois inteiros
mdc (x,y).
Exerccio 1.10
Justifique por que, no exerccio 1.5, possvel escrever algumas funes, mas no todas, obedecendo
aos trs critrios propostos.
Exerccio 1.11
Um problema clssico de backtracking o seguinte: dado um conjunto de inteiros, possvel escolher
um subconjunto tal que a soma de seus elementos seja igual a um resultado desejado? Essa estratgia
recursiva pode ser usada para resolver outros problemas que envolvem busca em um espao de
opes.
Escreva a funo recursiva
Bool SomaSubconjunto (int inicio, int *numeros, int totNumeros, int soma)
onde
inicio
numeros
2. Abstrao de dados
Exerccio 2.1
Defina o tipo de dados abstrato Complexo. A estrutura dos nmeros complexos :
um nmero real (p.ex. float, double ou RACIONAL) representando a parte real
um nmero real representando o coeficiente da parte imaginria.
Defina os mtodos cria_complexo, soma, mult e igual. Lembre que a multiplicao de complexos
feita de forma distributiva, ou seja:
Exerccio 2.2
Defina o tipo de dados abstrato Vetor. Um vetor v no espao cartesiano bidimensional pode ser
definido por um par ordenado (a,b) onde a e b so nmeros reais, como na Figura 1 abaixo.
Defina tambm os mtodos abaixo com os seguintes parmetros:
Mtodo
Parmetros
Resultado
cria_vetor
modulo
produto
angulo
iguais
float, float
vetor
vetor, vetor
vetor, vetor
vetor, vetor
vetor
float
float
float
true ou false
Figura 1
Figura 2
= (a,b) e w = (c,d)
y de v. Note
Exerccio 2.3
Considere os seguintes tipos de dados em C e seus respectivos tamanhos em bytes:
Tipo de dado
char
short int
int
double
Tamanho
1 byte
2 bytes
4 bytes
8 bytes
char:
short int:
int:
double:
A B C D 1 2 3 A
16961 17475 12849 16691
1145258561 1093874225
1258033.266651
Naturalmente os nmeros impressos devero refletir os caracteres da sequncia; se fosse usada outra
sequncia de caracteres, a sada do programa seria diferente.
3. Vetores
Exerccio 3.1
Considere uma tabela de notas de uma turma, onde cada linha contm um par de nmeros: matrcula
do aluno (do tipo inteiro) e sua nota (do tipo real). Escreva um programa que leia essa tabela e calcule:
a) a mdia da turma;
b) quantos alunos obtiveram nota acima da mdia;
c) quantos alunos obtiveram nota igual mdia;
d) quantos alunos obtiveram nota abaixo da mdia;
e) a maior nota e quantos alunos a obtiveram.
Exerccio 3.2
O imperador romano Csar usava um sistema simples para criptografar as mensagens que enviava aos
seus generais. Nesse sistema, cada letra era substituda por trs letras frente no alfabeto.
Sua tarefa semelhante, porm mais simples. Escreva um programa que converta cada letra, e
somente as letras, de uma mensagem de at n caracteres para a letra imediatamente posterior. Note
que z deve ser convertido para a e Z para A.
Exerccio 3.3
Palndromos so palavras que podem ser lidas igualmente nas duas direes, como ARARA, RADAR e
ANILINA. Note que AMORA no um palndromo, ainda que AROMA seja uma palavra vlida.
Escreva uma funo ehPalindromo que recebe um ponteiro para a 1 letra de uma palavra e o
nmero de letras, e retorna um booleano (TRUE=1 ou FALSE=0) indicando se a palavra um
palndromo. No use recurso; a funo deve ser iterativa.
Sugesto: Primeiro leia os caracteres da palavra e armazene-os em um vetor, depois verifique se tratase de um palndromo.
Exerccio 3.4
Considere duas sequncias A e B, cada uma com at 8 nmeros inteiros entre 0 e 9 inclusive. Escreva
um programa que interprete A e B como nmeros inteiros, some-os, e produza uma nova sequncia C
contendo os dgitos da soma. Exemplo:
A: 9 8 7 6
B: 9 8 7
C: 1 0 8 6 3
Exerccio 3.5
Considere duas sequncias ordenadas A e B com at n letras de a a z, por exemplo:
A= g i i i m r t
B= d g g i i k o o t
Escreva um programa que, dadas as sequncias ordenadas A e B, gere 4 sequncias ordenadas com
a) a unio de A e B, com repeties.
Exemplo: d g g g i i i i i k m o o r t t
Exemplo: d g i k m o r t
Exerccio 3.6
Escreva um programa que, dado um conjunto de at max nmeros inteiros, calcule a mdia, mediana e
moda dos nmeros. O tamanho do conjunto, n, deve ser fornecido pelo usurio em tempo de execuo.
A mediana e a moda de um conjunto de n nmeros so assim definidas:
Se n for mpar, a mediana o nmero m tal que metade dos demais nmeros m e a outra
metade m. Se n for par, a mediana a mdia entre m1 e m2 tal que metade dos demais
nmeros m1 e a outra metade m2.
A moda o nmero que ocorre com maior frequncia. Se mais de um nmero ocorre com a
mesma frequncia mxima, ento a moda no est definida. Seu programa deve indicar quando
esse caso ocorrer.
Sugesto: Teste o programa com conjuntos de tamanho par e mpar.
Exerccio 3.7
Modifique o cdigo do exerccio 3.3 de modo que a funo seja recursiva.
Exerccio 3.8
Escreva uma funo que, dada uma matriz quadrada de nmeros inteiros, retorna o caractere
S
I
D
X
Exerccio 3.9
Modifique o programa do exerccio 3.5 para que aceite sequncias desordenadas. Em nenhum
momento ordene as sequncias de entrada.
Paulo Costa 2013
Exerccio 3.10
Modifique o programa do exerccio 3.9 para aceitar sequncias desordenadas de qualquer coisa
inteiros, nmeros decimais (float ou double), caracteres, estruturas, etc.
Sugestes:
Coloque o cdigo de clculo de unio e interseo em funes separadas.
Use um #define para definir o tipo de dado contido nas sequncias.
Para determinar o tamanho desse tipo de dado, utilize a funo sizeof() da biblioteca de C.
Para comparar valores de tipo e tamanho arbitrrios, use a funo memcmp() da biblioteca de C.
4. Listas encadeadas
Exerccio 4.1
Considere uma lista simplesmente encadeada com a seguinte estrutura:
struct nodo {
int dado;
struct nodo* prox;
};
Escreva a funo RemoveUltimo que
recebe um ponteiro para a lista L,
remove o ltimo nodo de L, e
no retorna nada.
A funo deve funcionar corretamente em todos os casos, incluindo:
lista vazia,
lista com um nico nodo,
lista com dois nodos, e
lista com n nodos.
Exerccio 4.2
Considere uma lista simplesmente encadeada com a mesma estrutura do exerccio 4.1. Escreva a
funo MoveParaInicio que
recebe um ponteiro para a lista L e o inteiro N,
caso N se encontre em um ou mais nodos de L, move os nodos contendo N para o incio de L, e
retorna um booleano indicando se N encontra-se ou no em L; suponha que o tipo Bool j existe
e que pode assumir os valores TRUE ou FALSE.
Essa funo deve manipular apenas ponteiros, ou seja, no deve criar nodos com malloc() nem
destru-los com free(). Alm disso, a funo deve funcionar corretamente em todos os casos,
incluindo:
lista vazia,
lista com um nico nodo contendo N,
lista com um nico nodo no contendo N,
lista com dois nodos, nenhum deles contendo N,
lista com dois nodos, apenas um contendo N,
lista com dois nodos, ambos contendo N,
lista com n nodos, nenhum deles contendo N,
lista com n nodos, apenas um contendo N, e
lista com n nodos, vrios contendo N, mas no todos, e
lista com n nodos, todos contendo N.
Exerccio 4.3
Considere a funo
int Tamanho (struct nodo* lista)
que recebe um ponteiro para uma lista linear (veja figura no exerccio 4.7) e retorna o nmero de nodos
da lista. Uma forma de implementar essa funo consiste em percorrer toda a lista contando o nmero
de nodos visitados. Uma implementao alternativa envolve o uso de uma varivel global
static int tamLista
Assim, ao invs de percorrer toda a lista contando o nmero de nodos, a funo Tamanho() apenas
retorna o valor armazenado em tamLista.
Responda as seguintes perguntas:
1)
2)
3)
4)
Por que tamLista deve ser global? Por que no pode ser local a Tamanho()?
Por que tamLista declarada como static?
Quais as vantagens dessa implementao alternativa?
Quais as desvantagens?
Exerccio 4.4
Considere uma lista duplamente encadeada com a seguinte estrutura:
struct nodo {
char letra;
struct nodo* antes;
struct nodo* depois;
};
Escreva a funo ehPalindromo que
recebe dois ponteiros para a lista L (um para o incio e outro para o fim de L),
determina se a palavra formada pelas letras em L um palndromo (veja o exerccio 3.3), e
retorna um booleano indicando se trata-se ou no de um palndromo; suponha que o tipo Bool j
existe e que pode assumir os valores TRUE ou FALSE.
A funo deve ser iterativa (ou seja, no use recurso). Alm disso, a funo deve funcionar
corretamente em todos os casos, incluindo:
lista vazia,
lista com um nico nodo,
lista com dois nodos contendo letras iguais,
lista com dois nodos contendo letras diferentes,
lista com trs, quatro e n nodos contendo um palndromo, e
lista com trs, quatro e n nodos contendo um no-palndromo.
Exerccio 4.5
Implemente a verso recursiva da funo ehPalindromo do exerccio anterior.
Exerccio 4.6
Considere a funo mostrada a seguir, que opera sobre uma lista linear simplesmente encadeada com
a mesma estrutura do exerccio 4.1. O objetivo da funo remover o nodo inicial de uma lista novazia e retornar o dado nele contido. Suponha que tDado , nodo , dado e prox j foram definidos.
Essa funo realiza corretamente a operao esperada? Justifique.
Exerccio 4.7
Uma lista circular simplesmente encadeada uma lista linear onde o ltimo nodo aponta de volta para o
primeiro. A lista linear acessada atravs de um ponteiro para o primeiro nodo; a circular, atravs de
um ponteiro para o ltimo nodo. Isso permite um acesso fcil a ambas as extremidades da lista circular.
Lista linear
Lista circular
incio
fim
Considere uma lista linear L e uma lista circular C, ambas simplesmente encadeadas e com a mesma
estrutura do exerccio 4.1.
1) Escreva a funo TornaCircular que
recebe um ponteiro para a lista linear L,
transforma L em uma lista circular, e
no retorna nada.
2) Escreva a funo TornaLinear que faz o oposto da funo anterior.
3) Escreva a funo TamanhoCircular que
recebe um ponteiro para a lista circular C,
conta o nmero de nodos em C, e
retorna esse nmero.
As trs funes acima devem funcionar corretamente em todos os casos, incluindo:
lista vazia,
lista com um nico nodo,
lista com dois nodos, e
lista com n nodos.
A funo acima deve executar em tempo constante, independente do tamanho de C e D. Alm disso, a funo deve
funcionar corretamente em todos os casos, incluindo as 16
combinaes ao lado.
Nodos em D
0
Nodos em C
0
1
2
n
Exerccio 4.8
Considere uma lista simplesmente encadeada com a mesma estrutura do exerccio 4.1, onde os todos
os inteiros esto entre 0 e 9 inclusive.
1) Escreva a funo ListaParaInt que
recebe um ponteiro para a lista L,
interpreta os nmeros em L como dgitos de um long unsigned int, e
retorna o nmero resultante.
Suponha que o dgito mais significativo esteja no incio da lista, e que o nmero final pode ser
armazenado em um long unsigned int sem causar overflow.
A funo deve funcionar corretamente em todos os casos, incluindo:
lista vazia (nesse caso a funo deve retornar 0),
lista com um nico nodo,
lista com dois nodos, e
lista com n nodos.
2) Escreva a funo IntParaLista que faz o oposto da funo acima, ou seja:
recebe um inteiro N do tipo unsigned long int,
coloca cada um dos dgitos decimais de N em uma lista L, e
retorna um ponteiro para o incio de L.
Exerccio 4.9
Considere uma lista circular L duplamente encadeada,
como na figura ao lado.
*fim
Exerccio 4.10
A funo ao lado opera sobre uma lista
simplesmente encadeada com a mesma
estrutura do exerccio 4.1. O que faz essa
funo?
Exerccio 4.11
A funo abaixo opera sobre uma lista simplesmente encadeada com a mesma estrutura do exerccio
4.1. O que faz essa funo?
void funcaoRecursiva (struct nodo** lista) {
struct nodo* primeiro;
struct nodo* resto;
if (*lista == NULL)
return;
primeiro = *lista;
resto = primeiro->prox;
if (resto == NULL)
return;
funcaoRecursiva (&resto);
primeiro->prox->prox = primeiro;
primeiro->prox = NULL;
*lista = resto;
}
poePilha
tiraPilha
topoPilha
tamPilha
pilhaVazia
(char letra)
(void)
(void)
(void)
(void)
Exerccio 5.2
Projete duas pilhas de caracteres utilizando um nico vetor V de tamanho n, de modo que
poePilha
tiraPilha
topoPilha
tamPilha
pilhaVazia
Exerccio 5.3
Escreva uma funo Bool ehPalindromo (void) que determina se uma palavra um palndromo
(veja a lista L2, Exerccio 3.3). As letras da palavra so obtidas com a funo char obtemLetra
(void), que retorna uma letra de cada vez, enquanto houver letras sem serem lidas. Se no houver
mais letras, uma chamada a obtemLetra causa erro. Para evitar esse erro, use a funo Bool
acabaramAsLetras (void). Note que a palavra s pode ser lida uma vez; no possvel recomear
do incio da palavra.
10
H trs tipos de estruturas de dados disponveis, mas apenas uma de cada tipo: uma pilha, uma fila e
um deque; todas armazenam caracteres. Voc pode usar as estruturas em qualquer combinao, ou
seja: apenas uma das trs, ou duas delas, ou todas as trs. Para utiliz-las, chame as funes de
acesso descritas abaixo.
Implemente apenas a funo ehPalindromo, sem usar recurso. Suponha que todas as demais j
existam. Suponha tambm que o tipo Bool j existe, e que pode assumir os valores TRUE ou FALSE.
Pilha
void
char
char
int
Bool
Fila
poePilha
tiraPilha
topoPilha
tamPilha
pilhaVazia
(char letra)
(void)
(void)
(void)
(void)
void
char
char
int
Bool
Deque
poeFila
tiraFila
frenteFila
tamFila
filaVazia
(char letra)
(void)
(void)
(void)
(void)
void
void
char
char
char
char
int
Bool
poeInicioDeque
poeFimDeque
tiraInicioDeque
tiraFimDeque
inicioDeque
fimDeque
tamDeque
dequeVazio
(char letra)
(char letra)
(void)
(void)
(void)
(void)
(void)
(void)
Sugestes:
Use o projeto de Dev-C++ chamado ehPalindromo que acompanha esta lista de exerccios. Esse
projeto contm todo o cdigo de suporte necessrio realizao do exerccio. Abra o arquivo
ehPalindromo.c e escreva seu cdigo na funo ehPalindromo(). No altere mais nada no
cdigo fornecido. Se o programa compilar e funcionar corretamente, ento sua implementao
provavelmente estar correta.
Exerccio 5.4
Imagine um deque implementado atravs de um array circular A de tamanho TAM de modo que
elementos adicionados ao final do deque ocupam posies crescentes no array, enquanto elementos
adicionados ao incio do deque ocupam posies decrescentes no array. Por exemplo:
inicio
fim
Deque
Incio da execuo
[- - - -]
-1
-1
Incio-> <-Fim
[1 - - -]
Incio-> 1 <-Fim
[1 2 - -]
Incio-> 1 2 <-Fim
[1 2 - 3]
Incio-> 3 1 2 <-Fim
[1 2 4 3]
Incio-> 4 3 1 2 <-Fim
[1 - 4 3]
Incio-> 4 3 1 <-Fim
Na tabela acima, inicio e fim so variveis inteiras com os ndices do array A correspondentes ao
incio e fim do deque. Indique se a parte principal de poeNoInicio(n) pode ser escrita em
pseudocdigo como:
decrementar inicio
se inicio < 0
inicio = TAM 1
A[inicio] = n
incrementar inicio
se inicio TAM
inicio = 0
A[inicio] = n
se inicio = = TAM 1
inicio = 1
incrementar inicio
A[inicio] = n
se inicio = = 0
inicio = TAM
decrementar inicio
A[inicio] = n
( ) Sim
( ) Sim
( ) Sim
( ) Sim
( ) No
( ) No
( ) No
( ) No
Exerccio 5.5
Para cada afirmao a seguir, indique se verdadeira (V) ou falsa (F). Em todos os casos, justifique.
11
) Ao implementar um deque atravs de uma lista encadeada com dois ponteiros de acesso (incio
e fim da lista), consideramos duas opes: a) usar uma lista circular simplesmente encadeada, e
b) usar uma lista linear duplamente encadeada. Dessas, a opo b mais eficiente.
) Uma boa estrutura de dados para se implementar uma fila um array circular com compactao
aps cada remoo.
) Se usarmos uma lista linear duplamente encadeada para implementar uma fila, tanto faz termos
apenas um ponteiro para o incio ou para o final da lista; em qualquer caso, inseres e
remoes da fila levaro tempo O(1).
Exerccio 5.6
Implemente uma fila atravs de duas pilhas.
Pressupostos:
1)
2)
3)
4)
Restries:
1)
2)
3)
4)
5)
Pilha
void
tDado
tDado
int
Bool
Fila
poePilha
tiraPilha
topoPilha
tamPilha
pilhaVazia
void
tDado
tDado
int
Bool
poeFila
tiraFila
frenteFila
tamFila
filaVazia
(tDado dado)
(void)
(void)
(void)
(void)
Sugestes:
Use o projeto Dev-C++ filaComPilhas que acompanha esta lista de exerccios. O projeto contm todo
o cdigo de suporte necessrio realizao do exerccio. Abra o arquivo fila.c e escreva seu cdigo
nas funes a serem implementadas. No altere mais nada no cdigo fornecido.
filaComPilhas uma modificao do projeto ehPalindromo. O cdigo em filaComPilhas.c testa a
funcionalidade da fila em uma aplicao simples: verificao se palavras digitadas pelo usurio so
palndromos. Se o programa compilar e funcionar corretamente, ento sua implementao da fila
provavelmente estar correta.
Exerccio 5.7
Implemente um deque atravs de duas pilhas.
Pressupostos:
1)
2)
3)
4)
Restries:
1)
2)
3)
4)
5)
12
Pilha
void
tDado
tDado
int
Bool
Deque
poePilha
tiraPilha
topoPilha
tamPilha
pilhaVazia
void
void
tDado
tDado
tDado
tDado
int
Bool
poeInicioDeque
poeFimDeque
tiraInicioDeque
tiraFimDeque
inicioDeque
fimDeque
tamDeque
dequeVazio
(tDado dado)
(tDado dado)
(void)
(void)
(void)
(void)
(void)
(void)
Exerccio 5.8
Implemente uma pilha atravs de uma fila. Suponha que o tipo de dado a ser armazenado (tdado) e os
mtodos de acesso fila j foram previamente implementados.
Restries:
1) O nmero total de variveis usadas em todos os mtodos no pode ser maior que trs.
2) Use apenas os mtodos de acesso fila e os comandos de C que julgar convenientes.
3) No use recurso.
Mtodos a serem usados
void
tDado
tDado
int
Bool
void
tDado
tDado
int
Bool
poeFila
tiraFila
frenteFila
tamFila
filaVazia
(tDado dado)
(void)
(void)
(void)
(void)
poePilha
tiraPilha
topoPilha
tamPilha
pilhaVazia
(tDado dado)
(void)
(void)
(void)
(void)
Exerccio 5.9
Considere uma fila implementada em um vetor V no-circular de tamanho n, de modo que o primeiro
item colocado na fila seja armazenado em V[0], o prximo em V[1] etc. Ao retirarmos itens da fila, a
frente da fila passa a estar em V[1], V[2] etc., criando espaos vazios no incio do vetor. Pode-se evitar
esse desperdcio compactando o vetor ou seja, deslocando a fila para baixo no vetor -- de modo que
a frente da fila volte a estar em V[0]. Essa compactao pode ser feita em momentos distintos:
1) aps cada remoo da fila,
2) antes de cada insero na fila, ou
3) antes de uma insero quando o fim da fila j chegou ao final do vetor, ou seja, V[n].
Para cada um desses mtodos:
Discuta suas vantagens e desvantagens.
Escreva as funes de acesso fila incorporando o respectivo mtodo de compactao.
6. Complexidade
Exerccio 6.1
Liste as limitaes da anlise experimental de complexidade de algoritmos.
Exerccio 6.2
A anlise terica de complexidade de algoritmos utiliza os conceitos de melhor caso, caso mdio e pior
caso. Liste trs motivos pelos quais a anlise do caso mdio pode ser problemtica.
Exerccio 6.3
Liste trs limitaes do modelo RAM de computao.
13
Exerccio 6.4
Para cada uma das operaes descritas abaixo, fornea o tempo de execuo no pior caso. Use a
notao O grande, por exemplo, T( n) = O(log(n)). Suponha que todas as operaes bsicas sejam
realizadas em tempo constante.
1) Busca de um dado em array desordenado com n posies.
2) Busca binria de um dado em array ordenado com n posies.
3) Busca de um dado em uma matriz quadrada com n linhas e colunas.
n
4) Clculo de c usando apenas multiplicaes.
Exerccio 6.5
Coloque as funes abaixo em ordem crescente de complexidade assinttica. Atribua 1 para a funo
de menor complexidade e 8 para a funo de maior complexidade.
2
10n (log n)
3
B. ( ) n
3
C. ( ) 100 (log n)
2
3
D. ( ) n (log n)
A. (
4
10 log n
3 2
F. ( ) 10 n
E. (
G. (
300n log n
n
H. ( ) 2
Exerccio 6.6
Coloque as funes abaixo em ordem crescente de complexidade assinttica. Atribua 1 para a funo
de menor complexidade e 8 para a funo de maior complexidade.
3 2
10 n
n
B. ( ) 2
2
3
3 2
C. ( ) 10 n (10 log 10 n)
3
2
D. ( ) 10 n log 10 n
A. (
3
2
2 3
10n (10 log 10 n)
3
F. ( ) 10n
6
5
4 3
G. ( ) 10 (10 log 10 n)
8
9
H. ( ) 10 log 10 n
E. (
Exerccio 6.7
Coloque as funes abaixo em ordem crescente de complexidade assinttica. Atribua 1 para a funo
de menor complexidade e 10 para a funo de maior complexidade.
A. (
B. (
C. (
D. (
E. (
3
10n
2
3
10 n log 10 n
3 2
10 n
3
3 2
10 n log (10 n )
2
2
2 3
10n (10 log 10 n)
F. (
8
9
10 log 10 n
3
2
2 2
H. ( ) 10n (10 log 10 n)
6
5
4 3
I. ( ) 10 (10 log 10 n)
2
3
3 2
J. ( ) 10 n (10 log 10 n)
G. (
Exerccio 6.8
Verdadeiro ou falso:
01. (
02. (
Se
Se
(
)
03.
Se
04. ( ) Se
05. ( ) Se
14
06. (
07. (
08. (
09. (
10. (
11. (
12. (
13. (
14. (
15. (
16. (
17. (
18. (
19. (
20. (
Se
Se
Se
Se
Se
Se
Se
Se
Se
Se
Se
Se
Se
Se
Se
Exerccio 6.9
Considere a definio de O(g(n)) a seguir:
Exerccio 6.10
Para cada um dos trechos de cdigo abaixo, fornea o tempo de execuo no pior caso. Use a notao
O grande, por exemplo,
. Suponha que todas as variveis so inteiras.
Trecho 1
Trecho 2
Trecho 3
for (i=0;i<n;i+=2)
soma++;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
soma++;
for (i=0;i<n;i++)
soma++;
for (j=0;j<n;j++)
soma++;
Trecho 4
Trecho 5
Trecho 6
for (i=0;i<n;i++)
for (j=0;j<n*n;j++)
soma++;
for (i=0;i<n;i++)
for (j=0;j<i;j++)
soma++;
for (i=0;i<n;i++)
for (j=0;j<n*n;j++)
for (k=0;k<j;k++)
soma++;
Trecho 7
Trecho 8
Trecho 9
for (i=0;i<n/2;i++)
for (j=0;j<i/2;j++)
soma++;
for (i=0;i<n;i++)
for (j=0;j<LOG(i);j++)
soma++;
for (i=0;i<LOG(n);i++)
soma++;
for (j=0;j<n;j++)
soma++;
Trecho 10
Trecho 11
Trecho 12
for (i=0;i<LOG(n);i++)
for (j=0;j<i;j+=2)
soma++;
for (i=0;i<n;i++)
for (j=0;j<i*i;j++)
for (k=0;k<LOG(j);k++)
soma++;
for (i=0;i<n;i++)
for (j=0;j<LOG(i);j++)
for (k=0;k<j;k++)
soma++;
15
Exerccio 6.11
Pilha
Para cada estrutura de dados nas tabelas a seguir, fornea o tempo de execuo no pior caso das
operaes de insero (INS) e remoo (REM) de elementos. Utilize a notao O grande.
Implementao
Variveis disponveis
Array
Lista linear
simplesmente
encadeada
10
Lista linear
duplamente
encadeada
Lista circular
simplesmente
encadeada
Lista circular
duplamente
encadeada
INS
REM
13
Array circular
14
Lista linear
simplesmente
encadeada
15
16
17
18
19
20
21
22
23
24
25
Lista linear
duplamente
encadeada
Fila
12
Lista circular
simplesmente
encadeada
Lista circular
duplamente
encadeada
26
ndice do topo de cada pilha
16
Exerccio 6.12
Considere o Bubble Sort, cujo pseudocdigo est listado abaixo. Determine o nmero de operaes
primitivas executadas em cada linha do pseudocdigo e calcule o nmero total, tanto para o melhor
caso quanto para o pior caso.
Algoritmo: bubbleSort (A, n)
Entrada: array A com n elementos
Sada: array A em ordem crescente
1) para i de 0 at n-1 passo 1 faa
2)
para j de n-1 at i+1 passo -1 faa
3)
se A[j-1] > A[j] ento
4)
temp = A[j-1]
5)
A[j-1] = A[j]
6)
A[j] = temp
Linha
Melhor caso
Pior caso
1
2
3
4
5
6
Total
Exerccio 6.13
Considere o Insertion Sort, cujo pseudocdigo est listado abaixo. Determine o nmero de operaes
primitivas executadas em cada linha do pseudocdigo e calcule o nmero total, tanto para o melhor
caso quanto para o pior caso.
Algoritmo: insertionSort (A, n)
Entrada: array A com n elementos
Sada: array A em ordem crescente
1)
2)
3)
4)
5)
6)
7)
Linha
Melhor caso
Pior caso
1
2
3
4
5
6
7
Total
Exerccio 6.14
Considere o Selection Sort, cujo pseudocdigo est listado abaixo. Determine o nmero de operaes
primitivas executadas em cada linha do pseudocdigo e calcule o nmero total, tanto para o melhor
caso quanto para o pior caso.
Algoritmo: selectionSort (A, n)
Entrada: array A com n elementos
Sada: array A em ordem crescente
1) para i de 0 at n-2 faa
2)
para j de i+1 at n-1 faa
3)
se A[j] < A[min] ento
4)
temp = A[i]
5)
A[i] = A[min]
6)
A[min] = temp
Linha
Melhor caso
Pior caso
1
2
3
4
5
6
Total
17
Exerccio 6.15
Existem dois algoritmos para resolver certo problema, cujos tempos de execuo so dados por:
Algoritmo 1
Algoritmo 2
Exerccio 6.16
Existem dois algoritmos para resolver certo problema, cujos tempos de execuo so dados por:
Algoritmo 1
Algoritmo 2
Exerccio 6.17
Existem dois algoritmos para resolver certo problema, cujos tempos de execuo so dados por:
Algoritmo 1
Algoritmo 2
3
2
n (a + b + c) n + (ab + bc + ac) n (abc)
onde a, b e c so as razes reais.
Exerccio 6.18
Considere a definio de (g(n)) a seguir:
18
Exerccio 6.19
3
Considere a definio de (g(n)) no exerccio 6.18. Considere tambm a funo f (n) = 10n 300n +
2000n. Use o mtodo analtico discutido em aula para responder as seguintes perguntas:
3) Se usarmos c1=5 e c2=20, qual o menor valor inteiro de n0 que permite provar que f (n) = (n )?
Dados: 5 = 2,24 e 17 = 4,12.
Exerccio 6.20
3
Considere a definio de (g(n)) no exerccio 6.18. Considere tambm a funo f (n) = 8n 300n +
40n. Utilize as informaes nos grficos fornecidos para responder as perguntas a seguir. Fornea suas
respostas na forma de intervalos, por exemplo (0, 10]. Justifique as respostas de 1 a 6.
1) Qual a faixa de valores de n0 que satisfazem a definio de para quaisquer c1 e c2 0?
2) Qual a faixa de valores de c1 que satisfazem a definio de ?
3) Qual a faixa de valores de c2 que satisfazem a definio de ?
Considere agora que c1, c2, n e n0 so nmeros inteiros positivos (ou seja, maiores que zero).
4)
5)
6)
7)
8)
Grfico 1
T(n)
f '(n) = 8
300/n
Grfico 2
T(n)
4/n2
-1 103
-2 103
200
10
15
20
25
30
35
40
45
(37.36, 0)
-4
40
(42.7, 0)
12
-200
300n
1 103
16
-400
T1(n) = 7n2
400
600
800
-3 103
-4 103
19
7. Ordenao
Exerccio 7.1
O que um algoritmo de ordenao estvel? O que um algoritmo de ordenao in place?
Exerccio 7.2
Caracterize o melhor e o pior caso do Quick Sort.
Exerccio 7.3
Diferencie o melhor e o pior caso do Merge Sort e justifique.
Exerccio 7.4
1) O tempo de execuo do Merge Sort igual para o melhor caso e o pior caso? Justifique.
2) O tempo de execuo do Quick Sort igual para o melhor caso e o pior caso? Justifique.
Exerccio 7.5
Descreva os principais mtodos de escolha do piv no Quick Sort. Para cada um, comente sobre seu
impacto na eficincia da ordenao.
Exerccio 7.6
Complete a tabela abaixo, fornecendo a complexidade assinttica dos vrios algoritmos de ordenao.
Algoritmo
Tempo
Pior caso
Caso mdio
Melhor caso
Bubble sort
Bubble sort modificado
Selection sort
Insertion sort
Heap sort
Merge sort
Quicksort
Exerccio 7.7
Verdadeiro ou falso:
01. (
02. (
) Os algoritmos de ordenao estveis incluem o Merge Sort, o Quick Sort e o Bubble Sort.
03. (
) Heap Sort pode ser feito in place, mas mais simples e intuitivo se usa um heap separado.
04. (
05. (
) Selection Sort uma variao do FP-Sort (FP = Fila de Prioridades) onde a fila de
) O Merge Sort pode ser implementado tanto de forma recursiva como de forma iterativa.
07. (
) O Merge Sort, o Heap Sort e o Insertion Sort executam em tempo O(n log n).
08. (
) O tempo de execuo do Merge Sort igual para o melhor caso e o pior caso.
09. (
) O tempo de execuo do Quick Sort igual para o melhor caso e o pior caso.
20
8. rvores
Exerccio 8.1
Considere as duas rvores binrias a seguir.
rvore 1
rvore 2
A
A
B
D
1)
2)
3)
4)
5)
6)
F
J
G
K
C
E
J
I
N
G
K
L
Q
prefixado.
infixado.
posfixado.
prefixado.
infixado.
posfixado.
Exerccio 8.2
1)
2)
3)
4)
5) Qual o tempo de execuo do caminhamento de Euler sobre uma rvore binria prpria com
altura h? Justifique.
n ns e
Exerccio 8.3
Considere a expresso prefixada a seguir, onde todos os operadores so binrios:
3 1
6 2 7
Exerccio 8.4
Considere a expresso infixada a seguir, onde todos os operadores so binrios:
(8
((27)4))(((56)3)1)
Exerccio 8.5
Considere a expresso posfixada a seguir, onde todos os operadores so binrios:
5 7
8 2 4 6
21
Exerccio 8.6
O caminhamento prefixado de uma rvore binria visita seus ns na seguinte ordem:
A B D H M N E I O C F J K P G L Q R
O caminhamento infixado da mesma rvore binria visita seus ns na seguinte ordem:
M H N D B I O E A J F P K C G Q L R
O caminhamento posfixado da mesma rvore binria visita seus ns na seguinte ordem:
M N H D O I E B J P K F Q R L G C A
Desenhe a rvore.
Exerccio 8.7
O caminhamento prefixado de uma rvore binria visita seus ns na seguinte ordem:
A B D H M N I O E J P C F K Q G L R
O caminhamento infixado da mesma rvore binria visita seus ns na seguinte ordem:
M H N D I O B E J P A F K Q C G L R
O caminhamento posfixado da mesma rvore binria visita seus ns na seguinte ordem:
M N H O I D P J E B Q K F R L G C A
Desenhe a rvore.
Exerccio 8.8
Considere a expresso prefixada a seguir, onde todos os operadores so binrios:
L G K
X J
C Q A
Exerccio 8.9
Considere a expresso infixada a seguir, onde todos os operadores so binrios:
( ( ( E
C )
H )
( ( G
D )
F ) ) )
Exerccio 8.10
Considere a expresso posfixada a seguir, onde todos os operadores so binrios:
8 1 4 9 7
3 8
Exerccio 8.11
Verdadeiro ou falso:
01. (
02. (
03. (
04. (
05. (
22
06. (
07. (
08. (
09. (
) Nem toda rvore binria quase completa uma rvore binria prpria.
10. (
Exerccio 8.12
Seja:
G
eg
ig
ng
hg
G
o nmero de nodos internos de G
o nmero total de nodos de G
a altura de G
o nmero de nodos externos de
P
ep
ip
np
hp
P
o nmero de nodos internos de P
o nmero total de nodos de P
a altura de P
o nmero de nodos externos de
Verdadeiro ou falso:
01. (
02. (
03. (
04. (
05. (
06. (
07. (
08. (
2hp + 1 np
hp+1
np 2
1
hp + 1 ep
hp
ep 2
hp
hp ip 2 1
ng = 2eg 1
hg
1 eg 2
hg
hg ig 2 1
Exerccio 8.13
Considere uma rvore A com raiz r e um total de n ns. Define-se o ancestral comum mais prximo
entre dois ns n e m ou ACMP(n,m) como o n mais baixo de A (ou seja, o n mais distante de r) que
tem ambos n e m como descendentes. Um n pode ser considerado descendente de si mesmo.
Escreva uma funo em C que recebe ponteiros para dois ns como entrada e retorna um ponteiro
para o ACMP entre eles. Suponha que a funo pai j exista; abaixo, seu prottipo:
/* ENTRADA: ponteiro para um n
*/
/* SADA:
ponteiro para seu pai, ou NULL se o n a raiz */
pNo *pai (tNo *pNo);
Abaixo, o prottipo da funo ACMP que voc deve escrever:
pNo *ACMP (tNo *pN1, tNo *pN2);
23
Exerccio 8.14
A figura a seguir mostra vrios vetores, cada um implementando uma rvore binria diferente.
0
1
2
3
4
5
6
7
8
6
3
8
30
4
60
4
30
7
8
16
14
8
28
8
14
9
6
14
46
7
92
7
46
15
11
22
10
11
10
19
18
21
9
42
11 9
21
18
16
20
38
10
76
10
38
10
11
12
13
11 13 17 21
10 12 15 20
32 34 24 36
16
16 17 12 18
24
16 17 12 18
15
19
17
40
26
20
52
20
26
13
28
35
14
62
14
31
18
14
15
16
17
23 24
41
13
19 21
88
13 19 21
44
Vetor
rvore...
binria
prpria?
binria
completa?
binria quase
completa?
de busca
binria?
1
2
3
4
5
6
7
8
Exerccio 8.15
Descreva um mtodo usando o caminhamento de Euler para calcular o nmero de descendentes de
cada n em uma rvore binria. possvel armazenar informaes nos ns, se necessrio. Qual o
tempo de execuo desse algoritmo?
Exerccio 8.16
4
3
7
2
24
( 5
( 4
( 3
1 ) ) )
( 8
( ( 6
2 )
7 ) )
Exerccio 8.17
Considere a rvore de busca binria na figura a seguir.
100
54
163
27
71
10
6
40
19
31
133
66
49
59
86
68
80
115
97
198
150
180
223
Exerccio 8.18
Considere a rvore de busca binria na figura a seguir.
100
54
163
27
71
10
6
40
19
31
133
66
49
59
86
68
80
115
97
198
150
180
223
Exerccio 8.19
Considere uma rvore binria ordenada A cujos nodos possuem a seguinte estrutura:
struct nodo {
int dado;
struct nodo* menor;
struct nodo* maior;
};
25
rvore vazia,
rvore com um nico nodo,
rvore com dois nodos, e
rvore com n nodos.
As figuras a seguir mostram uma rvore antes e depois de ser transformada numa lista.
Antes
Depois
9. Heaps
Exerccio 9.1
Um heap uma rvore binria que armazena uma coleo de chaves em seus nodos e que satisfaz
duas propriedades adicionais: uma relacional e outra estrutural. Explique essas propriedades.
Exerccio 9.2
Para cada uma das rvores abaixo, indique se ela um heap ou, caso contrrio, qual propriedade
violada. Use a seguinte marcao nas suas respostas:
-
Hn
R
E
RE
Por exemplo, se a rvore no um heap porque viola apenas a propriedade estrutural, escreva
for um heap e a chave no seu ltimo n for 40, escreva H 40.
E. Se
26
rvore 1
rvore 2
rvore 3
11
10
18
20
14
16
11
10
13
12
rvore 4
17
14
16
19
20
19
20
21
12
17
18
7
9
10
20
13
18
14
11
16
10
21
17
19
9
12
18
10
20
14
14
12
9
16
20
13
19
21
4
8
14
16
rvore 9
6
16
23
20
13
10
11
18
12
16
rvore 6
rvore 8
11
15
rvore 7
12
13
10
18
4
7
11
17
16
rvore 5
12
15
17
17
18
11
10
17
14
19
9
12
18
10
20
14
16
13
21
rvore 10
3
8
11
12
23
6
19
15
20
16
17
13
10
18
24
Exerccio 9.3
Considere o heap mostrado na figura a seguir. Mostre a sequncia de transformaes feitas no heap ao
inserirmos um novo nodo com chave 8. Para cada etapa da sequncia, mostre tambm o contedo do
vetor utilizado para armazenar os nodos do heap.
12
15
18
21
29
24
28
0
30
26
35
40
33
10
11
12
13
12 15 18 21 29 24 28 30 26 35 40 33
27
Exerccio 9.4
Considere o heap mostrado na figura a seguir. Mostre a sequncia de transformaes feitas no heap ao
removermos um nodo. Para cada etapa da sequncia, mostre tambm o contedo do vetor utilizado
para armazenar os nodos do heap.
12
15
18
21
29
24
28
0
30
26
35
40
33
10
11
12
13
12 15 18 21 29 24 28 30 26 35 40 33
Exerccio 9.5
Considere a figura do exerccio 8.14, onde cada vetor implementa uma rvore binria diferente. Para
cada um, determine se a rvore correspondente um heap. Se for um heap, indique o ltimo n; se
no, indique qual a propriedade do heap violada. Use a seguinte marcao nas suas respostas:
-
Hn
R
E
RE
Por exemplo, se a rvore correspondente no um heap porque viola apenas a propriedade estrutural,
escreva E. Se for um heap e a chave no seu ltimo n for 40, escreva H 40.
Exerccio 9.6
Um heap dito crescente quando a chave em um n qualquer menor ou igual s chaves nos seus
filhos. Similarmente, o heap dito decrescente quando a chave em um n qualquer maior ou igual s
chaves nos seus filhos.
1) Em que posies de um heap crescente possvel encontrar a maior chave?
2) possvel armazenar 7 chaves distintas em um heap H de modo que um caminhamento
prefixado de H retorne as chaves em ordem crescente? Se a resposta for no, justifique. Se a
resposta for sim, o heap deve ser crescente, decrescente, ou pode ser de ambos os tipos?
Fornea como exemplo um heap contendo as chaves de 1 a 7.
3) possvel armazenar 7 chaves distintas em um heap H de modo que um caminhamento infixado
de H retorne as chaves em ordem crescente? Se a resposta for no, justifique. Se a resposta for
sim, o heap deve ser crescente, decrescente, ou pode ser de ambos os tipos? Fornea como
exemplo um heap contendo as chaves de 1 a 7.
4) possvel armazenar 7 chaves distintas em um heap H de modo que um caminhamento
psfixado de H retorne as chaves em ordem crescente? Se a resposta for no, justifique. Se a
resposta for sim, o heap deve ser crescente, decrescente, ou pode ser de ambos os tipos?
Fornea como exemplo um heap contendo as chaves de 1 a 7.
28
Exerccio 10.2
Liste quatro cdigos hash mais utilizados. Para cada um, fornea seu nome, uma breve descrio de
como funciona, e uma indicao dos tipos de chave s quais ele se adqua.
Exerccio 10.3
Liste duas funes de compresso mais utilizadas, seus nomes e suas expresses matemticas.
Exerccio 10.4
1) Algumas funes de compresso usam nmeros primos e a funo mdulo (% em C). Por que?
2) Na funo (ay + b) mod N, necessrio que a mod N 0. Por que?
Exerccio 10.5
1) O que uma coliso em uma tabela hash?
2) Existem duas estratgias principais para o tratamento de colises em tabelas hash. Para cada uma,
fornea seu nome, uma breve descrio de como funciona, e vantagens e desvantagens.
3) Qual estratgia para o tratamento de colises mais apropriado quando se desconhece o nmero
de itens a serem armazenados na tabela? Justifique.
Exerccio 10.6
1) Qual o tempo de execuo das operaes de busca, insero e remoo em uma tabela hash
no melhor caso?
no pior caso?
2) O que caracteriza o pior caso possvel para as operaes sobre uma tabela hash?
3) O principal fator que afeta o desempenho de uma tabela hash o chamado fator de carga. Defina
esse fator e explique como ele afeta o desempenho da tabela hash.
Exerccio 10.7
Considere a seguinte sequncia de chaves, a serem inseridas em uma tabela hash com 11 posies:
7, 12, 19, 29, 35, 42, 56, 67, 76, 89, 81
Considere tambm que a tabela usa a seguinte funo hash:
Exerccio 10.8
Idem ao exerccio anterior, exceto pelas chaves a serem inseridas:
89, 97, 76, 42, 19, 28, 50, 67, 35, 12, 7
Exerccio 10.9
Idem ao exerccio anterior, exceto pelas chaves a serem inseridas:
7, 21, 92, 6, 53, 24, 65, 76, 80, 91, 19
29
Exerccio 10.10
Idem ao exerccio anterior, exceto pelas chaves a serem inseridas:
9, 16, 32, 45, 69, 81, 94, 2, 26, 53, 19
Exerccio 10.11
Idem ao exerccio anterior, exceto pelas chaves a serem inseridas:
12, 44, 13, 88, 23, 94, 11, 39, 20, 16, 5
Exerccio 10.12
Idem ao exerccio anterior, exceto que tabela usa endereamento aberto e teste linear.
Exerccio 10.13
Uma tcnica de resoluo de colises em tabelas hash com endereamento aberto o hashing duplo.
Essa tcnica usa uma funo de hash secundrio d(k) e resolve colises colocando o item que colidiu
na primeira clula disponvel na srie (i + j d(k)) mod N para j = 0, 1, , N 1 onde N o
tamanho da tabela, k a chave do item que colidiu, e i a posio da tabela onde tentou-se inserir o item
que colidiu.
Considere uma tabela hash com 11 posies que usa as seguintes funes de hash:
Hash primrio:
Hash secundrio:
Mostre a tabela hash aps a insero das chaves indicadas abaixo, na ordem em que aparecem. Utilize
a tabela a seguir para facilitar os clculos.
1)
2)
3)
4)
5)
6)
7)
8)
42, 11, 37, 15, 60, 20, 89, 29, 82, 72, 52
15, 84, 32, 61, 75, 6, 1, 5, 18, 96, 28
24, 46, 53, 28, 70, 91, 40, 60, 85, 81, 22
31, 76, 15, 2, 44, 27, 86, 63, 9, 54, 93
41, 11, 37, 15, 60, 20, 89, 29, 82, 72, 58
18, 84, 32, 61, 75, 6, 1, 5, 18, 93, 31
42, 64, 35, 82, 7, 19, 27, 66, 58, 75, 11
30
(2k + 5) mod 11
k
0
10
20
30
40
50
60
70
80
90
5
7
3
4
1
1
10
5
8
2
6
6
4
3
2
7
0
4
9
1
1
11
21
31
41
51
61
71
81
91
7
6
5
3
3
7
1
4
10
1
8
5
6
2
4
6
2
3
0
7
2
12
22
32
42
52
62
72
82
92
9
5
7
2
5
6
3
3
1
7
10
4
8
1
6
5
4
2
2
6
3
13
23
33
43
53
63
73
83
93
0
4
9
1
7
5
5
2
3
6
1
3
10
7
8
4
6
1
4
5
4
14
24
34
44
54
64
74
84
94
2
3
0
7
9
4
7
1
5
5
3
2
1
6
10
3
8
7
6
4
5
15
25
35
45
55
65
75
85
95
4
2
2
6
0
3
9
7
7
4
5
1
3
5
1
2
10
6
8
3
6
16
26
36
46
56
66
76
86
96
6
1
4
5
2
2
0
6
9
3
7
7
5
4
3
1
1
5
10
2
7
17
27
37
47
57
67
77
87
97
7 (k mod 7)
8
7
6
4
4
1
2
5
0
2
9
6
7
3
5
7
3
4
1
1
8
18
28
38
48
58
68
78
88
98
10
6
8
3
6
7
4
4
2
1
0
5
9
2
7
6
5
3
3
7
9
19
29
39
49
59
69
79
89
99
1
5
10
2
8
6
6
3
4
7
2
4
0
1
9
5
7
2
5
6
31
Exerccio 1.2
Soma iterativa
int somaI (int a, int b) {
for ( ; b>0; b--)
a++;
return (a);
}
Multiplicao iterativa
int multI (int a, int b) {
int m;
for (m=0; b>0; b--)
m = somaI (m,a);
return (m);
}
Soma recursiva
int somaR (int a, int b) {
if (a==0) return (b);
if (b==0) return (a);
return (somaR (++a, --b));
}
Multiplicao recursiva
/* Essa funo apenas passa o terceiro */
/* parmetro para a funo recursiva
*/
int multR (int a, int b) {
return (multRaux (a, b, 0));
}
/* Clculo recursivo propriamente dito */
int multRaux (int a, int b, int m) {
if (a==0 || b==0) return (m);
return (multRaux (a, --b, somaR(m,a)));
}
Exerccio 1.3
int menorDigito (int n) {
if (n<=9) return (n);
return ((n%10) <= menorDigito (n/10) ? (n%10) : menorDigito (n/10));
}
Exerccio 1.4
int maiorDigito (int n) {
if (n==0) return (0);
return ((n%10) >= maiorDigito (n/10) ? (n%10) : maiorDigito (n/10));
}
Paulo Costa 2013
32
Exerccio 1.5
As funes de soma (somaI e somaR) na soluo anterior j obedecem todos os critrios do exerccio.
As funes de multiplicao no podem obedecer todos os critrios ao mesmo tempo; ao menos um
deve ser violado. Em multI o critrio c foi violado; em multR o critrio b foi violado.
Uma implementao alternativa de multR, que viola o critrio a, dada abaixo:
int multR (int a, int b) {
if (a==0 || b==0) return (0);
if (a==1) return (b);
if (b==1) return (a);
return (a + multR (a, --b));
}
Exerccio 1.6
int somaDigitos (int n) {
if (n==0) return (0);
return ((n%10) + somaDigitos (n/10));
}
Exerccio 1.7
int totalDigitos (int n) {
if (n<10) return (1);
return (1 + totalDigitos (n/10));
}
Exerccio 1.8
n
Ai(n)
Ar(n)
12
20
33
54
10
88
33
Exerccio 1.9
MDC recursivo
MDC iterativo
Exerccio 1.11
Bool SomaSubconjunto (int inicio, int *numeros, int totNumeros, int soma) {
// Caso base:
// se no h mais nmeros, ento s h uma soluo se soma 0
if (inicio >= totNumeros)
return (soma == 0);
// Idia principal: ou numeros[inicio] usado, ou no .
// Trate numeros[inicio] explicitamente, e deixe a recurso
// tartar o resto do array.
// Chamada recursiva para tratar o caso de numeros[inicio] ser usado;
// no esquea de subtra-lo de soma na chamada recursiva
if (SomaSubconjunto (inicio+1, numeros, totNumeros, soma-numeros[inicio]))
return (TRUE);
// Chamada recursiva para tratar o caso de numeros[inicio] no ser usado
if (SomaSubconjunto (inicio+1, numeros, totNumeros, soma))
return (TRUE);
// Se as tentativas acima falharam, ento no possvel obter a soma
return (FALSE);
}
2. Abstrao de dados
Exerccio 2.1
Definio do TDA Complexo
Define-se complexo como dois nmeros reais onde um deles a parte real e o outro o coeficiente
da parte imaginria
a = areal + i aimaginrio
Usando a notao de vetor: a = <a[0],a[1]> onde
34
a e b como
a e b como
a e b como
Exerccio 2.2
Especificao do TDA Vetor
abstract typedef <float,float> VETOR;
abstract VETOR cria_vetor (float a, float b);
precondition
(a <> 0) OR (b <> 0);
postcondition
cria_vetor[O] = a;
cria_vetor[1] = b;
abstract float modulo (VETOR v);
postcondition
modulo = SQRT (v[O]*v[0] + v[1]*v[1]);
abstract float produto (VETOR v, VETOR w);
postcondition
produto = v[O]*w[O] + v[1]*w[1];
abstract float angulo (VETOR v, VETOR w);
postcondition
angulo = ACOS (produto(v,w) / (modulo(v) * modulo(w)));
abstract boolean iguais (VETOR v, VETOR w);
postcondition
iguais = (v[0] == w[0]) AND (v[1] == w[1]);
35
Exerccio 2.3
int main (void) {
union {
char
short int
int
double
}
u;
c [8];
si[4];
i [2];
d;
int k;
u.c[0]
u.c[2]
u.c[4]
u.c[6]
=
=
=
=
'A';
'C';
'1';
'3';
u.c[1]
u.c[3]
u.c[5]
u.c[7]
=
=
=
=
'B';
'D';
'2';
'A';
3. Vetores
Exerccio 3.3
#define
#define
#define
#define
TAM_MAX
Bool
TRUE
FALSE
100
int
1
0
36
Exerccio 3.5
#define TAM_MAX
15
#define POS_VAZIA 0
char A [TAM_MAX],
B [TAM_MAX],
C [TAM_MAX];
void uniaoComRep (char *letraA, char *letraB, char *letraC) {
while ((*letraA != POS_VAZIA) && (*letraB != POS_VAZIA))
*letraC++ = (*letraA <= *letraB ? *letraA++ : *letraB++);
while (*letraA != POS_VAZIA)
*letraC++ = *letraA++;
while (*letraB != POS_VAZIA)
*letraC++ = *letraB++;
}
void uniaoSemRep (char *letraA, char *letraB, char *letraC) {
while ((*letraA != POS_VAZIA) && (*letraB != POS_VAZIA))
if (*letraA == *letraC)
letraA++;
else if (*letraB == *letraC)
letraB++;
else {
if (*letraC != POS_VAZIA)
letraC++;
if (*letraA <= *letraB)
*letraC = *letraA++;
else
*letraC = *letraB++;
}
while (*letraA != POS_VAZIA) {
if (*letraA != *letraC) {
if (*letraC != POS_VAZIA)
letraC++;
*letraC = *letraA;
}
letraA++;
}
while (*letraB != POS_VAZIA) {
if (*letraB != *letraC) {
if (*letraC != POS_VAZIA)
letraC++;
*letraC = *letraB;
}
letraB++;
}
}
void intersecaoComRep (char *letraA, char *letraB, char *letraC) {
while ((*letraA != POS_VAZIA) && (*letraB != POS_VAZIA))
if (*letraA == *letraB) {
*letraC = *letraA; letraA++; letraB++; letraC++;
}
else if (*letraA <= *letraB)
letraA++;
else
letraB++;
}
void intersecaoSemRep (char *letraA, char *letraB, char *letraC) {
while ((*letraA != POS_VAZIA) && (*letraB != POS_VAZIA))
if (*letraA == *letraB) {
if (*letraA != *letraC) {
if (*letraC != POS_VAZIA)
letraC++;
*letraC = *letraA;
}
letraA++;
letraB++;
}
else if (*letraA <= *letraB)
letraA++;
else
letraB++;
}
37
Exerccio 3.7
#define
#define
#define
#define
TAM_MAX
Bool
TRUE
FALSE
100
int
1
0
4. Listas encadeadas
Exerccio 4.1
void RemoveUltimo (struct nodo **lista) {
struct nodo *penultimo, *ultimo;
if (*lista == NULL)
return;
/* Lista vazia: */
/* no faa nada */
if (*lista->prox == NULL) {
free (*lista);
*lista = NULL;
return;
}
/*
/*
/*
/*
/*
Lista
com
um
nico
nodo
*/
*/
*/
*/
*/
penultimo = *lista;
ultimo = penultimo->prox;
while (ultimo->prox != NULL) {
penultimo = ultimo;
ultimo = ultimo->prox;
}
free (ultimo);
penultimo->prox = NULL;
/*
/*
/*
/*
/*
/*
/*
/*
Lista
com
dois
ou
mais
nodos
*/
*/
*/
*/
*/
*/
*/
*/
Exerccio 4.3
1) Porque se fosse local a Tamanho(), ela no seria visvel pelas funes que precisam modific-la
ao adicionar ou remover nodos.
Paulo Costa 2013
38
2) Porque isso garante que tamLista mantm seu valor entre chamadas a Tamanho(). Sem o
modificador static, a varivel tamLista perderia seu valor anterior, tendo um valor aleatrio
(lixo) em cada chamada a Tamanho().
3) A funo Tamanho() no precisa percorrer a lista inteira para calcular seu tamanho, o que levaria
tempo O(n). Basta retornar o valor de tamLista, o que levaria tempo O(1).
4) Qualquer adio ou remoo de nodos na lista deve atualizar o valor de tamLista. Isso diminui a
mantenibilidade do cdigo, ao misturar funes distintas em vrias pores do cdigo.
Exerccio 4.6
A funo no realiza corretamente a operao esperada. O problema est na definio do parmetro,
que um ponteiro para o incio da lista. Esse parmetro passado por valor, mas deveria ser passado
por referncia. Como est, a funo realiza a operao corretamente, mas no capaz de atualizar o
ponteiro que foi passado para a funo; a modificao efetuada na lista perdida quando a funo
retorna. Ao final da funo, a lista original permanece como estava antes da chamada da funo.
Exerccio 4.7
struct nodo *TornaLinear (struct nodo *fim) {
struct nodo *inicio;
if (fim == NULL)
return (NULL);
inicio = fim->prox;
fim->prox = NULL;
return (inicio);
}
struct nodo *TornaCircular (struct nodo *inicio) {
struct nodo *fim;
if (inicio == NULL)
return (NULL);
fim = inicio;
while (fim->prox != NULL)
fim = fim->prox;
fim->prox = inicio;
return (fim);
}
void UneCirculares (struct nodo **fim1, struct nodo **fim2) {
struct nodo *inicio;
if (*fim2 == NULL)
return;
if (*fim1 != NULL) {
inicio = *fim1->prox;
*fim1->prox = *fim2->prox;
*fim2->prox = inicio;
}
*fim1 = *fim2;
*fim2 = NULL;
}
Exerccio 4.9
A funo transforma a lista circular em uma lista linear.
Exerccio 4.10
A funo inverte a lista de entrada.
Exerccio 4.11
A funo inverte a lista de entrada.
39
Exerccio 5.4
Sim. No. No. Sim.
Exerccio 5.5
( V ) a: remoo do incio, insero no incio e insero no final executam em tempo O(1); remoo do
final executa em tempo O(n). b: as quatro operaes executam em tempo O(1).
( F ) Se o array circular, no faz sentido falar-se em compactao. Mesmo que fizesse, nunca
haver desperdcio de espao aps remoes da fila; as compactaes no serviriam para nada,
consumindo tempo desnecessariamente.
( F ) Se a lista linear, o fato de ser simplesmente ou duplamente encadeada irrelevante. Apenas
um ponteiro para o incio da lista (frente da fila) resulta em remoo em tempo O(1) e insero
em tempo O(n); apenas um ponteiro para o final da lista (fim da fila) resulta em insero em
tempo O(1) e remoo em tempo O(n).
Exerccio 5.6
/* Insere dado no fim da fila */
40
Exerccio 5.7
Soluo 1
/* Poe dado no inicio do deque */
Soluo 2
/* Poe dado no inicio do deque */
41
Exerccio 5.8
/* Insere dado na pilha */
6. Complexidade
Exerccio 6.1
necessrio implementar o algoritmo, o que pode ser difcil ou oneroso.
Se as entradas analisadas forem tendenciosas, os resultados sero enganadores.
Para comparar dois algoritmos, devem-se replicar as condies experimentais (mesmo hardware
e mesmo ambiente de execuo).
Exerccio 6.2
Pode ser difcil caracterizar o caso mdio.
Exige prvio conhecimento da distribuio de probabilidades das diferentes entradas,
normalmente desconhecida.
O clculo da expresso matemtica resultante freqentemente de tratamento complexo.
Muitas vezes o caso mdio quase to ruim quanto o pior caso.
Exerccio 6.3
Exerccio 6.4
1)
2)
3)
4)
5)
Exerccio 6.5
A
42
Exerccio 6.6
A
Exerccio 6.7
A
10
Exerccio 6.8
1
10
11
12
13
14
15
16
17
18
19
20
Exerccio 6.9
2
Exerccio 6.10
Trecho 1
Trecho 2
Trecho 3
Trecho 4
Trecho 5
Trecho 6
Trecho 7
Trecho 8
Trecho 9
Trecho 10
Trecho 11
Trecho 12
Exerccio 6.11
Insero Remoo
Insero Remoo
Insero Remoo
Insero Remoo
15
22
16
23
10
17
24
11
18
25
12
19
26
13
20
27
14
21
43
Exerccio 6.12
Algoritmo: bubbleSort (A, n)
Entrada: array A com n elementos
Sada: array A em ordem crescente
1) para i de 0 at n-1 passo 1 faa
2)
para j de n-1 at i+1 passo -1 faa
3)
se A[j-1] > A[j] ento
4)
temp = A[j-1]
5)
A[j-1] = A[j]
6)
A[j] = temp
Linha
Melhor caso
Pior caso
2n + 3
2n + 3
n + 3n
2n 2n
2n 2n
3 n (n 1) / 2
2n 2n
n n
Total
3n + 3n + 3
(15n 3n + 6) / 2
n + 3n
2
2
j varia
de n 1
at i + 1
0
1
2
n2
n1
1
2
3
n1
n
Iterao
do para
na linha 1
primeira
segunda
terceira
penltima
ltima
Total
Paulo Costa 2013
o decremento de j
na linha 2: n i 1
o comando se
na linha 3
n0 n
n1
n2
n (n 2) 2
n (n 1) 1
1 +2+ + n
2
n (n + 1) / 2 (n + n) / 2
n01 n1
n11 n2
n21 n3
n (n 2) 1 1
n (n 1) 1 0
0 +1+ + n 1
2
(n n) / 2
n1
n2
n3
1
0
(n n) / 2
44
Exerccio 6.13
Algoritmo: insertionSort (A, n)
Entrada: array A com n elementos
Sada: array A em ordem crescente
1)
2)
3)
4)
5)
6)
7)
Linha
Melhor caso
Pior caso
2n + 1
2n + 1
2n 2
2n 2
2n 2
2n 2
4n 4
2n + 2n 4
2n 2n
n n
3n 3
Total
13n 10
2
2
3n 3
2
5n + 8n 10
45
Iterao do
para na linha 1
primeira
segunda
ltima
j varia de
at
1
2
n1
0
1
n2
1
1
Total
2
2
3
n
2 +3+ + n
n (n + 1) / 2 1
2
(n + n 2) / 2
1
2
n1
1 +2+ + n 1
n (n + 1) / 2 n
2
(n n) / 2
46
Exerccio 6.14
Algoritmo: selectionSort (A, n)
Entrada: array A com n elementos
Sada: array A em ordem crescente
Linha
Melhor caso
Pior caso
2n + 1
2n + 1
n + 3n 4
2
n + 3n 4
2
3/2 n 3/2 n
3/2 n 3/2 n
n n
3/2 n 3/2 n
n n
Total
(5n 7n 6) / 2
6n 3
penltima
ltima
j varia
de i + 1
at n 1
0
1
2
n3
n2
1
2
3
n2
n1
Total
o decremento de j
na linha 3: n i 1
o comando se
na linha 4
n0n
n1
n2
n (n 3) 3
n (n 2) 2
2 +3+ + n
2
(n + n) / 2 1
n01 n1
n11 n2
n21 n3
n (n 3) 1 2
n (n 2) 1 1
1 + + n 1
2
(n n) / 2
n1
n2
n3
2
1
(n n) / 2
2
47
Exerccio 6.15
Devemos comparar os tempos de execuo dos algoritmos a fim de determinar se existe pelo menos
um tamanho de entrada n para o qual ambos executam no mesmo tempo. Para isso, igualamos T1(n) e
T2(n) e calculamos a raiz do polinmio resultante:
2
2
T1(n) = T2(n) n 100n + 4000 = 20n + 2000 n 120n + 2000 = 0 n1 = 20 e n2 = 100
As duas razes reais indicam que a reta T2 corta a parbola T1 em dois pontos. O coeficiente do termo
de mais alta ordem de T1 positivo, de forma que seu grfico uma parbola com a concavidade
voltada para cima. Isso significa que, entre n1 e n2 , T1 menor do que T2. Em outras palavras:
T2 T1 para n 20
T1 T2 para 20 n 100
T2 T1 para n 100
Como n representa o tamanho da entrada, temos que n no pode ser negativo. Assim, conclumos que:
o algoritmo 2 mais rpido que o algoritmo 1 para entradas de tamanho menor que 20,
os dois algoritmos executam no mesmo tempo para entradas de tamanho igual a 20,
o algoritmo 1 mais rpido que o algoritmo 2 para entradas de tamanho entre 20 e 100,
os dois algoritmos executam no mesmo tempo para entradas de tamanho igual a 100, e
o algoritmo 2 mais rpido que o algoritmo 1 para entradas de tamanho maior que 100.
Exerccio 6.16
Devemos comparar os tempos de execuo dos algoritmos a fim de determinar se existe pelo menos
um tamanho de entrada n para o qual ambos executam no mesmo tempo. Para isso, igualamos T1(n) e
T2(n) e calculamos as razes do polinmio resultante:
2
2
T1(n) = T2(n) n 600n + 150 000 = 2n 1 200n + 200 000
2
n 600n + 50 000 = 0
n1 = 100 e n2 = 500.
Paulo Costa 2013
48
As duas razes reais indicam que as parbolas T1 e T2 se cruzam em dois pontos. Os coeficientes dos
termos de mais alta ordem de T1 e de T2 so ambos positivos, de forma que seus grficos so
parbolas com concavidades voltadas para cima. Para determinarmos se T1 menor ou maior que T2
entre n1 e n2 , calculamos T1(n) e T2(n) para um n qualquer nesse intervalo, por exemplo n = 200:
2
T1(200) = 200 600200 + 150 000 = 70 000
2
T2(200) = 2200 1 200200 + 200 000 = 40 000
T1 T2 para n 100
T2 T1 para 100 n 500
T1 T2 para n 500
As concluses acima podem ser obtidas a partir dos grficos de T1(n) e T2(n):
T(n)
2.0 105
1.5 105
1.0 105
(100, 105)
(500, 105)
5.0 104
n
100
200
300
400
500
600
Como n representa o tamanho da entrada, temos que n no pode ser negativo. Assim, conclumos que:
o algoritmo 1 mais rpido que o algoritmo 2 para entradas de tamanho menor que 100,
os dois algoritmos executam no mesmo tempo para entradas de tamanho igual a 100,
o algoritmo 2 mais rpido que o algoritmo 1 para entradas de tamanho entre 100 e 500,
os dois algoritmos executam no mesmo tempo para entradas de tamanho igual a 500, e
o algoritmo 1 mais rpido que o algoritmo 2 para entradas de tamanho maior que 500.
Exerccio 6.17
Devemos comparar os tempos de execuo dos algoritmos a fim de determinar se existe pelo menos
um tamanho de entrada n para o qual ambos executam no mesmo tempo. Para isso, igualamos T1(n) e
a + b + c = 60
ab + bc + ac = 1100
abc = 6000
49
A soluo algbrica desse sistema de equaes simples, mas trabalhosa. Uma alternativa observar
que as trs razes (a, b e c) provavelmente so mltiplos de 10 mas menores que 100, j que a soma
das trs tem um zero e seu produto tem trs zeros. Usando trs variveis auxiliares x, y e z e fazendo
x = a / 10 , y = b / 10 e z = c / 10 ,
obtemos
x+y+z=6
xy + yz + xz = 11
xyz = 6
Da pode-se facilmente deduzir que
x=1,y=2 e z=3,
de modo que
a = 10 , b = 20 e c = 30.
O fato das trs razes serem reais indica que as curvas de T1 e de T2 se cruzam em trs pontos. O
coeficiente do termo de mais alta ordem de T2 positivo, de forma que seu grfico uma parbola com
a concavidade voltada para cima. O coeficiente do termo de mais alta ordem de T1 tambm positivo,
de forma que seu grfico pode ser representado esquematicamente como se v a seguir:
T(n)
1400
1200
1000
4700
1300
(30, 1000)
(10, 1000)
(20, 900)
800
600
400
200
n
5
10
15
20
25
30
35
T1 T2 para n 10
T2 T1 para 10 n 20
T1 T2 para 20 n 30
T2 T1 para n 30
Como n representa o tamanho da entrada, temos que n no pode ser negativo. Portanto:
o algoritmo 1 mais rpido que o algoritmo 2 para entradas de tamanho menor que 10,
os dois algoritmos executam no mesmo tempo para entradas de tamanho igual a 10,
o algoritmo 2 mais rpido que o algoritmo 1 para entradas de tamanho entre 10 e 20,
os dois algoritmos executam no mesmo tempo para entradas de tamanho igual a 20,
o algoritmo 1 mais rpido que o algoritmo 2 para entradas de tamanho entre 20 e 30,
os dois algoritmos executam no mesmo tempo para entradas de tamanho igual a 30, e
o algoritmo 2 mais rpido que o algoritmo 1 para entradas de tamanho maior que 30.
50
Exerccio 6.18
Definir c1, c2 e n0 0 | 0 c1 n2 2n2 n/2 c2 n2 para todo n n0
0 c1 n2 2n2 n/2 c2 n2
0 c1 f (n) c2 onde f (n) = 2 1/(2n)
0 c1 f (n)
n 1/3
n 1/2
n1
n2
c2 f (n)
c2 1/2
c2 1
c2 3/2
c2 7/4
0 c1 1/2
0 c1 1
0 c1 3/2
0 c1 7/4
etc.
T(n)
f '(n) = 2
1/(2n)
Segundo a definio de
c1 f(n) c2
(0.25, 0)
Portanto
a faixa de valores de c1 que satisfazem
a definio de (0, 2) e
a faixa de valores de c2 que satisfazem
a definio de [2, ).
-2
-4
A inequao vlida para vrios conjuntos de constantes; qualquer um prova que 2n2 n/2 = (n2).
Exemplos:
n0 = 1/3, c1 = 1/2, c2 = 2
n0 = 1/3, c1 = 1/4, c2 = 2
n0 = 1/2, c1 = 1/2, c2 = 2
n0 = 1, c1 = 3/2, c2 = 3
n0 = 2, c1 = 1, c2 = 4 etc.
A seguir, a representao grfica da soluo para n0 = 1, c1 = 3/2, c2 = 3:
0 3/2 n2 2n2 n/2 3n2
T(n)
T(n)
T1(n) = 3n2
T2(n) = 3/2 n2
T3(n) = 2n2 n/2
T1(n) = 3n2
T2(n) = 3/2 n2
T3(n) = 2n2 n/2
800
1.5
600
(1, 1.5)
400
0.5
200
n
0.25
0.5
0.75
1.25
n
4
12
16
20
51
Exerccio 6.19
Para determinar as faixas de valores aceitveis para c1, c2 e n0 utilizando o mtodo analtico, devemos
analisar as razes de algumas equaes e seus sinais em vrios intervalos. Comeamos com a
expresso obtida a partir da definio de :
3
3
2
3
3
2
c1 n 10n 300n + 2000n c2 n (n ) c1 f(n) c2 onde f(n) = 10 300/n + 2000/n
3
2
2
f (n) = 10n 300n + 2000n = 10n (n 30n + 200) = 10n (n 10) (n 20)
cujas razes so 0, 10 e 20. Portanto, as razes de f(n) so 10 e 20; exclumos o 0 devido aos
denominadores na expresso de f(n). Observamos que
lim
x
f(n) = 10
Conclumos que c1 10, c2 10 e n0 > 20. Note que n0 no pode ser 20 pois n0=20, por ser uma raiz
de f(n), resultaria em c1 0 c2, o que no permitido pois a definio de afirma que c1,c2 e n0 > 0.
Podemos agora responder as duas primeiras perguntas:
a) O menor valor inteiro de n0 que nos permite provar que f (n) = (n ) 21.
3
3
2
3
5n 10n 300n + 2000n 20n
Resolvendo a primeira inequao:
3
3
2
3
2
2
5n 10n 300n + 2000n 5n 300n + 2000n 0 ( 5n) n 60n + 400 0
n = (60 (3600 4400)) / 2 = (60 2000) / 2 = (60 1020) / 2 = (60 205) / 2 = 30 105
n1 = 0, n2 = 30 22,4 = 7,6 e n3 = 30 + 22,4 = 52,4
3
O coeficiente de n = 5 0, de modo que o sinal do polinmio de 3 grau pode ser assim resumido:
7,6
+++
52,4
+++
3
2
5n 300n + 2000n
afirma que 0 n0 n ,
3
2
3
3
2
2
10n 300n + 2000n 20n 10n + 300n 2000n 0 ( 10n) n + 30n 200 0
n = (30 (900 + 4200)) / 2 = (30 1700) / 2 = (30 1017) / 2
n1 = 0
n2 = (30 + 41,2) / 2 = 5,6
n3 = (30 41,2) / 2 = 35,6
3
O coeficiente de n = 10 0, de modo que o sinal do polinmio de 3 grau pode ser assim resumido:
35,6
+++
5,6
+++
3
2
10n + 300n 2000n
52
Exerccio 6.20
3
1) O grfico 1 mostra que a maior raiz da funo f(n) = 8 300/n + 40/n 37,366. Segundo a
definio de , 0 c1 f(n), portanto n 37,366 para que f(n) 0 para todo n n0. Logo, a faixa de
valores de n0 que satisfazem a definio de [37,366 , ).
2) O grfico 2 mostra que
. Segundo a definio de
valores de c1 que satisfazem a definio de (0, 8).
Primeira parte:
2
c1 8 300/n + 40/n
Segunda parte:
2
c2 8 300/n + 40/n
n = 37 c1 0,079
n = 40 c1 0,525
n = 42 c1 0,880
n = 43 c1 1,045
n = 50 c1 2,016
n = 100 c1 5,0004
n = 300 c1 7,000...
n = 3000 c1 7,900...
n 37
n 40
n 42
n 43
n 50
n 100
n 300
n 3000
c2 0,079
c2 0,525
c2 0,880
c2 1,045
c2 2,016
c2 5,0004
c2 7,000...
c2 7,900...
etc.
53
T(n)
T2
(n) = 8n3
T1(n) = 8n3
300n2 40n
T3(n) = n3
3 105
2 105
1 105
(42.7, 0.78 105)
n
-30
-20
-10
10
20
30
40
50
60
70
-1 105
7. Ordenao
Exerccio 7.1
Um algoritmo de ordenao estvel aquele que mantm a ordem relativa dos dados com chaves
iguais. Um algoritmo de ordenao in place que ordena os dados na prpria estrutura onde se
encontram, no necessitando de memria extra alm dos dados sendo ordenados. Tal algoritmo usa no
mximo memria da ordem de O(1) ou O(log n) alm dos dados sendo ordenados.
Exerccio 7.2
O pior caso ocorre quando, em cada chamada recursiva... (respostas equivalentes)
o piv o maior ou o menor elemento da sequncia e no possui duplicatas.
o piv escolhido de forma que o particionamento resulte um uma subsequncia vazia.
O melhor caso ocorre quando, em cada chamada recursiva... (respostas equivalentes)
o piv o elemento intermedirio da sequncia.
o piv a mediana dos elementos da sequncia.
o piv o mais prximo da mdia aritmtica dos elementos da sequncia.
o piv escolhido tal que o particionamento resulte em subsequncias de tamanhos iguais.
Exerccio 7.3
Distino: (respostas equivalentes)
no h distino entre o melhor e pior caso.
o tempo de execuo do Merge Sort igual para o melhor caso e o pior caso.
Justificativa: (respostas equivalentes)
o nro de chamadas recursivas e comparaes entre dados independe da qualidade da entrada.
todo o funcionamento do Merge Sort independe do estado de ordenao prvia dos dados.
Exerccio 7.4
1) Sim. O nro de chamadas recursivas e de comparaes entre dados independente da qualidade
da entrada. O funcionamento do Merge Sort independe do estado de ordenao prvia dos dados.
2) No. O nro de chamadas recursivas depende dos tamanhos dos dois sub-vetores obtidos aps a
partio; esses tamanhos, por sua vez, dependem da qualidade do piv escolhido a cada passo da
Paulo Costa 2013
54
recurso. Um bom piv aquele que resulta em sub-vetores de tamanhos iguais ou aproximados,
mas no h garantia que se escolher sempre um bom piv a cada passo da recurso.
Exerccio 7.5
Mtodo 1: escolha como piv o primeiro (ou ltimo) elemento da sequncia ou array.
Observaes sobre esse mtodo (equivalentes entre si):
Tem a maior probabilidade de produzir particionamento desbalanceado da sequncia de entrada.
uma boa escolha apenas se a entrada estiver razoavelmente desordenada.
Resulta no pior caso se a entrada j estiver ordenada.
Mtodo 2: escolha como piv um elemento qualquer (aleatrio) da sequncia ou array.
Observaes sobre esse mtodo (equivalentes entre si):
Raramente resulta no pior caso.
Frequentemente resulta em um caso mdio prximo ao melhor caso.
Mtodo 3: escolha como piv a moda de trs elementos aleatrios da sequncia ou array.
Observaes sobre esse mtodo (equivalentes entre si):
Tem a maior probabilidade de produzir particionamento balanceado da sequncia de entrada.
Tem a maior probabilidade de se aproximar do melhor caso.
Exerccio 7.6
Tempo
Algoritmo
Pior caso
Caso mdio
Melhor caso
Bubble sort
Bubble sort modificado
Selection sort
Insertion sort
Heap sort
Merge sort
Quicksort
Exerccio 7.7
1
8. rvores
Exerccio 8.1
1)
2)
3)
4)
5)
6)
A
M
M
A
M
M
B
H
H
B
H
H
D
D
N
D
D
D
H
N
O
H
B
N
M
I
I
M
N
I
I
O
D
E
I
E
N
B
J
I
E
B
O
E
E
N
A
O
E
J
B
C
O
J
J
A
F
F
J
F
C
F
P
J
F
P
F
C
Q
O
C
K
G
P
K
G
P
Q
K
K
R
K
K
R
P
Q
L
P
G
L
Q
G
G
L
Q
G
L
L
C
Q
L
C
R
R
A
R
R
A
55
Exerccio 8.2
1) uma rvore binria onde cada n tem zero ou dois filhos.
2) uma rvore binria onde todos os nveis tm o nmero mximo de filhos.
3) uma rvore binria onde todos os nveis at o penltimo tm o nmero mximo de filhos e, no
penltimo nvel, todos os ns internos esto esquerda dos ns externos.
4) Cada n v visitado trs vezes:
a primeira vez antes de visitar a sub-rvore da esquerda,
a segunda vez aps visitar a sub-rvore da esquerda e antes de visitar a sub-rvore da direita, e
a terceira vez aps visitar a sub-rvore da direita.
5) O(n). Todos os ns so visitados trs vezes, logo o tempo de execuo proporcional a n.
Exerccio 8.3
Exerccio 8.4
4
3
8
6
4
7
1
3
Exerccio 8.5
Exerccio 8.6
Exerccio 8.7
A
A
B
D
H
M
C
E
J
I
N
B
G
K
P
D
L
H
R
C
E
J
I
N
G
K
L
Q
56
Exerccio 8.8
1)
((T
2)
T L
(L G)) K)((XJ)((CQ)A))
G K X J C Q A
Exerccio 8.9
1)
2)
E C
E C H
A G D
G D
F
A
F B
B
Exerccio 8.10
1 4 9 7 3 8 6 5 2
(8(1(4(97))))((((38)6)5)2)
1)
2)
Exerccio 8.11
1
10
Exerccio 8.12
1
Exerccio 8.13
pNo *ACMP (tNo *pN1, tNo *pN2) {
int profN1 = 0,
profN2 = 0;
tNo *aux1 = pN1,
*aux2 = pN2;
while (pai (aux1) != NULL) {
aux1 = pai (aux1);
profN1++; }
while (pai (aux2) != NULL) {
aux2 = pai (aux2);
profN2++; }
while (profN1 > profN2) {
pN1 = pai (pN1);
profN1--; }
while (profN2 > profN1) {
pN2 = pai (pN2);
profN2--; }
while (pN1 != pN2) {
pN1 = pai (pN1);
pN2 = pai (pN2); }
return (pN1);
}
57
Vetor
Exerccio 8.14
1
2
3
4
5
6
7
8
rvore...
binria
prpria?
Sim
Sim
No
No
Sim
No
Sim
No
binria
completa?
No
No
No
No
No
No
Sim
No
binria quase
completa?
Sim
No
Sim
No
No
No
No
No
de busca
binria?
No
No
No
Sim
No
No
No
Sim
Exerccio 8.15
Exerccio 8.16
Exerccio 8.17
100
54
163
27
71
10
6
40
19
31
133
66
49
59
86
68
80
115
97
223
150
180
243
Exerccio 8.18
100
54
163
27
86
10
6
40
19
31
66
49
59
133
97
71
115
198
150
180
223
58
Exerccio 8.19
/* Nodos usados para construir a rvore e a lista encadeada */
typedef struct nodo* tNodo;
/* Une dois nodos tal que o 2o. segue aps o 1o. Equivale a ajustar */
/* o ponteiro "proximo" do 1o. nodo e o ponteiro "anterior" do 2o. */
void uneNodos (tNodo nodo1, tNodo nodo2) {
nodo1->maior = nodo2; nodo2->menor = nodo1;
}
/* Une duas listas circulares duplamente encadeadas e
*/
/* retorna um ponteiro para o incio da lista resultante. */
tNodo uneListas (tNodo lista1, tNodo lista2) {
tNodo ultimoLista1, ultimoLista2;
if (lista1 == NULL) return (lista2);
if (lista2 == NULL) return (lista1);
ultimoLista1 = lista1->menor;
ultimoLista2 = lista2->menor;
uneNodos (ultimoLista1, lista2);
uneNodos (ultimoLista2, lista1);
return (lista1);
}
/* Transforma recursivamente uma rvore binria ordenada numa lista */
/* circular duplamente encadeada e retorna um ponteiro p/ seu incio */
tNodo arvoreParaLista (tNodo raiz) {
tNodo lista1, lista2;
if (raiz == NULL) return (NULL);
/* Chamadas recursivas para transformar as duas sub-rvores */
lista1 = arvoreParaLista (raiz->menor);
lista2 = arvoreParaLista (raiz->maior);
/* Crie com a raiz da rvore uma lista de um nico nodo */
raiz->menor = raiz; raiz->maior = raiz;
/* Junte as trs listas parciais em ordem crescente */
lista1 = uneListas (lista1, raiz);
lista1 = uneListas (lista1, lista2);
return (lista1);
}
9. Heaps
Exerccio 9.1
Propriedade relacional: Para cada nodo v diferente da raiz, a chave em v maior ou igual chave no
pai de v.
Propriedade estrutural: A rvore binria completa. Se a rvore tem altura h, ento:
1) todos os nveis entre 0 e h -1 possuem o maior nmero de nodos possvel, e
2) todos os nodos no nvel h esto esquerda dos nodos ausentes.
59
Exerccio 9.2
rvore
1
10
RE
RE
H 21
H 14
RE
Exerccio 9.3
12
12
15
18
21
30
0
29
26
35
24
40
15
28
21
33
7
30
10
11
12
18
13
12 15 18 21 29 24 28 30 26 35 40 33
29
26
35
4
24
40
18
29
26
35
28
33
7
15
8
40
10
11
12
13
12
15
30
12 15 18 21 29 24 28 30 26 35 40 33 8
12
21
33
28
21
24
9
30
10
11
12
13
12 15 18 21 29 8 28 30 26 35 40 33 24
29
26
35
4
18
40
33
7
28
24
10
11
12
13
12 15 8 21 29 18 28 30 26 35 40 33 24
8
15
12
21
30
0
29
26
35
4
18
40
33
7
28
24
10
11
12
13
8 15 12 21 29 18 28 30 26 35 40 33 24
60
Exerccio 9.4
12
33
15
21
30
0
29
26
35
15
18
24
40
21
28
30
33
7
10
11
18
12
13
12 15 18 21 29 24 28 30 26 35 40 33
29
26
35
4
24
40
6
18
29
26
35
28
10
11
12
13
30
7
10
11
18
33
40
6
21
24
15
33
30
33 15 18 21 29 24 28 30 26 35 40
15
21
28
12
13
15 33 18 21 29 24 28 30 26 35 40
29
26
35
4
24
28
40
6
10
11
12
13
15 21 18 33 29 24 28 30 26 35 40
15
21
18
26
30
0
29
33
35
4
24
28
40
5
10
11
12
13
15 21 18 26 29 24 28 30 33 35 40
Exerccio 9.5
rvore
1
RE
H 28
RE
RE
H 21
RE
Exerccio 9.6
1) Em qualquer um dos ns externos, ou folhas da rvore.
2) Sim. O heap deve ser crescente. Exemplo: o heap representado pelo vetor (1, 2, 5, 3, 4, 6, 7).
3) No. Para visitar as chaves em ordem crescente em um percurso infixado, a chave em qualquer
n teria que ser maior que a chave no filho da esquerda e menor que a chave no filho da direita.
Isso no possvel em um heap com chaves distintas, onde a chave em um n sempre menor
(ou maior) que as chaves de todos os seus descendentes, tanto esquerda quanto direita.
4) Sim. O heap deve ser decrescente. Exemplo: o heap representado pelo vetor (7, 3, 6, 1, 2, 4, 5).
Paulo Costa 2013
61
Funo de compresso
O inteiro produzido pelo cdigo hash
Um inteiro no intervalo [0, N 1]
Exerccio 10.2
1) Endereos de memria
Reinterpretamos os endereos de memria da chave como um inteiro.
Geralmente bom para qualquer tipo de chave, exceto chaves numricas e cadeias (strings).
2) Cast para inteiro, ou converso para inteiro
Reinterpretamos os bits da chave como um inteiro.
Apropriado para chaves de tamanho nmero de bits do tipo inteiro. Ex: byte, short, int e float.
3) Soma de componentes
Particionamos os bits da chave em componentes de tamanho fixo (p.ex. 16 ou 32 bits) e
somamos os componentes, ignorando overflows.
Apropriado para chaves de tamanho nmero de bits do tipo inteiro. Ex: long e double.
4) Acumulao polinomial, ou cdigo hash polinomial
Particionamos os bits da chave em uma sequncia de componentes de tamanho fixo (p.ex., 8, 16,
ou 32 bits), usamos esses componentes como coeficientes de um polinmio p(z) e calculamos
p(z) para um valor fixo z, ignorando overflows.
Apropriado para cadeias (strings).
5) Cdigo hash com shift
Variao do cdigo hash polinomial; substitui as multiplicaes por shifts do resultado parcial.
Apropriado para cadeias (strings).
Exerccio 10.3
1) Diviso: h2 (y) = y mod N
2) Multiplicao, Adio e Diviso (MAD): h2 (y) = (ay + b) mod N
onde a e b so inteiros 0 tal que a mod N 0
Exerccio 10.4
1) Na funo de compresso h2 (y) = y mod N o tamanho da tabela hash ( N) um nmero primo. O
objetivo espalhar as chaves adequadamente, diminuindo a probabilidade de padres na
distribuio das chaves e, assim, evitar colises.
2) Se a mod N 0 ento todo y mapear para o mesmo valor b.
Exerccio 10.5
1) Uma coliso ocorre quando a funo hash produz o mesmo resultado para duas chaves distintas, ou
seja, h(k1) = h(k2) onde k1 e k2 so chaves e h a funo hash.
2) Encadeamento separado e endereamento aberto.
Paulo Costa 2013
62
a) Encadeamento separado
Cada posio A[i] do array armazena um ponteiro para uma sequncia, geralmente
implementada por uma lista encadeada, contendo itens (k,v) tais que h(k) = i.
Vantagens: implementao simples; execuo rpida.
Desvantagem: consumo maior de memria devido s estruturas de dados auxiliares.
b) Endereamento aberto
Todos os itens (k,v) so armazenados na prpria tabela. Ao se tentar inserir um item (k,v) em
uma posio A[i] que j est ocupada, ento tenta-se novamente em outras posies.
Vantagem: uso econmico de memria.
Desvantagens: implementao mais complexa; requer cuidados para evitar clustering
(agrupamento), que prejudica a eficincia da tabela.
3) Quando se desconhece o nmero de itens a serem armazenados na tabela, a estratgia mais
apropriada o encadeamento separado. Justificativa: essa estratgia permite que a tabela cresa
sem grande perda de desempenho. Se fosse usado o endereamento aberto, seria necessrio o
rehashing de toda a tabela, que pode consumir bastante tempo.
Exerccio 10.6
1) No melhor caso, O(1). No pior caso, O( n).
2) Quando todas as chaves colidem.
3) O fator de carga de uma tabela hash definido por = n/N onde n o tamanho da entrada
(nmero de itens armazenados na tabela) e N o tamanho do array. Quanto menor o fator de carga,
menor a probabilidade de ocorrer colises na tabela, e maior a probabilidade das operaes sobre a
tabela serem efetuadas em tempo O(1).
Exerccio 10.7
Exerccio 10.8
0
0
1
42
81
76
42
97
76
50
28
12
67
89
67
29
35
35
10
19
10
19
56
12
89
63
Exerccio 10.9
0
91
Exerccio 10.10
80
69
53
53
92
26
81
76
32
16
65
21
94
45
24
10
19
10
19
Exerccio 10.11
Exerccio 10.12
0
0
1
10
11 39 20 5 16 44 88 12 23 13 94
20
2
3
4
16
11
88
39
94
23
12
44
8
9
13
10
64
Exerccio 10.13
0
10
1)
10
20
65
87
16
27
94
12
13
43
2)
72
42
37
20
60
11
82
89
15
29
52
3)
18
75
15
32
28
61
84
96
4)
91
46
70
22
53
81
28
60
40
24
85
5)
31
15
76
27
44
86
54
93
63
6)
72
20
37
29
60
11
82
89
15
58
41
7)
18
75
32
84
31
61
18
93
8)
58
42
66
75
82
27
11
64
35
19
65