You are on page 1of 67

UESC

Universidade Estadual de Santa Cruz

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.

Listas encadeadas .................................................................................................. 6

5.

Pilhas, filas e deques ............................................................................................ 10

6.

Complexidade....................................................................................................... 13

7.

Ordenao ............................................................................................................ 20

8.

rvores ................................................................................................................. 21

9.

Heaps .................................................................................................................... 26

10. Tabelas Hash ........................................................................................................ 28

Parte 2 Solues de exerccios selecionados ................................................ 32


1.

Recurso ............................................................................................................... 32

2.

Abstrao de dados.............................................................................................. 34

3.

Vetores ................................................................................................................. 36

4.

Listas encadeadas ................................................................................................ 38

5.

Pilhas, filas e deques ............................................................................................ 40

6.

Complexidade....................................................................................................... 42

7.

Ordenao ............................................................................................................ 54

8.

rvores ................................................................................................................. 55

9.

Heaps .................................................................................................................... 59

10. Tabelas Hash ........................................................................................................ 62

Parte 1 Listas de exerccios


1. Recurso
Exerccio 1.1
1) Determine o que a seguinte funo recursiva em C calcula:
int func (int n) {
if (n == 0)
return 0;
return (n + func (n-1));
}
2) Escreva uma funo iterativa que atinja o mesmo objetivo.

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)

somaI, uma funo iterativa que retorna a + b.


somaR, uma funo recursiva que retorna a + b.
multI, uma funo iterativa que retorna a b. Faa uma chamada a somaI se desejar.
multR, uma funo recursiva que retorna a b. Faa uma chamada a somaR se desejar.

No use qualquer operador aritmtico alm de incremento (++) ou decremento (--).

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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

Exerccio 1.8
Calcule o nmero de adies necessrias para computar
iterativo e recursivo implementados a seguir:

fib(n) para 0 n 10 usando os mtodos

/* Nmeros de Fibonacci, mtodo iterativo */


int iFIB
int i,
for (i
f3 =
}
return
}

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

/* Nmeros de Fibonacci, mtodo recursivo */

4
5

int rFIB (int n) {


if (n<=1) return (n);
return (rFib (n-1) + rFib (n-2));
}

6
7
8

Coloque seus resultados na tabela ao lado, onde

Ai(n) o nmero de adies no cmputo iterativo de fib(n) e


Ar(n) o nmero de adies no cmputo recursivo de fib(n).

9
10

Exerccio 1.9
O mximo divisor comum (MDC) de dois inteiros

x e y pode ser assim definido:

mdc (x,y) = y se y x e (x%y) = 0


mdc (x,y) = mdc (y,x) se x < y
mdc (x,y) = mdc (y, x%y) caso contrrio.
Escreva uma funo recursiva e uma iterativa para calcular

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

a posio do array a partir da qual se montam os subconjuntos de inteiros, para


ento test-los; deve ser sempre 0 na primeira chamada em main(),

numeros

o array que contm o conjunto de inteiros,

totNumeros a tamanho do conjunto de inteiros, e


soma

o resultado desejado para a soma dos elementos do subconjunto.

A seguir, exemplos do resultado esperado de SomaSubconjunto para algumas entradas:


Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

SomaSubconjunto (0, {2, 4, 8}, 3, 10) deve retornar TRUE


SomaSubconjunto (0, {2, 4, 8}, 3, 14) deve retornar TRUE
SomaSubconjunto (0, {2, 4, 8}, 3, 9) deve retornar FALSE
Sugestes:
a) Nas chamadas recursivas, ao invs de considerar os nmeros no array inteiro, considere apenas
a parte do array comeando em inicio. Na primeira chamada em main() o usurio
especifica a busca no array inteiro passando o valor 0 para inicio. No necessrio nenhum
lao; a recurso trata pores cada vez menores do array.
b) O caso base quando inicio >= totNumeros. Nesse caso, retorne TRUE se soma 0.
c) Caso contrrio, considere o nmero na posio inicio do array. H apenas duas
possibilidades: ou esse nmero usado para formar soma, ou ele no usado.
d) Faa uma chamada recursiva para verificar se possvel obter uma soluo usando esse
nmero (no esquea de ajustar o valor desejado de soma para refletir o fato que o nmero j
foi usado).
e) Se no for possvel, faa outra chamada recursiva para verificar se possvel obter uma soluo
sem usar esse nmero.
f) Se nenhuma das tentativas for bem sucedida, ento o problema no tem soluo.

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:

(a + bi) (c + di) = ac + (bi) (di) + adi + cbi


= ac + bd(-1) + (ad + cb) i
= (ac - bd) + (ad + cb) i

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

Dados dois vetores v

Figura 2

= (a,b) e w = (c,d)

- O mdulo de v dado por |v| = SQRT

(a + b ) onde SQRT a funo raiz quadrada


- O produto escalar de v e w dado por p = v w = ac + bd
- O ngulo entre v e w dado por ACOS ((v w) / (|v| |w|)) onde ACOS a funo arcocosseno (veja Figura 2).
Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

Use a notao de vetor v = <v[0],v[1]> onde v[O] e v[1] so os coeficiente x e


que um vetor no pode ser nulo, ou seja, seus dois coeficientes no podem ser ambos 0.

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

Considere tambm a seguinte sequncia de caracteres: A B C D 1 2 3 A. Escreva um programa em C


que mostra na tela os valores numricos obtidos quando se interpreta a sequncia acima como short
int, int e double. A sada do programa dever consistir no seguinte:
Como
Como
Como
Como

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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

b) a unio de A e B, sem repeties.

Exemplo: d g i k m o r t

c) a interseo de A e B, com repeties. Exemplo: g i i t


d) a interseo de A e B, sem repeties. Exemplo: g i 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

se a matriz for triangular superior,


se a matriz for triangular inferior,
se a matriz for diagonal, ou
em qualquer outro caso.

A funo deve receber como parmetros


o tamanho da matriz, por exemplo, 3 para uma matriz quadrada 3 x 3
um ponteiro para o primeiro elemento da matriz.

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

Estruturas de Dados Listas de exerccios e solues

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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

tDado TiraDoInicio (struct nodo* lista) {


struct nodo* inicio;
tDado dadoNoInicio;
inicio = lista;
if (inicio == NULL)
exit (-1);
dadoNoInicio = inicio->dado;
lista = inicio->prox;
free (inicio);
return (dadoNoInicio);
}

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.

4) Escreva a funo UneCirculares que


recebe dois ponteiro para as listas circulares C e D,
une C e D em uma nica lista circular,
coloca o resultado da unio em C,
deixa D vazia, e
no retorna nada.

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.

Paulo Costa 2013

Nodos em D
0
Nodos em C

0
1
2
n

Estruturas de Dados Listas de exerccios e solues

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

Considere tambm a funo abaixo, onde *fim


aponta para o ltimo nodo de L.

Os nodos da lista possuem a


seguinte estrutura:
struct nodo {
struct nodo* antes;
int dado;
struct nodo* depois;
};

