Buscar

Estrutura de dados

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 26 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 26 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 26 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Introdução aos tipos abstratos de dados 
 
1. O tipo de dado que representa números é muito utilizado em programação; logo, é 
sua correta utilização durante o desenvolvimento de uma aplicação é fundamental. 
Suponha que você esteja analisando os tipos de dados para a implementação de uma 
aplicação voltada à contabilidade. Durante essa análise, você questiona qual tipo de 
dados uma variável deve utilizar para representar o número 10, visando à redução do 
custo de memória do computador. 
Você acertou! 
A. Int. 
O tipo int é utilizado exclusivamente para números naturais. 
O char é utilizado para representar um caractere. As demais opções (long int, 
double e float) fazem uso de mais memória em comparação ao int. 
2. Os tipos de dados booleanos têm características específicas em relação aos outros tipos 
de variáveis. A partir dessa afirmação, identifique a alternativa que apresenta um exemplo 
de dados booleanos: 
Você acertou! 
A. Verdadeiro ou falso. 
Dados booleanos são utilizados exclusivamente para demonstrar um estado em 
contraposição a outro, como verdadeiro/falso. 
O tipo booleano não poderá receber valores numéricos ou palavras, como as demais opções 
(Rua Paulista; 2,5; 10; 01/12/2019). 
3. Programas de computador fazem uso de diversas variáveis e operações. Em qual momento 
uma variável ocupa a memória do computador? 
Você acertou! 
C. Durante a execução do programa. 
As variáveis somente existem quando o programa está em execução, pois nesse momento 
está sendo utilizado um bloco de memória do computador. 
Durante a finalização do programa, a memória deverá ser liberada, e não alocada. Durante o 
desenvolvimento do programa ou a compilação, é verificada a estrutura do código, e não a 
alocação da variável em memória. 
4. A utilização de variáveis que consomem pouca memória é de suma importância para o 
desenvolvimento de aplicações com hardware limitado. Por isso, você precisa poupar 
memória no sistema de presença de uma universidade, na qual os computadores utilizados 
serão reciclados pelos alunos de anos iniciais. A partir das informações anteriores, qual tipo 
de variável deve ser utilizado para representar uma única letra do alfabeto visando à redução 
do custo de memória do computador? 
Você acertou! 
B. Char. 
Para a representação de um único caractere, seja ele uma letra, um símbolo ou um número, 
usa-se o tipo char. 
O tipo string é capaz de representar uma lista de elementos maiores que um caractere. Os 
tipos int, float e double são utilizados para representar números. 
5. Durante o desenvolvimento de uma aplicação, faz-se uso de diferentes tipos de dados. Na 
definição de tipos abstratos de dados (TAD), faz-se referência ao par (v,o). Qual é o 
significado desse par? 
Você acertou! 
C. (variável, operação). 
Formalmente, pode-se definir TAD como um par (v,o), em que ‘v’ representa uma ou mais 
variáveis, e ‘o’ , uma ou mais operações. 
 
 
Listas sequenciais: estáticas e dinâmicas 
 
1. A linguagem Python possibilita a armazenagem de diferentes tipos de dados em um 
mesmo vetor. A partir desse contexto, um programador implementou o seguinte código: 
#declaração do vetor 
Aluno = ['A',20,60,'casa',3] 
print(Aluno[-1]) 
Qual será a saída do programa? 
Você acertou! 
E. 3. 
Em Pyhon, o programador poderá acessar cada elemento de forma individual e circular, 
logo, a posição -1 representa o último elemento do vetor. 
Posição ==> Conteúdo 
0 ou -5 ==> A 
1 ou -4 ==> 20 
2 ou -3 ==> 60 
3 ou -2 ==> casa 
4 ou -1 ==> 3 
 
2. A linguagem Python possibilita o acesso direto a um elemento de um vetor. O índice de 
acesso tem o comportamento circular. A partir dessa afirmação, no vetor abaixo, qual o 
índice correspondente à primeira posição 0 (zero)? vetor = ['A','B','C','D','E'] 
Você acertou! 
C. -5. 
A posição correspontende à posição zero é a -5, de acordo com a tabela abaixo: 
Posição ==> Conteúdo 
0 ou -5 ==> A 
1 ou -4 ==> B 
2 ou -3 ==> C 
3 ou -2 ==> D 
4 ou -1 ==> E 
3. O vetor deverá corresponder a uma lista de elementos na qual cada nodo deverá 
armazenar uma informação. A partir dessa informação, qual é a posição ocupada pelo último 
elemento do vetor a seguir? vetor = [1,2,5,7,9] 
Você acertou! 
B. 4. 
As posições de um vetor são numerados a partir do valor zero, sendo zero para o primeiro 
elemento e, consequentemente, aos demais elementos do vetor. 
Posição ==> Conteúdo 
0 ou -5 ==> 1 
1 ou -4 ==> 2 
2 ou -3 ==> 5 
3 ou -2 ==> 7 
4 ou -1 ==> 9 
4. A lista encadeada é muito utilizada para armazenar um número indefinido de elementos. 
Em uma lista encadeada simples, cada nodo possui duas informações. Quais são elas? 
Você acertou! 
A. Conteúdo e índice do próximo nodo. 
Uma lista encadeada simples possui sempre o seu conteúdo e o seu endereço de memória 
(índice) do próximo nodo. Os nodos não têm o conhecimento do seu respectivo lugar na lista, 
ou seja, não sabem a sua origem ou nodo anterior, pois não armazenam essa informação; são 
independentes e desconhecem o tamanho da lista. 
5. As listas encadeadas simples e os vetores têm diversas vantagens e desvantagens 
comparadas entre si. Qual das informações a seguir é uma vantagem das listas encadeadas 
simples, se comparada a vetores? 
Você acertou! 
C. Têm o seu tamanho flexível em tempo de execução. 
As listas encadeadas simples têm em seu nodo o seu respectivo conteúdo e o endereço de 
memória do próximo, logo ocupam mais memória que um vetor; poderão aceitar elementos 
durante a sua utilização definidos pelo usuário, desde tipos primitivos a abstratos, criados pelo 
programador; e, por não terem tamanho fixo ou previamente definido, não poderão ser 
listadas por comando for predeterminado, havendo a necessidade de adicionar um break. 
Listas encadeadas simples 
1. A análise e o desenvolvimento de algoritmos com o uso de listas encadeadas são de suma 
importância no desenvolvimento de uma aplicação. Durante essa ação, o desenvolvedor 
precisa realizar a análise prévia dos códigos de uma determinada aplicação para iniciar seu 
desenvolvimento. 
Analise o algoritmo a seguir e marque a alternativa que representa seu significado: 
def acao(self,item): 
 atual = self.inicio 
 status = False 
 while atual != None and not status: 
 if atual.dado()==item: 
 status = True 
 else: 
 atual = atual.prox() 
 return status 
Você acertou! 
C. Procura um elemento na lista. 
O algoritmo inicia com o apontamento para o início da lista e declara uma variável como 
Falso. No segundo momento (comando While), percorre a lista enquanto não chegar ao 
seu final e o status for diferente de Falso. Dentro do laço com o comando IF, verifica se 
o dado recebido na função encontra-se no Nodo; caso afirmativo, troca o status para True, 
informando que encontrou o valor. 
Ao final, retorna o status se encontrou ou não o conteúdo na lista. 
2. A lista simplesmente encadeada é uma lista do tipo dinâmica e apresenta vantagens em 
relação a listas estáticas, como vetores. A partir da afirmação anterior, marque a opção que 
informa uma das vantagens das listas simplesmente encadeadas. 
Você acertou! 
B. Permitem variação de seu tamanho em tempo de execução. 
Uma lista simplesmente encadeada permite o aumento e a redução do número de 
elementos em tempo de execução, sem precisar alocar posições contínuas de memória, como 
corre em listas estáticas. Na lista encadeada não existe busca de acordo com a indexação, pois 
a pesquisa é realizada sequencialmente a partir do primeiro elemento, Nodo. A inserção e a 
remoção de elementos podem ser realizadas em qualquer posição, sem a necessidade de 
reordenação dos demais elementos, mas, apesar disso, requerem percorrer nodo a nodo até 
sua posição. 
 