void funcao (struct nodo **fim) {


struct nodo *p;
if (*fim == NULL)
return;
p = *fim->depois;
p->antes = NULL;
*fim->depois = NULL;
*fim = p;
}

Qual o objetivo dessa funo? Ou seja, o que ela faz?

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?

Paulo Costa 2013

void funcao (struct nodo** lista) {


struct nodo* resultado = NULL;
struct nodo* atual = *lista;
struct nodo* prox;
while (atual != NULL) {
prox = atual->prox;
atual->prox = resultado;
resultado = atual;
atual = prox;
}
*lista = resultado;
}

Estruturas de Dados Listas de exerccios e solues

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

5. Pilhas, filas e deques


Exerccio 5.1
Projete uma pilha de caracteres utilizando um vetor V no-circular de tamanho n, de modo que o ndice
do caractere no topo da pilha seja armazenado em V[0] e os caracteres empilhados em V[1] a V[n1].
Implemente as funes de acesso pilha listadas abaixo:
void
char
char
int
Bool

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

o ndice do caractere no topo da pilha 0 seja armazenado em V[0],


o ndice do caractere no topo da pilha 1 seja armazenado em V[n1],
as pilhas possam crescer enquanto houver posies livres em V, e
as pilhas no sejam deslocadas durante a execuo do programa.

Implemente as funes de acesso listadas abaixo. O nmero da pilha pode ser 0 ou 1.


void
char
char
int
Bool

poePilha
tiraPilha
topoPilha
tamPilha
pilhaVazia

(int numPilha, char letra)


(int numPilha)
(int numPilha)
(int numPilha)
(int numPilha)

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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Aps a operao poeNoFim(1)

[1 - - -]

Incio-> 1 <-Fim

Aps a operao poeNoFim(2)

[1 2 - -]

Incio-> 1 2 <-Fim

Aps a operao poeNoInicio(3)

[1 2 - 3]

Incio-> 3 1 2 <-Fim

Aps a operao poeNoInicio(4)

[1 2 4 3]

Incio-> 4 3 1 2 <-Fim

Aps a operao tiraDoFim()

[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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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)

O tipo de dado a ser armazenado na fila, tDado, j est definido.


Todos os mtodos de acesso a pilhas, listados na tabela abaixo, j esto implementados.
Esses mtodos so capazes de manipular vrias pilhas independentes ao mesmo tempo.
Esses mtodos tomam o nmero da pilha como parmetro.

Restries:
1)
2)
3)
4)
5)

Implemente apenas os mtodos de acesso fila listados na tabela abaixo.


No declare nenhuma varivel.
Use apenas os mtodos de acesso a pilhas e os comandos de C que julgar convenientes.
Use apenas duas pilhas, numeradas 0 e 1.
No use recurso.

Pilha
void
tDado
tDado
int
Bool

Fila
poePilha
tiraPilha
topoPilha
tamPilha
pilhaVazia

(int numPilha, tDado dado)


(int numPilha)
(int numPilha)
(int numPilha)
(int numPilha)

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)

O tipo de dado a ser armazenado no deque, tdado, j est definido.


Todos os mtodos de acesso a pilhas, listados na tabela abaixo, j esto implementados.
Esses mtodos so capazes de manipular vrias pilhas independentes ao mesmo tempo.
Esses mtodos tomam o nmero da pilha como parmetro.

Restries:
1)
2)
3)
4)
5)

Implemente apenas os mtodos de acesso ao deque listados na tabela abaixo.


No declare nenhuma varivel.
Use apenas os mtodos de acesso a pilhas e os comandos de C que julgar convenientes.
Use apenas duas pilhas, numeradas 0 e 1.
No use recurso.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

12

Pilha
void
tDado
tDado
int
Bool

Deque
poePilha
tiraPilha
topoPilha
tamPilha
pilhaVazia

(int numPilha, tDado dado)


(int numPilha)
(int numPilha)
(int numPilha)
(int numPilha)

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

Mtodos a serem implementados

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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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.

5) Clculo de c usando apenas adies.

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

f (n) = ( g (n)) ento f (n) = O ( g (n))


f (n) = ( g (n)) ento f (n) = ( g (n))
f (n) = O ( g (n)) ento f (n) = ( g (n))
f (n) = ( g (n)) ento f (n) = ( g (n))
f (n) = O ( g (n)) ento g (n) = O ( f (n))

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

f (n) = ( g (n)) ento g (n) = ( f (n))


f (n) = O ( g (n)) e g (n) = O ( f (n)) ento f (n) = ( g (n))
f (n) = O ( g (n)) e g (n) = O ( f (n)) ento g (n) = ( f (n))
f (n) = O ( g (n)) e g (n) = O ( f (n)) ento f (n) = ( g (n))
f (n) = O ( g (n)) e g (n) = O ( f (n)) ento g (n) = ( f (n))
f (n) = O ( h (n)) e h (n) = O ( g (n)) ento f (n) = O ( g (n))
f (n) = O ( h (n)) e g (n) = O ( h (n)) ento f (n) g (n) = O ( h (n))
f (n) = O ( h (n)) e g (n) = O ( h (n)) ento f (n) g (n) = O ( h (n))
f (n) = O ( g (n)) ento k f (n) = O ( g (n)) onde k uma constante
f (n) = O ( g (n)) no pior caso, ento f (n) = O ( g (n)) em qualquer caso
f (n) = O ( g (n)) no melhor caso, ento f (n) = O ( g (n)) em qualquer caso
f (n) = ( g (n)) no pior caso, ento f (n) = ( g (n)) em qualquer caso
f (n) = ( g (n)) no melhor caso, ento f (n) = ( g (n)) em qualquer caso
f (n) = ( g (n)) no pior caso, ento f (n) = ( g (n)) em qualquer caso
f (n) = ( g (n)) no melhor caso, ento f (n) = ( g (n)) em qualquer caso

Exerccio 6.9
Considere a definio de O(g(n)) a seguir:

O(g(n)) = { f (n) : constantes c e n0 0 | 0 f (n) cg(n) para todo n n0 }


Considere tambm a funo f (n) = an + b onde a e b so constantes inteiras e a 0.
2
Pergunta: f (n) O(n )? Prove que sua resposta est correta utilizando a definio de O(g(n)) acima.

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

ndice do topo da pilha

Lista linear
simplesmente
encadeada

Ponteiro p/ topo da pilha (ltimo nodo)

Ponteiro p/ base da pilha (1 nodo)

Ponteiro p/ topo da pilha (ltimo nodo)

Ponteiro p/ base da pilha (1 nodo)

Ponteiros p/ topo e base da pilha (1 e ltimo nodos)

Ponteiro p/ topo da pilha (ltimo nodo)

Ponteiro p/ base da pilha (1 nodo)

Ponteiro p/ topo da pilha (ltimo nodo)

Ponteiro p/ base da pilha (1 nodo)

10

Lista linear
duplamente
encadeada
Lista circular
simplesmente
encadeada
Lista circular
duplamente
encadeada

INS

REM

Ponteiros p/ topo e base da pilha (1 e ltimo nodos) 11


Array sem
ndices do incio e fim da fila
compactao
Array c/ compactao
ndice do fim da fila
aps cada remoo

13

Array circular

ndices do incio e fim da fila

14

Lista linear
simplesmente
encadeada

Ponteiro p/ incio da fila (1 nodo)

15

Ponteiros p/ incio e fim da fila (1 e ltimo nodos)

16

Ponteiro p/ incio da fila (1 nodo)

17

Ponteiro p/ fim da fila (ltimo nodo)

18

Ponteiros p/ incio e fim da fila (1 e ltimo nodos)

19

Ponteiro p/ incio da fila (1 nodo)

20

Ponteiro p/ fim da fila (ltimo nodo)

21

Ponteiros p/ incio e fim da fila (1 e ltimo nodos)

22

Ponteiro p/ incio da fila (1 nodo)

23

Ponteiro p/ fim da fila (ltimo nodo)

24

Ponteiros p/ incio e fim da fila (1 e ltimo nodos)

25

Lista linear
duplamente
encadeada
Fila

12

Lista circular
simplesmente
encadeada

Lista circular
duplamente
encadeada

Precedida por insero


2 pilhas
implementadas
por arrays

26
ndice do topo de cada pilha

Precedida por remoo


27

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

NOTA: A identao mostra o escopo dos comandos:


o para na linha 2 est dentro do para na linha 1,
o se na linha 3 est dentro do para na linha 2, e
as linhas 4 a 6 esto dentro do se na linha 3.

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)

para i de 1 at n-1 faa


atual = A[i]
j = i-1
enquanto j>=0 e A[j]>atual faa
A[j+1] = A[j]
j = j-1
A[j+1] = atual

NOTA: A identao mostra o escopo dos comandos:


as linhas 5 e 6 esto dentro do enquanto na linha 4;
as linhas 2 a 7 esto dentro do para na linha 1.

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

NOTA: A identao mostra o escopo dos comandos:


o para na linha 2 est dentro do para na linha 1,
o se na linha 3 est dentro do para na linha 2, e
as linhas 4 a 6 esto dentro do se na linha 3.

Paulo Costa 2013

Linha

Melhor caso

Pior caso

1
2
3
4
5
6
Total

Estruturas de Dados Listas de exerccios e solues

17

Exerccio 6.15
Existem dois algoritmos para resolver certo problema, cujos tempos de execuo so dados por:

Algoritmo 1

Algoritmo 2

onde n o tamanho da entrada. Responda as seguintes perguntas, justificando todas as respostas:


1) possvel afirmar que um dos algoritmos executa sempre mais rpido que o outro para entradas
de qualquer tamanho?
2) possvel afirmar que um dos algoritmos executa sempre mais rpido que o outro para entradas
de tamanho entre 10 e 30? Se for possvel, qual dos dois?
3) possvel afirmar que um dos algoritmos executa sempre mais rpido que o outro para entradas
de tamanho igual a 50? Se for possvel, qual dos dois?
4) possvel afirmar que um dos algoritmos executa sempre mais rpido que o outro para entradas
de tamanho entre 90 e 200? Se for possvel, qual dos dois?
5) possvel afirmar que um dos algoritmos executa sempre mais rpido que o outro para entradas
de tamanho acima de 500? Se for possvel, qual dos dois?

Exerccio 6.16
Existem dois algoritmos para resolver certo problema, cujos tempos de execuo so dados por:

Algoritmo 1

Algoritmo 2

onde n o tamanho da entrada. Responda as seguintes perguntas, justificando todas as respostas:


1) Os tamanhos da entrada para os quais o algoritmo 1 executa mais rpido que o algoritmo 2.
2) Os tamanhos da entrada para os quais o algoritmo 2 executa mais rpido que o algoritmo 1.
3) Os tamanhos da entrada para os quais os dois algoritmos executam em tempos iguais.
Dica: Solucione as equaes e, a partir da, esboce os grficos de

Exerccio 6.17
Existem dois algoritmos para resolver certo problema, cujos tempos de execuo so dados por:

Algoritmo 1

Algoritmo 2

onde n o tamanho da entrada. Responda as seguintes perguntas, justificando todas as respostas:


1) Os tamanhos da entrada para os quais o algoritmo 1 executa mais rpido que o algoritmo 2.
2) Os tamanhos da entrada para os quais o algoritmo 2 executa mais rpido que o algoritmo 1.
3) Os tamanhos da entrada para os quais os dois algoritmos executam em tempos iguais.
Dica: Uma equao cbica com trs razes reais pode ser escrita na forma

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:

(g(n)) = { f (n) : constantes c1, c2 e n0 0 | 0 c1g(n) f (n) c2g(n) para todo n n0 }


Use a definio acima para mostrar que 2 n n/2 = (n )
2

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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:

1) Qual o menor valor inteiro de n0 que permite provar que f (n) = (n )?

2) Qual o maior valor inteiro de c1 que permite provar que f (n) = (n )?

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)

Qual a faixa de valores de n0 que satisfazem a definio de para quaisquer c1 e c2 0?


Qual a faixa de valores de c1 que satisfazem a definio de ?
Qual a faixa de valores de c2 que satisfazem a definio de ?
3
Use a definio de para mostrar que f (n) = (n ).
3
Use os resultados anteriores para mostrar graficamente que f (n) = (n ).

Grfico 1

T(n)

f '(n) = 8

300/n

Grfico 2
T(n)

4/n2

-1 103

-2 103

200

Paulo Costa 2013

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

Estruturas de Dados Listas de exerccios e solues

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. (

) Todos os algoritmos de ordenao funcionam atravs de comparaes entre chaves.

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. (

) O algoritmo de ordenao mais eficiente executa em tempo O( n log n).

05. (

) Selection Sort uma variao do FP-Sort (FP = Fila de Prioridades) onde a fila de

prioridades implementada com uma sequncia ordenada.


06. (

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Escreva a sequncia em que os ns da rvore 1 so visitados em um caminhamento


Escreva a sequncia em que os ns da rvore 1 so visitados em um caminhamento
Escreva a sequncia em que os ns da rvore 1 so visitados em um caminhamento
Escreva a sequncia em que os ns da rvore 2 so visitados em um caminhamento
Escreva a sequncia em que os ns da rvore 2 so visitados em um caminhamento
Escreva a sequncia em que os ns da rvore 2 so visitados em um caminhamento

L
Q

prefixado.
infixado.
posfixado.
prefixado.
infixado.
posfixado.

Exerccio 8.2
1)
2)
3)
4)

O que uma rvore binria prpria?


O que uma rvore binria completa?
O que uma rvore binria quase completa?
No caminhamento de Euler sobre uma rvore binria, quantas vezes os ns so visitados? Explique.

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

Desenhe a rvore binria correspondente expresso.

Exerccio 8.4
Considere a expresso infixada a seguir, onde todos os operadores so binrios:

(8

((27)4))(((56)3)1)

Desenhe a rvore binria correspondente expresso, sem parnteses.

Exerccio 8.5
Considere a expresso posfixada a seguir, onde todos os operadores so binrios:

5 7

8 2 4 6

Desenhe a rvore binria correspondente expresso.


Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

1) Escreva a expresso em notao infixada, com parnteses.


2) Escreva a expresso em notao posfixada, sem parnteses.

Exerccio 8.9
Considere a expresso infixada a seguir, onde todos os operadores so binrios:

( ( ( E

C )

H )

( ( G

D )

F ) ) )

1) Escreva a expresso em notao prefixada, sem parnteses.


2) Escreva a expresso em notao posfixada, sem parnteses.

Exerccio 8.10
Considere a expresso posfixada a seguir, onde todos os operadores so binrios:

8 1 4 9 7

3 8

1) Escreva a expresso em notao prefixada, sem parnteses.


2) Escreva a expresso em notao infixada, com parnteses.

Exerccio 8.11
Verdadeiro ou falso:
01. (

) Todo heap uma rvore binria prpria.

02. (

) Toda rvore binria prpria um heap.

03. (

) Toda rvore binria quase completa um heap.

04. (

) Todo heap uma rvore binria quase completa.

05. (

) Todo heap uma rvore binria de busca.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

22

06. (

) Toda rvore binria de busca um heap.

07. (

) Nem toda rvore binria de busca uma rvore binria prpria.

08. (

) Toda rvore binria de busca uma rvore binria quase completa.

09. (

) Nem toda rvore binria quase completa uma rvore binria prpria.

10. (

) Toda rvore binria prpria uma rvore binria quase completa.

Exerccio 8.12
Seja:

G
eg
ig
ng
hg

uma rvore binria genrica no vazia

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

uma rvore binria prpria no vazia

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Para cada vetor, indique, com Sim ou No, se a rvore correspondente

Vetor

Uma rvore binria prpria


Uma rvore binria completa
Uma rvore binria quase completa
Uma rvore de busca binria

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

Descreva um mtodo usando o caminhamento de


Euler para imprimir uma expresso aritmtica infixada
com parnteses a partir de sua rvore.
Por exemplo, se o mtodo for aplicado rvore ao
lado...

4
3

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

7
2

24

o resultado deve ser a impresso da expresso

( 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

106 120 144 157 172 190 200 243

Mostre o contedo da rvore aps a execuo das seguintes operaes:


remove (198); remove (190); remove (200); insere (198).
Certifique-se que em momento algum a altura da rvore seja superior a 4.

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

106 120 144 157 172 190 200 243

Mostre o contedo da rvore aps a execuo das seguintes operaes:


remove (71); remove (68); remove (80); insere (71).
Certifique-se que em momento algum a altura da rvore seja superior a 4.

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

25

Escreva a funo recursiva arvoreParaLista que


recebe um ponteiro para a raiz de uma rvore A,
reorganiza os ponteiros internos da rvore de modo a transform-la numa lista circular
duplamente encadeada, com os dados organizados em ordem crescente,
retorna um ponteiro para o primeiro nodo da lista (o nodo com do dado de menor valor), e
executa em tempo O(n), operando uma nica vez sobre cada nodo.
A funo deve funcionar corretamente em todos os casos, incluindo:

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

a rvore no viola nenhuma propriedade, portanto um heap; o ltimo n tem chave n.


a rvore viola a propriedade relacional, portanto no um heap.
a rvore viola a propriedade estrutural, portanto no um heap.
a rvore viola as duas propriedades, portanto no um heap.

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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

40

33

10

11

12

13

12 15 18 21 29 24 28 30 26 35 40 33

Estruturas de Dados Listas de exerccios e solues

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

a rvore no viola nenhuma propriedade, portanto um heap; o ltimo n tem chave n.


a rvore viola a propriedade relacional, portanto no um heap.
a rvore viola a propriedade estrutural, portanto no um heap.
a rvore viola as duas propriedades, portanto no um heap.

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.

10. Tabelas Hash


Exerccio 10.1
Uma tabela hash consiste de um array A de tamanho N e de uma funo hash h. Quais os dois
componentes da funo hash? Fornea seus nomes, parmetros de entrada e de sada, e explique
seus objetivos.
Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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:

h(k) = (2k + 5) mod 11


Desenhe a tabela aps a insero das chaves acima, na ordem em que foram listadas, supondo que a
tabela usa encadeamento separado.
Nota Utilize a tabela com valores pr-calculados fornecida no exerccio 13.

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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:

h(k) = (2k + 5) mod 11


d(k) = 7 (k mod 7)

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)

87, 16, 94, 5, 12, 20, 13, 65, 43, 10, 27

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

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

Estruturas de Dados Listas de exerccios e solues

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

Parte 2 Solues de exerccios selecionados


1. Recurso
Exerccio 1.1
A funo calcula a soma
Abaixo, uma verso iterativa dessa funo:
int func (int n) {
int i, soma;
for (i=1, soma=0; i<=n; i++)
soma+=i;
return (soma);
}

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

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

33

Exerccio 1.9
MDC recursivo

MDC iterativo

int mdcR (int x, int y) {


if ((y<=x) && ((x%y)==0))
return (y);
if (x<y)
return (mdcR (y, x));
return (mdcR (y, x%y));
}

int mdcI (int x, int y) {


int t;
// Importante garantir que x >= y
// Troque x e y se necessrio
if (x<y) {
t=y; y=x; x=t;
}
while ((x%y)!=0) {
t=x%y; x=y; y=t;
}
return (y);
}

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

areal (parte real de a)


a[1] aimaginrio (parte imaginria de a)
a[O]

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

34

Define-se a soma de dois nmeros complexos

a e b como

(a[0] + a[1]i) + (b[0] + b[1]i) = (a[0] + b[0]) + (a[1] + b[1])i


= soma[0] + soma[1]i
Define-se a multiplicao de dois nmeros complexos

a e b como

(a[0] + a[1]i) * (b[0] + b[1]i)


= (a[0] * b[0] - a[1] * b[1]) + (a[0] * b[1] + b[0] * a[1])i
= mult[0] + mult[1]i
Define-se a igualdade entre dois nmeros complexos
(a[0] + a[1]i) = (b[0] + b[1]i)

a e b como

(a[0] = b[0]) AND (a[1] = b[1])

Especificao do TDA Complexo


abstract typedef <real,real> COMPLEXO;
abstract COMPLEXO cria_complexo (real a, real b);
postcondition
cria_racional[O] = a;
cria_racional[1] = b;
abstract COMPLEXO soma (COMPLEXO a, COMPLEXO b);
postcondition
soma[O] = a[O] + b[O];
soma[1] = a[1] + b[1];
abstract COMPLEXO mult (COMPLEXO a, COMPLEXO b);
postcondition
mult[O] = a[0]*b[0] - a[1]*b[1];
mult[1] = a[0]*b[1] + b[0]*a[1];
abstract COMPLEXO igual (COMPLEXO a, COMPLEXO b);
postcondition
igual = (a[0] == b[0]) AND (a[1] == b[1]);

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

printf ("\n Como char: ");