3. A análise e o desenvolvimento de algoritmos com o uso de listas encadeadas são de suma 
importância no desenvolvimento de uma aplicação. Durante essa ação, o desenvolvedor 
precisa realizar a análise prévia dos códigos de uma determinada aplicação para iniciar seu 
desenvolvimento. Analiseo algoritmo a seguir e marque a alternativa que representa seu 
significado: 
 
 
1 def acao (self,item) 
2 temp = No(item) 
3 temp.prox(self.ini) 
4 self.ini = temp 
Você acertou! 
B. Adiciona um novo elemento no início da lista. 
A função, na linha 1, recebe como parâmetro um valor que será utilizado internamente. Na 
linha 2, realiza a criação de um No com o dado recebido. Na linha 3, realiza a atualização do 
ponteiro prox para o primeiro elemento da lista. Na linha 4, adiciona o ponteiro do início da 
lista para o novo No, inserindo o elemento sempre no início da lista. 
4. A lista simplesmente encadeada é uma lista do tipo dinâmica e apresenta vantagens em 
relação a listas estáticas, como vetores. A partir dessa afirmação, marque a opção que 
informa um tipo de lista em que é mais apropriado utilizar listas simplesmente encadeadas 
em detrimento de listas do tipo estáticas, como vetores. 
Você acertou! 
C. Listas grandes que realizam diversas inserções em diferentes posições. 
Uma lista simplesmente encadeada é recomendada para utilização em grandes listas, que 
podem ter muitas inserções e exclusões em quaisquer posições, cujo tamanho é indefinido. 
Por ser uma lista dinâmica, não tem sua pesquisa indexada e a varredura ocorre apenas em 
uma direção, pois possui somente o apontamento para o próximo elemento da lista. 
5. As listas simplesmente encadeadas possuem características únicas em seus nodos, 
diferentemente das listas estáticas. Em relação a essas características únicas, leia as 
alternativas a seguir e selecione a correta. 
Você acertou! 
D. O nodo tem seu conteúdo definido pelo usuário e um ponteiro para o próximo elemento. 
Uma lista simplesmente encadeada possui em seu nodo uma variável com a posição de 
memória do próximo elemento, bem como seu respectivo conteúdo. Devido a essa 
característica, seu armazenamento não precisa ser linear em memória, pois armazena a 
localização do próximo nodo. 
 
Implementação de listas encadeadas simples 
1. A análise de códigos é de suma importância para o desenvolvimento de um programador, 
sendo uma das tarefas mais comuns no seu dia a dia, seja na compreensão do 
desenvolvimento complementar, seja durante os seus estudos. 
Realize a análise do código a seguir e assinale a alternativa que contém o seu objetivo: 
def Metodo(self): 
atual = self.inicio 
self.inicio = atual.proximo 
Você acertou! 
C. Realizar a exclusão do primeiro nodo. 
Método que realiza a remoção do primeiro elemento: 
def Remove_Inicio(self): 
#Realiza a atribuição do início da lista para um o nodo atual. 
atual = self.inicio 
#Atualiza o primeiro elemento da lista para o elemento posterior ao primeiro nodo, excluindo 
o nodo inicial. 
self.inicio = atual.proximo 
 
 
 
 
2. As operações de manipulação de uma lista simplesmente encadeada permitem a 
manipulação de seus nodos durante sua execução. Analise o código a seguir e informe qual 
o seu objetivo: 
def Metodo(self): 
atual = self.inicio 
if self.inicio == None: 
 print("none") 
else: 
 while atual != None: 
 print(atual) 
 atual = atual.proximo 
Você acertou! 
C. Realizar a impressão de uma lista. 
#Realiza a impressão de todos os elementos de uma lista def Impressão(self): 
#Ponteiro atual recebe o início da lista: 
atual = self.inicio 
#verifica se a lista encontra-se vazia e informa o usuário if self.inicio == None: 
print("none") 
#Caso a lista tenha conteúdo, percorre toda a lista e imprime em cada interação o seu 
respectivo conteúdo. else: 
while atual != None: 
print(atual) 
atual = atual.proximo 
3. O desenvolvimento de listas encadeadas pode ser realizado de diversas formas, com ou 
sem o uso de bibliotecas. O método da biblioteca de listas chamado append(Elemento) realiza 
qual função no código? 
Você acertou! 
B. Adiciona um elemento ao final da lista. 
#Código em Python: 
 # Lista de letras 
 letras= ['A', 'H', 'T'] 
 # Metodo que adiciona a letra D no final da lista 
 animais.append('D') 
 # imprime a nova lista 
 print('Atualização da lista: ', letras) 
#Saída do programa 
 # Atualização da lista: ['A', 'H', 'T','D'] 
4. As bibliotecas utilizadas em programação auxiliam no desenvolvimento de listas 
simplesmente encadeadas. O método da biblioteca de listas chamado index(Elemento) realiza 
qual função no código? 
Você acertou! 
D. Retorna à posição da primeira ocorrência do elemento na lista. 
• #Código em Python: 
 # Lista de letras 
 letras = ['A', 'G', 'P','G'] 
 # imprime a lista 
 print(letras) 
 # Retorna e imprime a posição da primeira ocorrência do elemento G 
print(letras.index('G')) 
#Saída do programa 
 # ['A', 'G', 'P','G'] 
 #1 
5. Os métodos para a criação das classes nodo, lista encadeada, verificação de lista vazia, 
adicionar e remover posição na lista são elementos básicos no que se refere à implementação 
de listas encadeadas simples. Analise o código a seguir e informe qual o seu objetivo: 
def Metodo(Lista): 
 if Lista.inicio == None : 
 return True 
 else: 
 return False 
Você acertou! 
C.Verificar se a lista está vazia. 
#Método que verifica se a lista está Vazia, Caso positivo Retorna True caso contrário False. 
def ListaVazia(Lista): 
# Verifica se o ponteiro para o início da lista está vazio, se positivo retorna True, logo lista 
vazia. 
if Lista.inicio == None : 
return True 
#Caso o item anterior seja falso, retorna Falso, logo lista contém itens na lista. 
 else: 
return False 
 
 
Listas encadeadas duplas 
1. Uma lista duplamente encadeada tem como estrutura duas referências, o que permite que 
a lista seja percorrida em dois sentidos: do início ao fim e do fim ao início. Atendendo a essa 
propriedade, dos exemplos a seguir, quais se aplicam para uma lista duplamente encadeada? 
Você acertou! 
B. Sistemas de paginação web, comandos de desfazer (CTRL + Z) e refazer (CTRL + SHIFT + 
Z) operações, lista de espera de compras e visualizador de imagens. 
As listas duplamente encadeadas são bem aplicadas em problemas em que seja 
necessário realizar operações de navegação entre elementos do início ao fim e do fim para o 
início, como no caso de sistemas de paginação web, comandos de desfazer (CTRL + Z) e 
refazer (CTRL + SHIFT + Z) operações, lista de espera de compras, visualizador de imagens 
e playlist de músicas. 
Os exemplos sistema de georreferenciamento, sorteio de número aleatório, fila de 
atendimento, paginação unilateral, soma de dois números e ordenação de números não 
necessitam dessa estrutura de dados, além de não ser possível armazenar dados não 
sequenciais nessas listas. 
 
 
2. As listas duplamente encadeadas apresentam algumas características que precisam ser 
bem definidas para o seu adequado funcionamento. Quais são essas características? 
Você acertou! 
A. Definir um ponteiro para o primeiro e o último elemento da lista; o ponteiro anterior, 
referente ao primeiro elemento da lista, aponta para um endereço NULO; e o último 
elemento aponta para um endereço NULO. 
Uma lista duplamente encadeada pode armazenar tanto dados primitivos como estruturas de 
dados abstratos, e não necessita de ordenação em seus elementos. As principais 
características para o seu bom funcionamento são: 
Definir um ponteiro para o primeiro e o último elemento da lista; o ponteiro anterior, 
referente ao primeiro elemento da lista, aponta para um endereço NULO; e o último elemento 
aponta para um endereço NULO. 
3. Com uma lista duplamente encadeada implementada sobre um vetor ou alocação 
dinâmica, é possível definir algumas ações para o gerenciamento dos elementos contidos 
nela. Quais são essas ações? 
Você acertou! 
E. Percorrer elementos, inserir elemento, remover elemento e buscar elemento. 
Para gerenciar os dados de uma lista duplamente encadeada, as ações definidas são: percorrer 
elementos, inserir elemento, remover elemento e buscar elemento. As demais ações citadas 
são possíveis de se realizar com pequenasoperações, sem necessidade de implantá-las 
na lista. 
4. Entre as ações de uma lista duplamente encadeada, está a inserção. A inserção de um 
elemento em uma lista dupla pode ser realizada de três maneiras. Quais são essas maneiras? 
Você acertou! 
C. No início da lista, em alguma posição intermediária e no final da lista. 
Sempre que algum elemento for adicionado à lista, é importante que sejam mantidas as 
ligações de referências dos apontadores para os elementos anteriores e posteriores. Logo, é 
possível realizar a inserção de três formas: no início da lista, em alguma posição intermediária 
e no final da lista. 
As demais operações, tais como ordenadamente e aleatoriamente, não são formas de 
inserção, mas sim de possíveis operações. 
5. Cada projeto carrega sua particularidade, assim, uma lista pode conter vários métodos 
associados a ela, alguns mais conhecidos, como: criar uma lista vazia, verificar se a lista está 
vazia, verificar se a lista está cheia, entre outros. Nesse contexto, para a inserção de um 
elemento nas listas duplamente encadeadas, quais critérios devem ser atendidos? 
Você acertou! 
A. Verificar se existe espaço, adicionar o contador de itens e alocar um espaço para inserir 
um novo elemento. 
A inserção de elementos nas listas duplamente encadeadas pode ser realizada de três formas: 
início, intermédio e final. Além disso, deve atender a alguns critérios, tais como: verificar se 
existe espaço para inserir um novo elemento; acomodar um espaço para inserir um novo item 
e assegurar que os outros elementos não ficarão com uma referência vazia, a menos que os 
elementos sejam incluídos no final da lista; e adicionar o contador de itens. As outras opções 
citadas são critérios desnecessários. 
 