for (k=0; k<8; k++)
printf ("%c ", u.c[k]);
printf ("\n Como short int: ");
for (k=0; k<4; k++)
printf ("%d ", u.si[k]);
printf ("\n Como int: ");
for (k=0; k<2; k++)
printf ("%d ", u.i[k]);
printf ("\n Como double: ");
printf ("%f", u.d);
return 0;
}

3. Vetores
Exerccio 3.3
#define
#define
#define
#define

TAM_MAX
Bool
TRUE
FALSE

100
int
1
0

Bool ehPalindromo (char *palavra, int tamanho) {


int pos;
for (pos = 0; pos < (int)((tamanho+1)/2); pos++)
if (palavra[pos] != palavra[tamanho-pos-1])
return (FALSE);
return (TRUE);
}
int main(int argc, char *argv[]) {
char palavra [TAM_MAX];
printf ("Digite uma palavra qualquer, ou 'fim' para terminar: ");
scanf ("%s", palavra);
while (strcmp (palavra, "fim")) {
printf ("[%s] ", palavra);
if (! ehPalindromo(palavra, strlen(palavra)))
printf ("nao ");
printf ("eh um palindromo\n\n");
printf ("Digite uma palavra qualquer, ou 'fim' para terminar: ");
scanf ("%s", palavra);
}
return 0;
}

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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++;
}

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

37

Exerccio 3.7
#define
#define
#define
#define

TAM_MAX
Bool
TRUE
FALSE

100
int
1
0

Bool ehPalindromo (char *palavra, int tamanho, int pos) {


Bool letrasIguais;
if (tamanho-2*pos <= 1)
return (TRUE);
else
letrasIguais = (palavra[pos] == palavra[tamanho-pos-1]);
return (letrasIguais && ehPalindromo (palavra, tamanho, pos+1));
}
int main(int argc, char *argv[]) {
char palavra [TAM_MAX];
printf ("Digite uma palavra qualquer, ou 'fim' para terminar: ");
scanf ("%s", palavra);
while (strcmp (palavra, "fim")) {
printf ("[%s] ", palavra);
if (! ehPalindromo(palavra, strlen(palavra), 0))
printf ("nao ");
printf ("eh um palindromo\n\n");
printf ("Digite uma palavra qualquer, ou 'fim' para terminar: ");
scanf ("%s", palavra);
}
return 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

Estruturas de Dados Listas de exerccios e solues

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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

39

5. Pilhas, filas e deques


Exerccio 5.3
Usando um deque

Usando uma pilha e uma fila

Bool ehPalindromo (void) {


while (! acabaramAsLetras())
poeInicioDeque (obtemLetra());
while (tamDeque() > 1)
if (tiraInicioDeque() !=
tiraFimDeque())
return (FALSE);
return (TRUE);
}

Bool ehPalindromo (void) {


char letra;
while (! acabaramAsLetras()) {
letra = obtemLetra();
poePilha (letra);
poeFila (letra);
}
while (! pilhaVazia())
if (tiraPilha() != tiraFila())
return (FALSE);
return (TRUE);
}

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 */

/* Remove dado do incio da fila */

void poeFila (tDado dado) {


if (pilhaVazia (0))
while (! pilhaVazia (1))
poePilha (0, tiraPilha (1));
poePilha (0, dado);
}

tDado tiraFila (void) {


if (pilhaVazia (1))
while (! pilhaVazia (0))
poePilha (1, tiraPilha (0));
return (tiraPilha (1));
}

/* Retorna o dado na frente */


/* da fila sem remov-lo
*/

/* Retorna um Booleano indi- */


/* cando se a fila est vazia */

tDado frenteFila (void) {


if (pilhaVazia (1))
while (! pilhaVazia (0))
poePilha (1, tiraPilha (0));
return (topoPilha (1));
}

Bool filaVazia (void) {


return ( pilhaVazia(0) &&
pilhaVazia(1) );
}

/* Retorna o nro de elemen- */


/* tos armazenados na fila */
int tamFila (void) {
return (tamPilha(0)+tamPilha(1));
}
Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

40

Exerccio 5.7
Soluo 1
/* Poe dado no inicio do deque */

/* Poe dado no fim do deque */

void poeInicioDeque (tDado dado) {


while (! pilhaVazia (0))
poePilha (1, tiraPilha (0));
poePilha (1, dado); }

void poeFimDeque (tDado dado) {


while (! pilhaVazia (1))
poePilha (0, tiraPilha (1));
poePilha (0, dado); }

/* Tira dado do inicio do deque */

/* Tira dado do fim do deque */

tDado tiraInicioDeque (void) {


while (! pilhaVazia (0))
poePilha (1, tiraPilha (0));
return (tiraPilha (1)); }

tDado tiraFimDeque (void) {


while (! pilhaVazia (1))
poePilha (0, tiraPilha (1));
return (tiraPilha (0)); }

/* Retorna o dado no inicio */


/* do deque sem remov-lo
*/

/* Retorna o dado no fim */


/* do deque sem remov-lo */

tDado inicioDeque (void) {


while (! pilhaVazia (0))
poePilha (1, tiraPilha (0));
return (topoPilha (1)); }

tDado fimDeque (void) {


while (! pilhaVazia (1))
poePilha (0, tiraPilha (1));
return (topoPilha (0)); }

/* Retorna o nmero de elemen- */


/* tos armazenados no deque
*/

/* Retorna um Booleano indi*/


/* cando se o deque est vazio */

int tamDeque (void) {


return (tamPilha(0)+tamPilha(1));
}

Bool dequeVazio (void) {


return (pilhaVazia(0) &&
pilhaVazia(1)); }

Soluo 2
/* Poe dado no inicio do deque */

/* Poe dado no fim do deque */

void poeInicioDeque (tDado dado) {


while (! pilhaVazia (1))
poePilha (0, tiraPilha (1));
poePilha (0, dado); }

void poeFimDeque (tDado dado) {


while (! pilhaVazia (0))
poePilha (1, tiraPilha (0));
poePilha (1, dado); }

/* Tira dado do inicio do deque */

/* Tira dado do fim do deque */

tDado tiraInicioDeque (void) {


while (! pilhaVazia (1))
poePilha (0, tiraPilha (1));
return (tiraPilha (0)); }

tDado tiraFimDeque (void) {


while (! pilhaVazia (0))
poePilha (1, tiraPilha (0));
return (tiraPilha (1)); }

/* Retorna o dado no inicio */


/* do deque sem remov-lo
*/

/* Retorna o dado no fim */


/* do deque sem remov-lo */

tDado inicioDeque (void) {


while (! pilhaVazia (1))
poePilha (0, tiraPilha (1));
return (topoPilha (0)); }

tDado fimDeque (void) {


while (! pilhaVazia (0))
poePilha (1, tiraPilha (0));
return (topoPilha (1)); }

/* Retorna o nmero de elemen- */


/* tos armazenados no deque
*/

/* Retorna um Booleano indi*/


/* cando se o deque est vazio */

int tamDeque (void) {


return (tamPilha(1)+tamPilha(0));
}

Bool dequeVazio (void) {


return (pilhaVazia(1) &&
pilhaVazia(0)); }

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

41

Exerccio 5.8
/* Insere dado na pilha */

/* Retorna o dado no topo */


/* da pilha sem remov-lo */

void poePilha (tDado dado) {


poeFila (dado); }
/* Remove dado da pilha */
tDado tiraPilha (void) {
int t = tamFila();
while (t-- > 1)
poeFila (tiraFila());
return (tiraFila()); }
/* Retorna o nro de elemen- */
/* tos armazenados na pilha */

tDado topoPilha (void) {


tDado dado;
int t = tamFila();
while (t-- > 1)
poeFila (tiraFila());
dado = frenteFila();
poeFila (tiraFila());
return (dado); }
/* Retorna um Booleano indi*/
/* cando se a pilha est vazia */
Bool pilhaVazia (void) {
return (filaVazia()); }

int tamPilha (void) {


return (tamFila()); }

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

Equivalncia imperfeita com processadores reais.


Simplificao s vezes irrealista do algoritmo.
Um algoritmo simples pode ser difcil de analisar.
A anlise pode exigir ferramentas matemticas.

Exerccio 6.4
1)
2)
3)
4)
5)

Exerccio 6.5
A

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

O problema consiste em definir c e n0 0 | 0 an + b cn para todo n n0.


2
2
Dividindo a inequao acima por n obtemos 0 a/n + b/n c.
Fazendo n0 = 1 obtemos 0 a + b c que satisfeita por c = a + | b |.
2
A existncia de valores para c e n0 que satisfazem a definio de O(g(n)) prova que an + b O(n ).

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

NOTA: A identao mostra o escopo dos comandos:


o para na linha 2 est dentro do para na linha 1,
o se na linha 3 est dentro do para na linha 2, e
as linhas 4 a 6 esto dentro do se na linha 3.

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

Linha 1, qualquer caso: para i de 0 at n-1 passo 1 faa


As inicializaes equivalem a 2 operaes bsicas: atribuio de 0 a i e clculo de n 1. Essas
operaes so executadas uma nica vez.
No comando para temos primeiro um teste da condio de parada; se a condio for falsa, o lao
executado uma vez e, ao final, a varivel de controle incrementada.
Neste comando para, i varia de 0 a n 1 inclusive, logo a condio de parada ser testada n + 1 vezes
(n vezes ela ser falsa, e na ltima vez ser verdadeira). So n + 1 operaes bsicas.
A varivel de controle i ser incrementada n vezes. So n operaes bsicas. Esse tambm o
nmero de vezes que este lao e os comandos dentro dele sero executados.
Nmero total de operaes bsicas: 2 + n + 1 + n 2n + 3. Essa anlise independe da qualidade da
entrada, portanto o resultado vlido para todos os casos.
Linha 2, qualquer caso: para j de n-1 at i+1 passo -1 faa
As inicializaes equivalem a 3 operaes bsicas: clculo de n 1, atribuio do resultado a j e
clculo de i + 1. Lembrando que esta linha executada n vezes por causa do comando para na linha 1,
conclumos que essas operaes equivalem a 3n operaes bsicas.
Neste comando para, j varia de n 1 at i + 1 inclusive, em decrementos unitrios. Logo, a condio de
parada ser testada, e resultar falsa, (n 1) (i + 1) + 1 vezes; s no prximo teste ser verdadeira. O
total de testes ser ento (n 1) (i + 1) + 1 + 1 n i. So n i operaes bsicas para cada valor de
i, determinado pelo lao externo.
A varivel de controle j ser decrementada n i 1 vezes. So n i 1 operaes bsicas para cada
valor de i, determinado pelo lao externo. Esse tambm o nmero de vezes que o lao da linha 2 e os
comandos dentro dele (comando se da linha 3) sero executados.
medida que o valor de i aumenta (comando para da linha 1), o teste da condio de parada e o
decremento de j so executados mais e mais vezes:

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

Vezes que ser executado...


o teste da condio de
parada na linha 2: n i

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

Estruturas de Dados Listas de exerccios e solues

(n n) / 2

44

Nmero total de operaes bsicas na linha 2: 3n + (n + n) / 2 + (n n) / 2 n + 3n.


Linha 3, qualquer caso: se A[j-1] > A[j] ento
Nessa linha h uma subtrao, duas indexaes e uma comparao. So 4 operaes bsicas. A linha
2
2
2
ser executada (n n) / 2 vezes. Operaes bsicas: 4 (n n) / 2 2n 2n.
Linhas 4, 5 e 6, melhor caso:
No melhor caso o array j estar ordenado, de modo que a condio do comando se ser sempre falsa.
Portanto, os comandos dentro do se no sero executados nenhuma vez. Assim, no importa quantas
operaes bsicas haja nesses comandos; o total de operaes bsicas nessas linhas 0.
Linha 4, pior caso: temp = A[j-1]
Nessa linha h uma subtrao, uma indexao e uma atribuio. So 3 operaes bsicas. Vimos que,
2
no pior caso, os comandos dentro do se sero executados (n n) / 2 vezes. Operaes bsicas na
2
linha 4, no pior caso: 3 (n n) / 2.
Linha 5, pior caso: A[j-1] = A[j]
Nessa linha h uma subtrao, duas indexaes e uma atribuio. So 4 operaes bsicas. Vimos
2
que, no pior caso, os comandos dentro do se sero executados (n n) / 2 vezes. Operaes bsicas
2
2
na linha 5, no pior caso: 4 (n n) / 2 2n 2n.
Linha 6, pior caso: A[j] = temp
Nessa linha h uma indexao e uma atribuio. So 2 operaes bsicas. Vimos que, no pior caso, os
2
comandos dentro do se sero executados (n n) / 2 vezes. Operaes bsicas na linha 6, no pior
2
2
caso: 2 (n n) / 2 n n.

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

para i de 1 at n-1 faa


atual = A[i]
j = i-1
enquanto j>=0 e A[j]>atual faa
A[j+1] = A[j]
j = j-1
A[j+1] = atual

NOTA: A identao mostra o escopo dos comandos:


as linhas 5 e 6 esto dentro do enquanto na linha 4;
as linhas 2 a 7 esto dentro do para na linha 1.

Total

13n 10

2
2

3n 3
2

5n + 8n 10

Linha 1, qualquer caso: para i de 1 at n-1 faa


As inicializaes equivalem a 2 operaes bsicas: atribuio de 1 a i e clculo de n 1.
No comando para temos primeiro um teste da condio de parada; se a condio for falsa, o lao
executado uma vez e, ao final, a varivel de controle incrementada. Na prxima iterao a condio
de parada testada novamente e assim sucessivamente.
Neste algoritmo em particular, i varia de 1 a n 1 inclusive, logo a condio de parada ser testada n
vezes (n 1 vezes ela ser falsa, e na ltima vez ser verdadeira). So n operaes bsicas.
A varivel de controle i ser incrementada n 1 vezes. So n 1 operaes bsicas.
Nmero total de operaes bsicas: 2 + n + (n 1) 2n + 1.
Essa anlise independe da qualidade da entrada, portanto o resultado vlido para todos os casos. O
mesmo se aplica para as linhas 2, 3 e 7.
Linha 2, qualquer caso: atual = A[i]
Nessa linha h uma indexao e uma atribuio. So 2 operaes bsicas. A linha ser executada n
1 vezes. Operaes bsicas: 2 (n 1) 2n 2.
Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