Implementação de listas encadeadas duplas 
 
1. Existem várias formas de implementar as listas duplas. Entre os tipos, há as listas duplas 
com cabeça fixa. Logo, qual seria a vantagem em utilizar listas com cabeça fixas? 
Você acertou! 
A. Listas com cabeça fixa permitem e carregam sempre seu valor em seu início, não 
necessitando de ponteiros como início e fim. 
Listas com cabeça fixa não precisam recorrer a mais elementos de uma lista, como os 
ponteiros nomeados como início e fim, por exemplo, para poder percorrê-la, pois seu 
endereço já carrega o início da lista consigo. 
Logo, o endereço nomeado como cabeça fixa não deve também conter nenhuma informação, 
sendo apenas uma sentinela para acessar o primeiro elemento que contenha informação em 
uma lista. 
Uma das propriedades das listas de cabeça fixa é que seu ponteiro anterior aponte para 
uma referência nula. Além disso, funções básicas de inserção, remoção e impressão, etc., 
permanecem. 
 
 
2. As listas duplas são vistas como vias de mão dupla, em que é possível percorrê-las em duas 
direções. Uma vez implementada, como transformá-la em uma lista circular? 
Você acertou! 
D. Para que uma lista dupla seja circular, o endereço de próximo do último elemento deve 
apontar para o primeiro, e o endereço nulo apontado pelo ponteiro anterior do primeiro 
elemento, deve apontar para o último. 
O que diferencia as listas circulares de outras é que nelas o último elemento aponta para o 
primeiro e vice-versa, em caso de ponteiros duplos, não fazendo referência a endereços 
nulos, mesmo que exista apenas um elemento. 
3. Fazer a análise de um algoritmo, por natureza, envolve entender a sua complexidade. 
Por que as funções de inserção têm complexidade O(1) e remoção O(n) para os piores casos? 
Você acertou! 
B. De forma intuitiva, a inserção é feita de forma direta O(1), enquanto a remoção depende 
de percorrer (n) elementos na lista. 
Antes da remoção, é realizada a busca do elemento, tendo no pior caso que percorrer uma 
somatória de elementos, ou seja, por todos os elementos; enquanto a inserção é feita de 
modo direto, sem a necessidade de passar por nenhum elemento anterior, justamente pelos 
ponteiros de referência início e fim. 
4. Os problemas computacionais têm entradas bem estabelecidas, restrições e condições 
que satisfazem os valores de saída. As listas duplamente encadeadas podem ser usadas de 
acordo com a necessidade de cada problema, devido aos aspectos de uma lista. 
As listas podem ter diferentes aspectos, quais são esses aspectos? 
Você acertou! 
E. Tipo de informação: pode armazenar qualquer tipo de informação; ordem dos 
elementos: conforme a política de negócio; homogeneidade da informação: os elementos de 
uma lista podem ser representados pelo mesmo tipo de dado ou armazenar tipos de dados 
diferentes. 
As listas podem ter diferentes aspectos, tais como: 
Tipo de informação: neste caso, a lista pode armazenar qualquer tipo de informação, como 
nome, endereço, contatos, entre outros elementos existentes no mundo real. 
Ordem dos elementos: aqui, varia conforme a política de negócio, podendo estar em ordem 
de inserção, em ordem crescente ou decrescente, etc. 
Homogeneidade da informação: todos os elementos de uma lista podem ser representados 
pelo mesmo tipo de dado (inteiro, string ou uma classe criada), ou armazenar tipos de dados 
diferentes. Em linguagens fracamente tipadas, como Python e PHP, por exemplo, este 
comportamento é visto com maior naturalidade. 
Os demais aspectos não fazem ou não são comportamentos de uma lista duplamente 
encadeada: tipo do problema, complexidade, forma da lista ou linguagem de programação. 
5. Entre os diversos tipos de listas duplamente encadeadas, existe uma versão chamada de 
lista encadeada XOR. Em relação a uma lista duplamente encadeada simples, qual a principal 
característica de uma lista encadeada XOR? 
Você acertou! 
C. Armazenar endereços de memória reais; cada nó armazena o XOR dos endereços dos nós 
anteriores e dos próximos, necessitando de apenas um espaço de memória. 
Uma versão com eficiência de memória da lista duplamente vinculada pode ser criada usando 
apenas um espaço para o campo de endereço em cada nó. Essa lista vinculada duplamente 
eficiente em memória é chamada de lista vinculada XOR ou memória eficiente, pois a lista usa 
a operação XOR bit a bit para economizar espaço para um endereço. 
As listas duplamente encadeadas seguem a propriedade que, a partir de um determinado 
elemento, seja possível tanto avançar quanto voltar, logo, as outras opções estão incorretas. 
 
 
Implementação de Pilhas em Python 
1. A pilha é uma estrutura que permite a inserção e a remoção dos dados utilizando-se de 
regras predefinidas. Essas operações são realizadas por meio de duas funções: push e pop. 
Sabendo disso, considere que um programa tenha uma pilha a, inicialmente vazia, e que as 
seguintes operações foram realizadas: PUSH(a, 10); PUSH(a, 5); PUSH(a, 3); PUSH(a, 50); 
POP(a); PUSH(a, 11); PUSH(a, 9); PUSH(a,20); POP(a); POP(a). 
Ao final, quais serão o topo da pilha e o somatório dos elementos ainda dentro da pilha, 
respectivamente? 
Você acertou! 
B. 11 e 29. 
Considerando a execução de cada um dos comandos na sequência apresentada, 11 é o valor 
final do topo, e a somatória dos elementos restantes será: 11+3+5+10= 29. 
2. Sabendo que a pilha é uma estrutura que utiliza um único caminho para a entrada e a saída 
de seus elementos, sendo esse o topo da pilha, considere que os números 10, 11, 12, 13 e 
14 foram inseridos nessa ordem. Então, nesse caso: 
Você acertou! 
C. o número 14 é o primeiro elemento a ser removido da pilha. 
Como a pilha utiliza-se do modelo last in, first out, e o número 14 foi o último a ser inserido, 
ele é o primeiro a ser removido. 
3. Estruturas de dados, como pilhas e filas, são utilizadas em diversas aplicações, tendo cada 
uma delas comandos e funções específicas para a manipulação dos elementos que as 
compõem. Assim sendo, qual método é de uso da estrutura de pilha? 
Você acertou! 
C. Push(x), que insere o elemento x no topo da pilha sem sobrepor nenhum elemento. 
Push(x) é a função correta para a inserção de novos elementos em uma pilha, sem a 
sobreposição dos elementos já existentes, ajustando o novoelemento com os demais na 
pilha. 
Stack() cria uma pilha vazia. 
Dequeue() remove e retorna o item do início da fila. Um item não pode ser retirado de uma 
fila vazia. 
Pop() remove e retorna o item superior da pilha se a pilha não estiver vazia. 
Top() não é uma função válida em Python. 
 
 
 
 
 
 
 
 
 
 
 
4. mas Todas as estruturas de dados têm o que chamamos de local para entrada e saída de 
dados, e com as pilhas não é diferente, sendo esse local o seu topo. Sabendo disso, considere 
os estados inicial e final da pilha apresentada a seguir: 
 
 
 
 
 
 
 
 
 
 
 
 
Você acertou! 
A. Pop(), Pop(), Push(9), Push(3). 
Se todos os comandos forem executados nesta mesma ordem - Pop(), Pop(), Push(9), Push(3), 
a pilha será exibida no estado final, sendo removidos os itens 2 e 8, e inseridos 3 e 9. 
5. Px é uma pilha com 5 posições, v(1) a v(5), na qual v(5) é o topo. De v(1) até v(5), a pilha Px 
está preenchida, respectivamente, com os símbolos Q5, Q3, Q1, Q4, Q2. Há mais duas pilhas, 
inicialmente vazias, Py e Pz, com o mesmo tamanho. Qual é a quantidade mínima de 
movimentos entre as três pilhas para que a pilha Px, originalmente cheia, esteja preenchida 
de v(5) até v(1), respectivamente, com os símbolos Q1, Q2, Q3, Q4, Q5? 
Você acertou! 
C. 8. 
Seguindo as especificações dos movimentos, a quantidade mínima de movimentos entre as 
três pilhas para que elas cheguem ao preenchimento desejado de Px é de 8 movimentos. 
 