45

Linha 3, qualquer caso: j = i-1


Nessa linha h uma subtrao e uma atribuio. So 2 operaes bsicas. A linha ser executada n 1
vezes. Operaes bsicas: 2 (n 1) 2n 2.
Linha 4, melhor caso: enquanto j>=0 e A[j]>atual faa
Nessa linha h 4 operaes bsicas: duas comparaes, uma indexao e uma operao lgica e.
No melhor caso, A[j]>atual ser sempre falso, portanto a condio de repetio do enquanto ser
falsa logo de incio. Assim, os comandos dentro do enquanto no sero executados nenhuma vez.
Essa linha ser executada n 1 vezes. Operaes bsicas: 4 (n 1) 4n 4.
Linhas 5 e 6, melhor caso:
No importa quantas operaes bsicas haja nesses comandos. Vimos que, no melhor caso, os
comandos dentro do enquanto no sero executados nenhuma vez, portanto o nmero total de
operaes bsicas nessas linhas 0.
Linha 4, pior caso: enquanto j>=0 e A[j]>atual faa
Vimos que nessa linha h 4 operaes bsicas.
No pior caso, A[j]>atual ser sempre verdadeiro, portanto a condio de repetio do enquanto s
ser falsa quando j>=0 for falso. Na linha 3 j inicializado com o valor i 1, de modo que temos:

Iterao do
para na linha 1
primeira
segunda

ltima

j varia de

at

1
2

n1

0
1

n2

1
1

Total
2

Vezes que a linha 4


ser executada

Vezes que os comandos


dentro do enquanto
sero executados

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

Operaes bsicas na linha 4, no pior caso: 4 (n + n 2) / 2 2n + 2n 4.


Linha 5, pior caso: A[j+1] = A[j]
Nessa linha h uma adio, duas indexaes e uma atribuio. So 4 operaes bsicas. Vimos que,
2
no pior caso, os comandos dentro do enquanto sero executados (n n) / 2 vezes. Operaes
2
2
bsicas na linha 5, no pior caso: 4 (n n) / 2 2n 2n.
Linha 6, pior caso: j = j-1
Nessa linha h uma subtrao e uma atribuio. So 2 operaes bsicas. Vimos que, no pior caso, os
2
comandos dentro do enquanto sero executados (n n) / 2 vezes. Operaes bsicas na linha 6, no
2
2
pior caso: 2 (n n) / 2 n n.
Linha 7, qualquer caso: A[j+1] = atual
Nessa linha h uma adio, uma indexao e uma atribuio. So 3 operaes bsicas. A linha ser
executada n 1 vezes. Operaes bsicas: 3 (n 1) 3n 3.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

46

Exerccio 6.14
Algoritmo: selectionSort (A, n)
Entrada: array A com n elementos
Sada: array A em ordem crescente

Linha

Melhor caso

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

NOTA: A identao mostra o escopo dos comandos:


o para na linha 2 est dentro do para na linha 1,
o se na linha 3 est dentro do para na linha 2, e
as linhas 4 a 6 esto dentro do se na linha 3.

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

Linha 1, qualquer caso: para i de 0 at n-2 faa


As inicializaes equivalem a 2 operaes bsicas: atribuio de 0 a i e clculo de n 2. Essas
operaes so executadas uma nica vez.
No comando para temos primeiro um teste da condio de parada; se a condio for falsa, o lao
executado uma vez e, ao final, a varivel de controle incrementada.
Neste comando para, i varia de 0 a n 2. A condio de parada ser testada n vezes: n 1 vezes ela
ser falsa e na ltima vez ser verdadeira. So n operaes bsicas.
A varivel de controle i ser incrementada n 1 vezes. So n 1 operaes bsicas. Esse tambm o
nmero de vezes que este lao e os comandos dentro dele sero executados.
Nmero total de operaes bsicas: 2 + n + n 1 2n + 1. Essa anlise independe da qualidade da
entrada, portanto o resultado vlido para todos os casos.
Linha 2, qualquer caso: para j de i+1 at n-1 faa
As inicializaes equivalem a 3 operaes bsicas: clculo de i + 1, atribuio do resultado a j e clculo
de n 1. Lembrando que esta linha executada n 1 vezes por causa do comando para na linha 1,
conclumos que essas operaes equivalem a 3n 3 operaes bsicas.
Neste comando para, j varia de i + 1 at n 1. A condio de parada ser testada, e resultar falsa, (n
1) (i + 1) + 1 vezes; s no prximo teste ser verdadeira. O total de testes ser ento (n 1) (i + 1)
+ 1 + 1 n i. So n i operaes bsicas para cada valor de i, determinado pelo lao externo.
A varivel de controle j ser decrementada n i 1 vezes. So n i 1 operaes bsicas para cada
valor de i, determinado pelo lao externo. Esse tambm o nmero de vezes que o lao da linha 3 e os
comandos dentro dele (comando se da linha 3) sero executados.
medida que o valor de i aumenta (comando para da linha 1), o teste da condio de parada e o
incremento de j so executados menos e menos vezes:
Iterao
do para
na linha 1
primeira
segunda
terceira

penltima
ltima

j varia
de i + 1
at n 1

0
1
2

n3
n2

1
2
3

n2
n1

Total

Vezes que ser executado...


o teste da condio de
parada na linha 3: n i

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

Nmero total de operaes bsicas na linha 2: 3n 3 + (n + n) / 2 1 + (n n) / 2 n + 3n 4.


Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

47

Linha 3, qualquer caso: se A[j] < A[min] ento


Nessa linha h duas indexaes e uma comparao. So 3 operaes bsicas. A linha ser executada
2
2
2
(n n) / 2 vezes. Operaes bsicas: 3 (n n) / 2 3/2 n 3/2 n.
Linhas 4, 5 e 6, melhor caso:
No melhor caso o array j estar ordenado, de modo que a condio do comando se ser sempre falsa.
Portanto, os comandos dentro do se no sero executados nenhuma vez. Assim, no importa quantas
operaes bsicas haja nesses comandos; o total de operaes bsicas nessas linhas 0.
Linha 4, pior caso: temp = A[i]
Nessa linha h uma indexao e uma atribuio. So 2 operaes bsicas. Vimos que, no pior caso, os
2
comandos dentro do se sero executados (n n) / 2 vezes. Operaes bsicas na linha 4, no pior
2
2
caso: 2 (n n) / 2 n n.
Linha 5, pior caso: A[i] = A[min]
Nessa linha h duas indexaes e uma atribuio. So 3 operaes bsicas. Vimos que, no pior caso,
2
os comandos dentro do se sero executados (n n) / 2 vezes. Operaes bsicas na linha 5, no pior
2
caso: 3 (n n) / 2.
Linha 6, pior caso: A[min] = temp
Nessa linha h uma indexao e uma atribuio. So 2 operaes bsicas. Vimos que, no pior caso, os
2
comandos dentro do se sero executados (n n) / 2 vezes. Operaes bsicas na linha 6, no pior
2
2
caso: 2 (n n) / 2 n n.

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.