Implementação de Filas em Python 
1. Existem diferentes tipos de estruturas que são utilizadas para organizar dados. Qual 
dessas estruturas é representada como uma lista linear de elementos nos quais a exclusão 
pode ser feita de uma extremidade (início) e a inserção pode ocorrer apenas na outra 
extremidade (fim)? 
Você acertou! 
A. Fila. 
A lista linear de elementos nos quais a exclusão é feita na parte frontal e a inserção na parte 
traseira é chamada de fila, a qual utiliza o modelo first in, first out, FIFO. 
As pilhas utilizam o princípio LIFO, last in, first out, em que há inserção em apenas uma 
extremidade. 
Árvores tem os nós acessados por meio de busca direta, não seguindo o princípio FIFO. 
Em listas vinculadas aponta-se um ponteiro para os elementos que se deseja incluir/remover, 
não sendo utilizado, assim, o princípio FIFO das filas. 
Arrays têm seus elementos inseridos por meio de busca direta, não utilizando o princípio FIFO 
das filas. 
2. Existe um conjunto de operações básicas que podem ser realizadas sobre filas; algumas 
operações permitem manipulação, enquanto outras apenas retornam consultas sobre as 
filas. Entre as operações a seguir, qual delas retorna um valor booleano? 
Você acertou! 
C. estaVazia(). 
A operação que retorna um booleano é a estaVazia(), que retorna True se a fila estiver vazia, 
e False caso contrário. 
A operação tamanho() devolve um inteiro, com a quantidade de itens na fila. 
A operação primeiro() retorna (mas não remove) uma referência ao primeiro elemento da fila. 
Já a operação fila() cria uma fila vazia, enquanto a operação enfilera(item) adiciona um item 
no final da fila. 
3. Em cada estrutura de dados é utilizado um processo para inserção e remoção de 
elementos. Todo tipo de estrutura, seja fila, pilha ou árvore, tem funções que auxiliam nesse 
processo. Sendo assim, se os elementos A, B, C e D forem colocados nesta ordem em uma 
fila e excluídos um de cada vez, em que ordem serão removidos? 
Você acertou! 
C. ABCD. 
A fila segue a abordagem FIFO, ou seja, abordagem primeiro a entrar, primeiro a sair. Portanto, 
a ordem dos elementos de remoção é ABCD, a mesma ordem em que foram inseridos. 
DCBA representaria uma pilha, que segue a abordagem LIFO, na qual o último a entrar é o 
primeiro a sair. 
As alternativas DCAB, ABDC e ACDB poderiam ser implementadas com árvores ou listas, por 
exemplo. 
4. Python disponibiliza diversas bibliotecas que facilitam a manipulação de diferentes 
estruturas de dados. Utilizando a biblioteca Python queue, com a seguinte implementação: 
 
import queue 
f = queue.Queue() 
f.put("abacate") 
f.put("amora") 
f.put("abacaxi") 
f.put_nowait("uva") 
f.get() 
f.get_nowait() 
f.put("pêra") 
f.put("amora") 
print(list(f.queue)) 
Qual seria a fila resultante? 
Você acertou! 
E. ['abacaxi', 'uva', 'pêra', 'amora']. 
O código em questão faz a criação de uma fila de nome f (f = queue.Queue()), depois adiciona 
3 elementos na fila (abacate, amora, abacaxi). 
Então, com os comandos get e get_nowait, os dois primeiros elementos são removidos da fila 
(abacate, depois amora) e, por fim, outros dois elementos são adicionados (pêra e amora), 
sendo assim, a fila resultante é ['abacaxi', 'uva', 'pêra', 'amora']. 
O resultado [] é uma lista vazia, e teria sido obtido se fosse parado na segunda linha de código. 
O resultado ['abacate', 'amora', 'abacaxi', 'uva', 'pêra', 'amora'] só seria possível se não 
houvesse os dois comandos de remoção da fila (get e get_nowait). 
O resultado ['abacate'] só seria possível se fosse parado na terceira linha, e adicionado 
somente mais uma linha de impressão. 
Por fim, o resultado ['abacate', 'amora', 'abacaxi', 'uva'] só seria possível se, após inserir “uva”, 
fosse finalizado com uma linha de impressão. 
5. Há diversas situações no cotidiano que poderiam ser representadas por diferentes 
estruturas de dados, como filas, pilhas, árvores, deques, entre outras. Entre as situações 
reportadas a seguir, qual melhor se encaixa com a estrutura do tipo fila? 
Você acertou! 
C. Documentos esperando para serem impressos em uma impressora. 
Documentos esperando para serem impressos em uma impressora melhor representam a 
estrutura de fila, em que o primeiro a ser enviado será o primeiro a ser impresso (first in, first 
out). 
Uma torre com pratos sobrepostos em uma mesa pode ser representada por uma pilha. 
A visualização do resultado da Copa do Mundo pode ser feita utilizando uma árvore, visto que 
o conjunto de times que passa para a próxima fase vai reduzindo até chegar ao campeão, que 
será o nodo raiz da árvore. 
Por fim, a relação de filmes indicados ao Oscar, assim como uma lista de itens a serem 
comprados no supermercado poderia ser implementada com uma lista comum. 
 
Implementação de Deques em Python 
1. Existem diferentes estruturas de dados que podem ser usadas para estruturar algoritmos 
que resolvam problemas relacionados a containers de dados, e a escolha de qual usar 
depende do problema a ser resolvido. Entre as opções a seguir, qual delas melhor define uma 
deque? 
Você acertou! 
A. Uma estrutura com inserção/exclusão possível nos extremos frontal e traseiro da fila. 
Deque é uma estrutura que permite inserir e remover tanto pela cabeça quanto pela 
cauda. Em pilhas, é possível inserir e remover apenas em uma das extremidades. Nas filas, é 
possível inserir apenas em uma extremidade e remover apenas na outra extremidade. Já as 
árvores são hierárquicas, e os dados são inseridos iniciando-se pelo nó raiz. Em deques, não 
há a obrigatoriedade de inserir e recuperar dados de forma ordenada: eles podem ser inseridos 
na ordem em que forem gerados. 
2. Usando a biblioteca Collections, é possível aproveitar alguns métodos já prontos para a 
manipulação de deques. Após executar o código abaixo, qual seria o resultado esperado na 
impressão? 
import collections 
d = collections.deque('abcd') 
d.appendleft('d') 
print (d) 
Você acertou! 
E. Inclusão do ‘d’ à esquerda. 
O resultado do print será: deque(['d', 'a', 'b', 'c', 'd']), incluindo um ‘d’ à esquerda da deque que 
foi criada inicialmente. Para incluir à direita, o comando da linha 3 deveria ser d.append('d'). 
Para remover o ‘d’, o comando seria d.pop(); para imprimir a letra ‘d’, o comando na quarta 
linha seria print ('d'); e, para imprimir a deque inicial, o comando print (d) deveria ser movido 
para a terceira linha. 
3. Entre os métodos já implementados na biblioteca Collections, estão métodos para 
remoção dos elementos em uma deque. Considere que inicializamos uma dequeda seguinte 
forma: d = collections.deque('6598732') Qual comando utilizamos para remover o elemento 
2? 
Você acertou! 
C. d.pop(). 
Para remover o elemento 2, utilizamos o comando d.pop(), pois ele está à direita na 
deque. Esse comando não recebe parâmetros; portanto, não podemos colocar dentro do 
parêntese o valor a ser removido. Por esse motivo, as alternativas d.pop(2) e d.popright(2) 
estão incorretas. Adicionalmente, o comando popright() não existe na sintaxe, visto que, como 
a eliminação padrão em uma fila é pela direita, o comando, nesses casos, é o pop(). Ao 
utilizarmos o comando d.popleft(), seria eliminado o primeiro elemento da esquerda, ou seja, 
o 6, e não o 2, como pede o enunciado. 
4. A linguagem de programação Python facilita a manipulação de estruturas de dados a partir 
do uso de bibliotecas com comandos que, em poucas linhas, ajudam a inserir, remover, fazer 
consultas, entre outras funcionalidades. Utilizando a biblioteca Collections, qual seria a 
deque resultante da seguinte sequência de operações? 
import collections 
d = collections.deque() 
d.extend('abcd') 
d.pop() 
d.append('j') 
d.appendleft('z') 
d.pop() 
print (d) 
Você acertou! 
A. deque(['z', 'a', 'b', 'c']). 
Após a criação da deque com os elementos 'abcd', foi removido o 'd', adicionado o 'j' à direita, 
adicionado o 'z' à esquerda e removido o 'j'. Dessa forma, o resultado é deque(['z', 'a', 'b', 
'c']). Se, no lugar do comando pop da linha 7, tivéssemos o comando d.reverse(), o resultado 
seria deque(['j', 'c', 'b', 'a', 'z']). Se houvesse um d.clear()no lugar do comando pop da linha 7, o 
resultado seria uma deque vazia: deque([]). Esta deque(['a', 'b', 'c', 'd']) é o resultado inicial, 
após o comando extend da linha 2, que é usado para adicionar múltiplos valores à direita da 
fila. Esta deque(['z', 'a', 'b', 'c', 'j']) seria resultante se não houvesse o d.pop()da linha 7, que 
removeu o 'j'. 
5. A computação simula o mundo real, criando ambientes e estruturas baseados no 
funcionamento de processos já existentes no dia a dia. Qual dos seguintes cenários do 
mundo real você associaria a uma estrutura de dados do tipo deque? 
Você acertou! 
C. Check-in de embarque em um voo nacional. 
A oferta de serviços com base na prioridade do cliente, como o check-in em um voo, é um 
exemplo que pode ser implementado usando-se deques. As crianças em fila para andar no 
carrossel podem ser um exemplo de filas simples, em que não é necessário priorização. Uma 
árvore pode representar a hierarquia em uma empresa, e uma coleção de revistas sobrepostas 
pode ser representada por uma pilha. 
 
Métodos de pesquisa em listas: sequencial, binária e tabelas 
hash 
1. A busca sequencial é uma técnica simples e intuitiva para buscar elementos em vetores 
ou listas. Tendo a informação de que os dados estão ordenados de forma crescente, qual 
otimização você pode aplicar na busca sequencial? 
Você acertou! 
D. Parar a execução e informar que o valor não existe, quando o valor atual for maior que o 
buscado. 
O desempenho de pior caso da busca sequencial pode ser otimizado sabendo-se que o vetor 
está ordenado. Para tanto, continua-se a buscar um elemento enquanto o elemento atual for 
maior que o buscado. No momento em que ele for menor, sabe-se que o vetor é ordenado e, 
no futuro, não será possível encontrar outro elemento maior. O contrário não é verdade, pois, 
caso seja encontrado um valor menor que o buscado, ainda é possível achar valores maiores 
no futuro. Funções hash podem ser utilizadas apenas em tabelas hash. Ainda, descobrir a 
posição de um elemento sem buscar em várias posições do vetor também só é possível em 
tabelas hash. 
2. A busca binária é uma técnica eficiente para buscar elementos em vetores ou listas. A 
única restrição desse método é que o vetor ou a lista estejam ordenados. Das seguintes 
sequências de acessos em um vetor, qual é válida em uma execução de busca binária? 
Você acertou! 
C. 5, 2, 1. 
Em cada iteração da busca binária, o elemento do meio do intervalo atual é acessado. Nesse 
sentido, para acessar a posição 1, é necessário que o tamanho do intervalo seja 2. Assumindo 
que o vetor tivesse tamanho 2, não seria possível nas alternativas (1, 2, 5) e (1, 5, 2) acessar 
elementos maiores que 2 após esse primeiro acesso. No caso da alternativa (5, 7, 3), o 
problema vai quando o elemento 5 é acessado e logo todos os menores que 5 são ignorados, 
mas, logo após, o número 3 é acessado. O mesmo ocorre na alternativa (5, 2, 8). Portanto, a 
alternativa correta é (5, 2, 1), um vetor de tamanho 10; o primeiro acesso é o 5, após a metade 
é o 2 e, por fim, o 1. 
3. Tabelas hash são estruturas muito eficientes utilizadas por diversas linguagens de 
programação e serviços. Entender seu funcionamento é crucial para o desenvolvedor, o qual 
deverá decidir o tamanho da tabela e a função hash que otimiza o desempenho de 
determinada aplicação. Considere uma tabela hash de 5 posições (de 1 a 5, aceitando 
repetições) e uma função hash que representa a i-ésima letra do alfabeto com o número i. 
Quantas colisões ocorrem após a inserção das chaves: A, B, A, C, A, E? 
Você acertou! 
B. 2. 
Uma tabela hash de 5 posições tem índices de 1 a 5. A função hash converte um caractere 
para um índice de acordo com a ordem no alfabeto. Por exemplo, a letra A é 1, a letra B é 2, 
e assim por diante. Nesse sentido, colisões vão ocorrer apenas quando a mesma letra for 
inserida. Como foi inserida três vezes a letra A, e as colisões ocorrem a partir da segunda 
inserção, o total de colisões é 2: a segunda inserção da letra A e a terceira. 
4. Métodos de busca são muito utilizados em milhares de sistemas e aplicações reais. O 
projetista e o desenvolvedor devem ter muito conhecimento sobre seu funcionamento e 
também sobre as vantagens e desvantagens de cada método. 
Para uma aplicação que realiza muitas inserções e atualizações nos dados, qual é o método 
mais indicado? 
Você acertou! 
D. Tabela hash implementada com vetores e listas para tratar colisões. 
A busca sequencial tem um custo muito alto e só é indicada para aplicações com vetores 
pequenos que realizam poucas buscas. A binária, por outro lado, pode ser eficiente, 
dependendo do caso: inserir dados sempre ordenados aumenta o custo da inserção, que, no 
caso de aplicação com muitas inserções e atualizações nos dados, é um ponto importante; 
ordenar apenas quando atualizar vai aumentar o custo das atualizações, que também são 
muito recorrentes nesse caso. Já uma lista encadeada não permite encontrar os elementos de 
forma veloz, pois é necessário percorrê-la do início ao fim. Assim, a resposta correta 
é tabela hash, pois, dada uma chave, é possível inserir e atualizar apenas computando a 
função hash, que tem baixo custo. 
5. Uma das maneiras de avaliar o melhor método para uma aplicação é analisar a 
complexidade de pior e melhor caso dos métodos e constatar com as entradas da aplicação-
alvo. Para tanto, é necessário conhecimento sobre ordens assintóticas. Nesse sentido, qual 
é a complexidade de pior caso das buscas sequencial, binária e na tabela hash, 
respectivamente? 
Você acertou! 
C. O(n), O(log2 n), O(K). 
Para calcular a complexidade de pior caso, deve-se pensar na pior entrada possível para o 
programa. No caso da busca sequencial, como se tem um laço que vai de 1 até N, o pior caso 
é percorrer esse laço N vezes. Nesse sentido, a complexidade da busca sequencial é O(n). 
Quando se fala da busca binária, ela é mais eficiente, pois a cada iteração elimina metade do 
intervalo. Essa eliminação de metade do vetor por vez remete a uma árvore binária, por isso 
o nome da busca. Nesse caso, a complexidade de tempo é O(log2 n). Por fim, a 
tabela hash tem uma complexidade de melhor caso de O(1); entretanto, no pior caso, podem 
ocorrer K colisões, e uma lista encadeada será percorrida até o K-ésimo elemento. Logo, 
complexidade O(K). 
 