Portanto, as respostas s perguntas so:


1) No. 2) No. 3) Sim, o algoritmo 1. 4) No. 5) Sim, o algoritmo 2.

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

Estruturas de Dados Listas de exerccios e solues

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

Isso significa que, entre n1 e n2 , T1 maior do que T2. Em resumo:

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)

T1(n) = n2 600n 1.5 105


T2(n) = 2n2 1200n 2 105

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.

Assim, as respostas s perguntas so:


1) n 100 e n 500
2) 100 n 500
3) n = 100 e n = 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

T2(n) e calculamos a raiz do polinmio resultante:


3
2
2
T1(n) = T2(n) n 59n + 1060n 4700 = n 40n + 1300
3
2
n 60n + 1100n 6000 = 0
Usando a dica fornecida, podemos escrever:

a + b + c = 60
ab + bc + ac = 1100
abc = 6000

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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)

T1(n) = n3 59n2 1060n


T2(n) = n2 40n

1400
1200
1000

4700
1300

(30, 1000)
(10, 1000)
(20, 900)

800
600
400
200

n
5

10

15

20

25

30

35

Isso significa que, entre n = 10 e n = 20 , T1 menor do que T2. Em outras palavras:

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.

Assim, as respostas s perguntas so:


1) O algoritmo 1 mais rpido que o 2 para entradas de tamanho menor que 10 ou entre 20 e 30.
2) O algoritmo 2 mais rpido que o 1 para entradas de tamanho entre 10 e 20 ou maiores que 30.
3) Os dois algoritmos executam no mesmo tempo para entradas de tamanho igual a 10, 20 e 30.
Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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)

O grfico ao lado mostra que

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

Paulo Costa 2013

0.5

0.75

1.25

n
4

Estruturas de Dados Listas de exerccios e solues

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

As razes de f(n) so as mesmas de f (n). Podemos deduzi-las facilmente fatorando f (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.

b) O maior valor inteiro de c1 que nos permite provar que f (n) = (n ) 9.


Terceira pergunta: Se usarmos c1 = 5 e c2 = 20 na definio de , obtemos

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

A soluo dessa inequao 0 n 7,6 e n 52,4. Contudo, a definio de


portanto a soluo da primeira inequao 0 n 7,6 e n 52,4.

afirma que 0 n0 n ,

Resolvendo a segunda inequao:

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

A soluo dessa inequao 35,6 n 0 e n 5,6. Contudo, a definio de afirma que 0 n0 n ,


portanto a soluo da segunda inequao apenas n 5,6.
Juntando os resultados parciais:
A interseo entre as solues das duas inequaes 5,6 n 7,6 e n 52,4. Assim, o menor valor

inteiro de n0 que nos permite provar que f (n) = (n ) 53.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

52

Exerccio 6.20
3

O problema consiste em definir c1, c2 e n0 0 | 0 c1 n 8n 300n + 40n c2 n para todo n n0.


3
3
2
Dividindo por n obtemos c1 f(n) c2 onde f(n) = f(n)/n = 8 300/n + 40/n
2

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

, c1 f(n), portanto a faixa de

3) O grfico 2 mostra que


. Segundo a definio de
valores de c2 que satisfazem a definio de [8, ).

, c2 f(n), portanto a faixa de

4) Agora c1, c2 e n0, alm de 0, so nmeros inteiros, ou seja, c1, c2 e n0 1


2

c1 f(n) 1 8 300/n + 40/n n 8n 300n + 40 7n 300n + 40 0


O grfico 3 mostra que a maior raiz desse polinmio 42,72. Como n0 um nmero inteiro, o menor
valor de n0 que satisfaz a definio de para quaisquer inteiros c1 e c2 0 43. Logo, a faixa de
valores de n0 que satisfazem a definio de [43, ).
5) O grfico 2 mostra que
. Segundo a definio de
valores de c1 que satisfazem a definio de [1, 7].

, c1 f(n), portanto a faixa de

6) O grfico 2 mostra que


. Segundo a definio de
valores de c2 que satisfazem a definio de [8, ).

, c2 f(n), portanto a faixa de

7) Definir c1, c2 e n0 0 | c1 n 8n 300n + 40n c2 n para todo n n0


3

c1 n 8n 300n + 40n c2 n c1 8 300/n + 40/n c2

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.

n0 no pode ser 37 pois c1 deve ser 1


n0 no pode ser 40 pois c1 deve ser 1
n0 no pode ser 42 pois c1 deve ser 1
n0 = 43,
c1 = 1, c2 = 8
n0 = 50,
c1 = 2, c2 = 8
n0 = 100, c1 = 5, c2 = 9
n0 = 300, c1 = 6, c2 = 10
n0 = 3000, c1 = 7, c2 = 11
Os conjuntos de constantes c1, c2 e n0
listados acima tornam a inequao vlida,
3
2
3
provando que 8n 300n + 40n = (n ).

8) O grfico abaixo mostra que f(n) = (n ). Foram usadas as constantes: n0 = 43, c1 = 1, c2 = 8.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

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

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

B
G

K
P

D
L

H
R

C
E
J

I
N

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Inicialize um contador global com 0.


Inicie o caminhamento de Euler da rvore a partir da raiz.
Ao visitar um n v pela esquerda, incremente o contador e guarde esse valor no n ( v.cesq).
Ao visitar um n v pela direita, guarde o valor do contador no n (v.cdir).
Ao final do caminhamento, o nro de descendentes de um n v dado por v.cdir v.cesq + 1.
Tempo de execuo: O(n).

Exerccio 8.16

Inicie o caminhamento de Euler da rvore a partir da raiz.


Ao visitar um n v pela esquerda: se o n interno, imprima (.
Ao visitar um n por baixo: imprima o valor ou o operador armazenado no n.
Ao visitar um n v pela direita: se o n interno, imprima ).

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

106 120 144 157 172 198

Exerccio 8.18
100
54

163

27

86

10
6

40
19

Paulo Costa 2013

31

66
49

59

133
97

71

115

198
150

180

223

106 120 144 157 172 190 200 243

Estruturas de Dados Listas de exerccios e solues

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.

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Estruturas de Dados Listas de exerccios e solues

61

10. Tabelas Hash


Exerccio 10.1
Cdigo hash
Entrada Uma chave
Um inteiro
Sada
Objetivo

Funo de compresso
O inteiro produzido pelo cdigo hash
Um inteiro no intervalo [0, N 1]

Transformar a chave em um inteiro que


possa ser convertido pela funo de
compresso em um ndice no array A

Transformar o inteiro produzido pelo cdigo


hash em um ndice no array A, dispersando as
chaves de maneira aparentemente aleatria

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

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

56

12

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

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

Paulo Costa 2013

Estruturas de Dados Listas de exerccios e solues

65

You might also like