Ordenação de dados - Métodos simples 
1. O algoritmo de ordenação por bolha é o mais simples e intuitivo.O seu funcionamento se 
baseia em comparar todos os elementos, dois a dois, do inicio ao fim da lista ou vetor. Essa 
operação é repetida enquanto ocorrerem trocas entre elementos. Dado o vetor [22, 11, 7, 
46, 29], após duas rodadas de execução do algoritmo de ordenação por bolha, ordenando de 
forma decrescente, qual será o estado do vetor? 
Você acertou! 
A. 22, 46, 29, 11, 7. 
O algoritmo de ordenação por bolha compara elementos dois a dois da esquerda para a direita. 
Nesse exercício, o objetivo é ordenar de forma decrescente, ou seja, quando a comparação 
for feita, caso o elemento na posição i for menor que o da posição i + 1, é realizada a troca 
de posição entre os elementos. 
Na primeira rodada vai comparar 22 com 11 e não trocar. Após, compara 11 com 7 e também 
não troca. Agora, quando compara 7 com 46 vai trocar e, após 7 com 29, troca novamente. 
Na primeira rodada tem-se: [22, 11, 46, 29, 7]. 
Na segunda rodada compara-se 22 com 11 e não troca. Logo após, troca 11 por 46 e 11 por 
29. Finalmente, compara 11 com 7 e não troca. O estado do vetor na segunda rodada é [22, 
46, 29, 11, 7]. 
2. A ideia principal do algoritmo de ordenação por inserção é como em um jogo de cartas. 
Quando você recebe uma nova carta, já ordena ela de alguma maneira. Vamos assumir que 
você está jogando cartas e tem a seguinte lista de cartas na mão: [Q, J, Q, J]. Quantas trocas 
serão feitas caso você ordene as cartas de forma ascendente, baseando-se no algoritmo de 
ordenação por inserção? 
Você acertou! 
C. 3. 
Na primeira rodada, o escolhido será o J (2.º elemento), o qual será comparado com o Q (1.º 
elemento). Uma vez que J é menor que Q lexicograficamente, ambos são trocados de 
posição (1 troca). O estado do vetor após a primeira rodada é [J, Q, Q, J]. 
Na segunda rodada, o escolhido é o Q (3.º elemento), que será comparado com outro Q (2.º 
elemento) e nada irá acontecer. 
Na terceira rodada, o escolhido é o J (4.º elemento), que será comparado com os dois Qs (3.º 
e 2.º elementos), sendo trocado (mais 2 trocas, totalizando 3). Ao fim dessa rodada, com 3 
trocas, o vetor está ordenado [J, J, Q, Q]. 
3. A ordenação por seleção busca o menor elemento da parte não ordenada do vetor em 
cada iteração e o coloca na sua posição correta. Quantas comparações e trocas são 
necessárias para ordenar o vetor [1, 5, 3, 9, 6] de forma crescente? 
Você acertou! 
D. 10 e 2. 
Na primeira rodada, o 1 será o menor e já está em sua posição correta. Serão 4 
comparações com os 4 elementos à direita do 1 e nenhuma troca. 
Na segunda rodada, o 5 será comparado com os 3 elementos à direita e uma troca será feita 
entre o 5 e o 3. 
Na terceira rodada, o 5 já estará na sua posição correta, logo, aconteceram 2 comparações e 
nenhuma troca. 
Ao final, na rodada quatro, o 9 será comparado com o 6, 1 comparação,e serão trocados, 
logo, uma troca. 
Somando 4 + 3 + 2 + 1 são 10 comparações e 2 trocas. 
4. Você foi contratado como consultor por uma empresa de desenvolvimento de sistemas. 
Um dos clientes solicitou o desenvolvimento de uma nova funcionalidade que permite 
ordenar os clientes por idade e renda. Essa funcionalidade será utilizada diversas vezes ao 
dia, o que indica que após uma ordenação, as outras só serão necessárias caso atualizações 
tenham sido feitas no banco de dados. Quantas comparações serão feitas pelo algoritmo de 
ordenação por bolha, caso a entrada seja uma lista de 10 elementos já ordenados? 
Você acertou! 
B. 9. 
Tomando como exemplo o vetor [1, 2, 3], com três elementos, o algoritmo de ordenação por 
bolha irá comparar 1 com 2, e 2 com 3, ou seja, 2 comparações, N - 1 elementos. Assim, é 
possível concluir que para um vetor já ordenado com 10 elementos, o algoritmo de ordenação 
por bolha irá fazer 9 comparações. 
5. Uma das maneiras de avaliar o melhor algoritmo de ordenação para determinada aplicação 
é analisando a sua complexidade de tempo. Você foi contratado para fazer essa análise. A 
primeira pergunta que seu chefe fez foi qual seria a complexidade de melhor e pior caso do 
algoritmo de ordenação em seleção, caso ele fosse executado M vezes consecutivas. O que 
você responderia? 
Você acertou! 
E. O(M * N2) e O(M * N2). 
O algoritmo de ordenação por seleção em cada iteração corrige a posição de um dos 
elementos do vetor. Para tanto, em cada iteração ele busca em toda lista pelo menor 
elemento ainda não processado. Isso ocorre tanto no caso de o vetor estar desordenado (pior 
caso) quanto no caso de estar ordenado (melhor caso). 
Nesse sentido, a complexidade de tempo de melhor e pior caso desse algoritmo é a mesma, 
O(N2).Entretanto, é preciso levar em consideração as M execuções citadas no enunciado. 
Nesse caso, serão repetidos M vezes a complexidade O(N2), ou seja, a complexidade final 
tanto de melhor quanto de pior caso é O(M * N2). 
 
Ordenação de dados com métodos eficientes e uso de Python 
1. O algoritmo de ordenação rápida utiliza um pivô para recursivamente ordenar o vetor. Em 
cada chamada da função de partição, os elementos menores que o pivô são colocados na 
esquerda e os maiores que o pivô na direita. Essa operação é repetida até que reste apenas 
um elemento. Dado o vetor [13, 87, 63, 91, 55] e o pivô 55, qual das opções a seguir é válida 
após a primeira execução da função partição? 
Você acertou! 
A. [13, 55, 63, 91, 87]. 
O algoritmo de ordenação rápida utiliza pivôs para ordenar o vetor. Nesse exercício, o objetivo 
é executar uma vez a função de partição utilizando o pivô 55. O vetor original é o [13, 87, 63, 
91, 55]. Da esquerda para a direita, os elementos menores que o pivô vão sendo armazenados, 
enquanto na direita os maiores que o pivô. O próprio pivô é inserido à direita dos menores 
elementos. No caso desse exemplo, o 13 é o único elemento menor que o pivô. O 55, que é 
o pivô, é trocado pelo 87, que é a primeira posição após o elemento menor. Nesse caso, o 
vetor após a primeira execução da função partição será [13, 55, 63, 91, 87]. 
 
 
 
2. A complexidade de tempo de melhor caso da ordenação rápida ocorre quando o elemento 
escolhido como pivô divide o vetor exatamente ao meio. No exemplo [M, Q, S, I, B], qual 
elemento escolhido como pivô resultaria no melhor caso de execução da ordenação rápida? 
Você acertou! 
E. M. 
O melhor caso da ordenação rápida ocorre quando o pivô escolhido é a mediana do vetor 
analisado. No exemplo do nosso vetor [M, Q, S, I, B], a mediana é o M, que dividiria o vetor 
em dois subvetores: [I, B] e [Q, S]. 
3. A ordenação por mistura ordena, de forma recursiva, sequências a partir de subsequências 
já ordenadas. Na fase de divisão, os elementos são recursivamente divididos. Dado o vetor 
[7, 4, 9, 5, 1], quantas chamadas recursivas serão feitas na fase de divisão? 
Você acertou! 
E. 8. 
O vetor original é o [7, 4, 9, 5, 1]. As duas primeiras chamadas recursivas serão [7, 4, 9] e [5, 
1]. Após, serão feitas mais quatro chamadas: [7, 4]; [9]; [5] e [1]. Por fim, mais duas chamadas 
serão feitas: [7] e [4]. O total de chamadas recursivas é 8. 
4. O melhor e o pior caso da ordenação por mistura é o mesmo, O(n log2 n). Dado um vetor 
totalmente desordenado [8, 7, 6, 5, 4, 3, 2, 1], qual será o estado do vetor após duas 
execuções da função merge? 
Você acertou! 
B. [7, 8, 5, 6, 4, 3, 2, 1]. 
Inicialmente, a ordenação por mistura irá dividir os elementos até chegar em vetores de 
tamanho um. Após, a fase de conquista começará e a função merge será utilizada. A recursão 
vai toda para a esquerda e a primeira execução do merge irá ordenar o vetor [8, 7], resultando 
em [7, 8, 6, 5, 4, 3, 2, 1]. Na segunda execução do merge, o vetor [6, 5] será ordenado. 
Resultando no vetor [7, 8, 5, 6, 4, 3, 2, 1]. 
5. A implementação dos algoritmos eficientes tem como base a técnica de divisão e 
conquista. Em ambas as ordenações, por mistura e rápida, o ponto-chave é a complexidade 
de tempo das funções de partição e de merge. Qual é a complexidade de tempo dessas 
funções quando executadas N vezes para um vetor de N posições? 
Vocêacertou! 
D. O(N2). 
A complexidade de ambos os algoritmos é Nlog2 N, sendo que log2 N é a altura da árvore de 
divisão e N é o custo de cada chamada, as funções partição e merge. A questão pergunta a 
complexidade de executar essas funções N vezes. O que resulta em N vezes O(N), ou seja, 
O(N2). 
 
Árvores: estruturas hierárquicas 
1. Alguns problemas requerem estruturas que possibilitem operações como inserção e 
remoção de maneira dinâmica, tais como as árvores. Em relação às árvores e suas vantagens 
em relação às demais estruturas, marque a alternativa correta. 
Você acertou! 
B. Árvores são consideradas eficientes para guardar informações, pois apresentam uma 
forma de organização não linear. 
Devido à topologia hierárquica das árvores, os dados podem ser localizados facilmente, 
quando comparadas a estruturas lineares, tais como listas, filas e pilhas. Além disso, 
normalmente os dados são alocados dinamicamente na memória. Sua forma e inserção pode 
respeitar algumas propriedades, mas não limita que sejam inseridas nas extremidades (início 
e fim). 
2. Considere que você precisa utilizar uma árvore binária e o TAD deve ter um campo para 
armazenar um número inteiro. Os nós podem ser representados na linguagem Python como 
uma classe com os seguintes atributos básicos: 
 
 
Você acertou! 
A. Número do nó, ponteiro para subárvore da direita e ponteiro para subárvore da esquerda. 
Um TAD para representar um nó, de maneira básica, precisa ter três campos: 
- um campo para armazenar a informação do nó e, como o enunciado cita inteiros, as 
alternativas com strings e listas (visto que é apenas uma informação) são eliminadas. 
- um campo para referenciar a subárvore da esquerda. 
- um campo para a subárvore da direita. Veja que também não precisa de lista e de ponteiro 
para o pai. 
3. Durante a implementação de um TAD hierárquico, será necessário conhecer alguns termos 
para projetar os métodos. Acerca das terminologias da estrutura de dados do tipo árvore, 
considere a imagem a seguir e marque a alternativa correta: 
 
Você acertou! 
C. O grau do nó E é 2. 
Alguns temos importantes para classificar as árvores são: 
- o grau de um nó que é dado pelo número de arestas que incidem neste nó. 
- a altura de uma árvore está relacionada ao seu nível máximo, essa árvore tem altura 3. 
- os nós folhas têm subárvore da direita e da esquerda vazias, ou seja, grau zero. 
- O nível de um nó é sua distância do nó raiz, logo o nó raiz tem nível igual a zero. 
Como você pode observar, essa árvore tem altura igual a três e seus nós folhas são D, G, H e 
F. O grau do nó C é um, já o grau do nó B e E é igual a dois. No segundo nível estão os nós D, 
E e F. 
 
 
 
 
 
4. Dada a seguinte árvore e considerando as propriedades de armazenamento de uma árvore 
binária, após a inserção do nó 9 e do nó 5, nessa ordem, pode-se afirmar que esses nós serão 
filhos dos nós: 
 
Você acertou! 
B. 9 será filho da esquerda do nó 10 e 5 será filho da direita do nó 4. 
Durante a inserção em uma árvore binária deve-se respeitar a propriedade em que os maiores 
valores são inseridos à direita e menores são inseridos à esquerda. Inicia-se a inserção pela 
raiz e essa propriedade é verificada em cada subárvore até encontrar o pai. Nesse exemplo, o 
9 será filho à esquerda do nó 10 e o 5 será filho à direita do nó 4. 
5. Caso você tivesse que indicar uma estrutura de dados apropriada para armazenar uma 
sequência de comandos HTML e verificar sua sintaxe antes de apresentar as informações 
no browser, qual estrutura você indicaria? 
Você acertou! 
E. Árvore 
A linguagem HTML verifica os comandos digitados, analisando se eles pertencem a uma 
determinada tag que o programador está usando e, para agilizar as consultas, as informações 
são organizadas de maneira hierárquica. Nesse caso, uma árvore seria a estrutura ideal. 
 
Caminhamento em árvore 
1. As árvores são estruturas de dados de grande contribuição, principalmente no que tange 
as expressões aritméticas, em que o percurso utilizado pode influenciar diretamente. O 
caminhamento em árvore é realizado de três formas, as quais variam conforme a posição de 
leitura do nó raiz, que podem ser: 
Você acertou! 
D. em-ordem, pós-ordem, pré-ordem. 
Os percursos realizados em árvores binárias variam em três tipos, conforme a posição de 
leitura do nó raiz, podendo ser pré-ordem, quando a raiz de cada subárvore é lida 
anteriormente às subárvores esquerda e direita. Quando somente a subárvore esquerda é 
visitada antes do nó raiz, dá-se o nome de percurso em-ordem. E quando tanto a subárvore 
esquerda como a direita são lidas anteriormente à raiz, atribui-se o percurso pós-ordem. 
2. Árvores binárias possibilitam maior organização dos elementos adicionados, o que facilita 
separar os elementos a cada nível de crescimento da árvore. Dada a seguinte lista de 
caracteres [P, R, O, G, R, A, M, A, D, O, R, U, M], como ficaria seu resultado final em uma 
leitura pós-ordem, caso seus valores fossem adicionados sequencialmente, do primeiro ao 
último elemento, em uma árvore binária? Para montar uma árvore binária, os elementos 
menores ou iguais ao nó mais abaixo entrará à esquerda; caso contrário, ficará à direita. 
Você acertou! 
B. A D A M O M G O R R U R P. 
 
3. Uma árvore binária que tenha como finalidade resolver problemas aritméticos, necessita 
que sua leitura seja feita de tal modo a combinar dois operandos para o operador da 
expressão. Exemplo: A + B. Portanto, como uma árvore deveria posicionar seus elementos e 
qual seria a melhor forma de leitura para que as operações ocorram? 
Você acertou! 
B. É preferível que os valores da operação aritmética estejam localizados à esquerda e à 
direita da raiz, desde que o operador seja raiz, e a leitura da árvore seja feita em-ordem. 
Em uma árvore binária, para avaliar expressões aritméticas, é importante organizá-la de tal 
forma que os operadores dividam simetricamente cada subexpressão, de modo a facilitar sua 
leitura. Tendo este objetivo em mente, é preferível que existam os operadores (soma, 
subtração, multiplicação e divisão), ocupando sempre a raiz, separando de forma mais 
simétrica os operandos (valores) da expressão, para uma leitura realizada em-ordem. 
4. O caminhamento de uma árvore binária influencia diretamente no resultado final de 
leitura de uma determinada sequência de símbolos, e pode se encontrar em 3 tipos, como 
percursos em pré-ordem, in-ordem e pós-ordem, variando, assim, a posição do valor raiz. 
Qual função a seguir descreve o percurso realizado em pós-ordem? 
Você acertou! 
A. def funcao(no): 
if atual != None: 
funcao(no.esquerdo) 
funcao(no.direito) 
print("Valor: {}.".format(no.valor)) 
A ordem dos elementos visitados em pós-ordem estabelece que os elementos da subárvore à 
esquerda serão visitados, seguidos dos elementos das subárvores à direita e, por fim, os 
elementos raízes. 
 
Mesmo que todas as funções apresentem recursividade, apenas a função com a impressão 
sucedendo às duas chamadas recursivas para as subárvores esquerda e direita imprimem o 
caminho pós-ordem. 
5. O modo como é feito o percurso determina como será o nível de prioridade de leitura dos 
elementos, podendo o nó raiz estar com prioridade (leitura em pré-ordem), ou os elementos 
da subárvore à esquerda (leitura in-ordem), ou os elementos da subárvore à esquerda 
seguido da leitura à direita (pós-ordem). Considerando a imagem a seguir, mostre a sequência 
de expressões resultantes, conforme os percursos de pré-ordem, em-ordem e pós-ordem, 
respectivamente. 
 
Você acertou! 
C. * 3 * 5 13 
3 * 5 * 13 
3 5 13 * * 
Os percursos variam conforme a sua modalidade, a qual está relacionada à posição de visita 
do nó raiz. Neste caso, onde é desejado obter as 3 formas de leitura, é possível identificar um 
padrão no posicionamento do operador aritmético, cujo posicionamento está mais à esquerda 
na leitura em pré-ordem: * 3 * 5 13; está mais simétrico na leitura em-ordem: 3 * 5 * 13; e 
mais à direita para a leituraem pós-ordem: 3 5 13 * *. 
 
Pesquisa binária 
1. A estrutura de dados de árvore apresenta grande versatilidade. Pode ser aplicada na 
solução de um leque de problemas, como em indexação de bancos de dados, em buscas, em 
estruturas de diretórios em sistemas de arquivos, entre outros. Considerando uma árvore 
binária de busca, qual destas é uma de suas propriedades? 
Você acertou! 
B. A subárvore esquerda de um nó contém os nós com chaves menores ou iguais que a do 
nó. 
Para uma árvore agir como uma árvore de busca, os valores armazenados em cada nó devem 
ser maiores que qualquer outro que esteja na subárvore esquerda e menores do que os salvos 
em subárvores à direita. Logo, a subárvore esquerda de um nó contém os nós com chaves 
menores ou iguais ao nó referente; a subárvore direita de um nó contém os nós com chaves 
maiores que o nó referente; e as subárvores esquerda e direita também devem ser uma árvore 
de pesquisa binária. 
De acordo com a propriedade de uma árvore de busca, uma subárvore à esquerda não pode 
receber chaves maiores que o nó. Além disso, em uma árvore binária de busca, cada nó pode 
ter, no máximo, dois filhos. Sobre o tipos e os valores armazenados nos nós, não exitem 
restrições: pode ser tanto uma string como um valor numérico qualquer, e, quando se trata de 
valores numéricos, também não existem restrições se o valor é positivo ou negativo. 
2. Uma árvore binária de busca é conhecida pela sua eficiência quando é necessária a 
pesquisa de algum valor, seguindo as regras de buscas, ramificando para a esquerda e para a 
direita. Sabendo disso, de acordo com a árvore na imagem, determine qual caminho a chave 
de busca percorreu para pesquisa do valor 87 e se este existe ou não. 
 
Você acertou! 
D. Visitou chave 70. 
Visitou chave 90. 
Visitou chave 83. 
Visitou chave 85. 
Visitou chave 89. 
Resultado: falha. 
Considerando que a raiz da árvore corresponde ao valor 70, para o número procurado (87), 
precisaremos caminhar pela subárvore à direita. Em seguida, será visitado nó de chave 90, 
porém o valor procurado ainda não é esse, e, como 87 é menor que 90, será explorada à 
subárvore à esquerda do nó de chave 90, resultando em uma visita ao nó de chave 83. Como 
87 é maior que 83, seguiremos à procura pela subárvore à direita desse nó, chegando ao nó 
de chave 85. O valor 87 é maior que 85, fazendo com que seja realizada a leitura ao último nó 
dessa ramificação: o nó de chave 89. 
Como não existem mais elementos a serem explorados a partir do nó de chave 89, o resultado 
obtido é de falha, pois o elemento 87 não existe. 
 
 
 
3. Sempre que vimos uma árvore, presumimos a ordem em que seus elementos foram 
adicionados. Dessa forma, conforme a imagem utilizada no exercício anterior, defina uma 
possível ordem do vetor que culminou na árvore apresentada, lembrando que o primeiro 
valor corresponde à raiz da árvore. 
 
Você acertou! 
B. [70,90,4,114,2,23,83,116,72,15,85,89,63]. 
Podemos verificar a ordem de cada elemento fazendo uma pequena inserção em uma árvore 
abstrata. Ao criar uma árvore binária sem balanceamento, temos sempre que considerar sua 
forma de organizar seus valores. Logo, se o valor 89, que é uma folha, for adicionado antes do 
valor 85, o valor 89 que antes não tinha nenhuma ramificação passará a ter o nó 85 como 
subárvore esquerda. 
Seguindo esse raciocínio, podemos estabelecer uma possível ordem como: 
[70,90,4,114,2,23,83,116,72,15,85,89,63]. 
4. Uma árvore binária de busca, como o próprio nome sugere, é uma estrutura de dados que 
armazena dados de maneira que permita a realização de busca binária. Essa busca segue 
o paradigma de divisão e conquista e acaba tendo uma eficiência melhor do que uma busca 
linear. Existem duas abordagens para realizar a implementação dessa busca: a 
implementação recursiva e iterativa. Qual a principal diferença entre essas implementações? 
Você acertou! 
C. Na abordagem recursiva, um nó definido como base nele próprio realiza a repetição dos 
seus passos invocando a si próprio, executando todos os seus passos novamente até 
encontrar o valor buscado. Diferentemente da busca recursiva, a busca iterativa considera 
as ramificações de maneira explícita de cada nó para percorrer seus nós, pois não há uma 
chamada interna para a mesma função. 
A abordagem recursiva realiza autorreferência, ou seja, ocorre quando algo é definido em 
termos de si mesmo. No caso da árvore, um nó é definido com base nele próprio até achar o 
valor buscado; já no método iterativo, a busca é realizada percorrendo explicitamente todos 
os nós da árvore até se encontrar o valor buscado. 
Além disso, apenas o método iterativo usa laços de repetição, como while e for. E, apesar de 
serem abordagens diferentes, ambas visitam os mesmos nós no processo de busca por 
determinado valor. 
5. Em termos de alocação de memória, podemos implementar uma árvore de busca binária 
utilizando alocação dinâmica ou alocação estática. Considerando a alocação estática, como 
ocorre a representação de uma árvore de pesquisa binária em um vetor? 
Você acertou! 
A. 1- O nó raiz deve ficar na posição inicial do vetor. 
 
2- Para cada nó em determinada posição i de um vetor, seu filho esquerdo ficará na posição 
2*i + 1, e seu filho direito ficará na posição 2*i + 2. 
As árvores também podem ser implementadas sob listas fixas ou estáticas, que ocorrem por 
meio da distribuição dos nós da árvore ao longo de um vetor (array). Essa distribuição ocorre 
da seguinte forma: o nó raiz será o primeiro elemento do vetor, e, para cada nó em 
determinada posição i do vetor, seu filho esquerdo ficará na posição 2*i + 1, e seu filho direito 
ficará na posição 2*i + 2. 
 
Balanceamento de árvore 
1. Uma das principais vantagens das árvores binárias em relação às demais estruturas de 
dados é a sua eficiência no processo de realizar buscas. A árvore AVL é conhecida por ter um 
resultado muito eficiente durante a operação de busca, pois realiza uma distribuição 
homogênea dos dados. Qual a ideia central ao fazer o balanceamento em uma árvore? 
Você acertou! 
A. A ideia central do balanceamento é que, para cada novo elemento adicionado ou 
removido da árvore, seja realizado uma reorganização para que a distribuição dos elementos 
conforme sua subárvore, continue homogênea. 
No que tange o balanceamento, a ideia central é que para cada novo elemento adicionado ou 
removido da árvore, seja realizada uma reorganização para que a distribuição dos elementos, 
conforme sua subárvore, continue homogênea. 
Em uma árvore AVL não existe a necessidade de as subárvores terem a mesma quantidade de 
nós, e seus nós não têm valores de pesos. Além disso, existe mais de um tipo de árvore 
balanceada, as quais têm um objetivo de retornar uma busca eficiente. 
2. As árvores AVL correspondem à família das árvores binárias, em que a distribuição dos 
elementos é feita de acordo com determinadas condições, as quais são necessárias para 
garantir o balanceamento da árvore. Em relação à altura de uma AVL, qual é a afirmação 
correta? 
Você acertou! 
D. A altura de uma árvore nula é igual a -1. 
Uma árvore balanceada é assim chamada por alguns critérios, sendo um deles, a altura: 
Altura: a altura de uma árvore é o nível máximo de suas folhas. Em algumas literaturas, é 
determinado como profundidade de uma árvore. A altura de uma árvore nula, por exemplo, é 
definida como –1, e uma árvore binária balanceada é uma árvore em que as alturas de suas 
subárvores (esquerda e direita) de todo nó nunca diferem em mais de 1. 
Quando a árvore tem apenas um elemento, sua altura é de zero. Logo, quando não tiver 
nenhum elemento, essa árvore é nula, e sua altura é -1. 
3. Uma árvore AVL é uma árvore binária muito utilizada para armazenamento de dados em 
memória. Cada nó de uma árvore AVL necessita da informação de altura, pois é fundamental 
para o processo de balanceamento. Para um nó folha, que tem uma altura igual a 1, sendo 
que essa árvore AVL tem 7 nós. Qual é a altura máxima que essa árvore podeter? 
Você acertou! 
D. 3. 
Para encontrar a altura máxima, os nós devem ser mínimos em cada nível. Supondo 
altura como 3, número mínimo de nós necessário: 
N (h) = N (h-1) + N (h-2) + 1 
N (3) = N (2) + N (1) + 1 = 4 + 2 + 1 = 7 
Logo, a altura máxima é 3. 
4. Uma árvore AVL tem as funções básicas como inserção, remoção e busca, assim como 
uma árvore simples. Considere a seguinte árvore AVL. Qual das alternativas a seguir é a 
árvore AVL atualizada após a inserção de 70? 
 
Você acertou! 
C. 
 
5. No processo de realizar o balanceamento de uma árvore AVL, após a exclusão ou inclusão 
são realizadas operações para realizar o balanceamento. Quais das seguintes operações são 
usadas pelas árvores AVL? 
Você acertou! 
A. Rotação à esquerda e rotação à direita. 
Para auxiliar no processo de balanceamento das árvores AVL, são utilizadas as operações de 
rotação à esquerda e à direita, com o objetivo de redistribuir os elementos de maneira 
homogênea. 
A operação de recoloração de nós pertence à árvore rubro-negra; não existe esse ajuste por 
altura de peso, e as funções de caminhamento têm apenas a função de percorrer os nós.

Outros materiais