Geral

Estruturas de Dados

Semana 1 6

#1

Ponteiros desempenham um papel crucial quando uma variável precisa ser acessada em diferentes partes de um programa. Nesse contexto, é comum encontrar diversos ponteiros distribuídos por várias seções do código, cada um apontando para a variável que contém os dados necessários. Uma vantagem significativa dessa abordagem é que, se esses dados forem alterados, não há preocupação, pois todos os ponteiros no programa estão direcionados para o endereço onde os dados atualizados residem. Essa flexibilidade oferecida pelos ponteiros é fundamental para garantir a eficiência e a consistência na manipulação de dados em diferentes partes do código.

Considerando o uso de ponteiros em estruturas de dados, analise o seguinte código em C:

#include <stdio.h>


int main() {

    int arr[5] = {1, 2, 3, 4, 5};

    int *ptr = arr;

    printf("%d\n", *ptr + 2);

    printf("%d\n", *(ptr + 2));

    printf("%d\n", ptr[2]);

    printf("%d\n", *ptr++);

    printf("%d\n", (*ptr)++);

    return 0;

}

Diante da análise realizada, assinale a alternativa que apresenta a saída impressa ao executar este código.

A
3, 5, 3, 1, 2
B
3, 5, 3, 2, 2
C
3, 3, 3, 1, 2
D
3, 3, 3, 1, 3
E
3, 5, 3, 2, 3
#2

Em linguagens de programação podemos contar com operadores relacionais e lógicos, estes que são essenciais para comparar valores, facilitando a tomada de decisões baseadas em condições específicas. Eles verificam a relação entre dois operandos e resultam em um valor booleano (true ou false). Esses operadores são comumente usados em estruturas de controle de fluxo, como condicionais if e laços for e while, para guiar a execução do programa de acordo com as condições avaliadas.

Compreender o uso correto dos operadores relacionais é essencial para desenvolver algoritmos eficazes e garantir que as comparações lógicas sejam realizadas com precisão, sendo assim, assinale a alternativa que apresenta o operador lógico sobre MAIOR ou IGUAL.

A
Operador maior ou igual  (<>)(<>).
B
Operador maior ou igual (<=)(<=).
C
Operador maior ou igual  (=>)(=>).
D
Operador maior ou igual (>=)(>=).
E
Operador maior ou igual (>==)(>==).
#3

Os ponteiros são elementos fundamentais na linguagem C, conferindo-lhe uma notável flexibilidade e poder. Eles funcionam como variáveis especiais tendo a propriedade especial de "apontar" para uma variável. Essa capacidade de apontar para diferentes tipos de variáveis, como inteiros, pontos flutuantes, duplos, entre outros, confere aos ponteiros uma versatilidade excepcional.

Com base em nossos estudos, assinale a alternativa que apresenta a função do operador de referência (&) em estruturas de dados utilizando ponteiros em linguagem C.

A
Libera a memória alocada dinamicamente pelo ponteiro.
B
Aloca dinamicamente a memória para a variável.
C
Retorna o valor contido na posição de memória apontada pelo ponteiro.
D
Retorna o endereço de memória da variável.
E
Desreferencia o ponteiro, acessando o valor armazenado.
#4

Leia o trecho a seguir: 

Vetores (ou arrays) são uma das estruturas de dados mais fundamentais na programação em C++. Eles permitem armazenar múltiplos valores em uma única variável, usando um índice para acessar cada valor individualmente. A posição de cada elemento no vetor é indicada por um índice numérico, começando do zero. Vetores são particularmente úteis quando você precisa armazenar uma coleção de dados e acessar esses dados de forma eficiente através de um índice. Dessa forma, os vetores são estruturas de dados [preencher 1].

Os termos [preencher 1] é corretamente substituído por:

A
escaláveis
B
homogêneas
C
heterogêneas
D
complexas
E
dinâmicas
#5

Os vetores são estruturas de dados fundamentais em C++, amplamente utilizadas para armazenar coleções de elementos do mesmo tipo em uma sequência contínua de memória. A definição de um vetor envolve a especificação de seu tamanho e tipo de dados dos elementos que ele irá armazenar. Uma das principais vantagens dos vetores é a capacidade de acessar diretamente qualquer elemento utilizando um índice, o que permite operações rápidas e eficientes. 


Com base no contexto apresentado, veja o trecho de código a seguir:


 

#include <iostream>

using namespace std;

 

int main() {

    int vetor[5] = {10, 20, 30, 40, 50};

    int soma = 0;    

    for(int i = 0; i < 5; i++) {

        soma += vetor[i];

    }    

    cout << "A soma dos elementos do vetor é: " << soma << endl;

    return 0;

}

Diante do código apresentado, assinale a alternativa que apresenta qual será a saída do programa acima quando executado.

A
A soma dos elementos do vetor é: 120
B
A soma dos elementos do vetor é: 140
C
A soma dos elementos do vetor é: 150
D
A soma dos elementos do vetor é: 100
E
A soma dos elementos do vetor é: 130
#6

Em C++, os ponteiros e as referências são conceitos essenciais na manipulação de endereços de memória. Ponteiros são variáveis que armazenam o endereço de outra variável, permitindo a manipulação direta dos dados em diferentes locais de memória. Referências, por outro lado, são aliases para variáveis existentes e devem ser inicializadas no momento da declaração.

Diante disso, assinale a alternativa que descreve a diferença entre ponteiros e referências em C++.

A
Referências e ponteiros têm a mesma funcionalidade e são usados de maneira intercambiável.
B
Ponteiros não podem ser utilizados com arrays, enquanto referências são usadas exclusivamente com arrays.
C
Ponteiros são sempre inicializados no momento da declaração, enquanto referências não precisam ser inicializadas.
D
Referências podem ser alteradas para apontar para diferentes objetos, enquanto ponteiros não podem.
E
Ponteiros podem armazenar dados nulos, enquanto as referências não podem ser nulas na passagem de parâmetros.

Semana 2 5

#1

Para ser implementada, a pilha requer um vetor e uma variável que indique seu tamanho máximo e esta variável pode levar o nome de tam, por exemplo. Ao definir este limite, a pilha só pode contemplar a quantidade de elementos informada nesta variável e para saber quando excede o limite, é necessário saber a quantidade de elementos em dado momento.

Observe as alternativas e escolha a que identifica quantos elementos estão na pilha.

A
isEmpty
B
print
C
lenght
D
isFull
E
push
#2

No desenvolvimento de software, um dos conceitos fundamentais na programação orientada a objetos é a modularização do código. Este processo envolve a separação da visão lógica de uma estrutura de dados da sua implementação concreta. Para alcançar essa modularização, é essencial isolar a implementação da interface pública, permitindo que a complexidade interna seja escondida dos usuários da classe. Esta prática não apenas melhora a manutenção do código, mas também promove a reutilização de componentes.

Neste sentido, assinale a alternativa que identifique o termo que representa a ação de ocultamento citada no enunciado:

A
Encapsulamento.
B
Interface.
C
Sistema.
D
Instância.
E
Objeto.
#3

A pilha é uma das estruturas de dados mais simples que existe, ela permite o acesso aos seus elementos somente a partir do topo, ou seja, quando o elemento entra na pilha, ele passa a ser o canal para manipulação dos dados por ser o único acesso. Isso significa que a retirada de elementos acontece inversamente à forma de como foram colocados, ou seja, o primeiro a sair é o último elemento que entrou na pilha.

Em relação ao que foi citado no enunciado, assinale a alternativa que demonstra a parte do código responsável pela impressão. 

A
if (int i=0; i<length; i++)
B
for (int i=0; i<length; i++)
C
for (int i=1; i<length; i++)
D
for (int i=0; i<length; i--)
E
for (int i=0; i=length; i++)
#4

Quando a fila é implementada com um vetor, o espaço para alocar os elementos é adjacente. Isso significa que os elementos são adicionados no fim e removidos do início da fila, e para que isso aconteça é preciso conhecê-la identificando a presença de elementos.

Avalie as alternativas e assinale a que representa as respectivas operações para uma fila, ao ser implementada. 

A
isFull - enqueue - isEmpty - enqueue
B
isFull - enqueue - isFull - dequeue
C
isFull - dequeue - isEmpty - dequeue
D
itemType - enqueue - isEmpty - dequeue
E
isFull - enqueue - isEmpty - dequeue
#5

Na criação da classe Time, a definição de seus atributos é crucial para representar as características de um objeto de tempo. Dentro do arquivo de cabeçalho (.h), os atributos são definidos na seção privada, enquanto os métodos que permitem acessar e modificar esses atributos são definidos na seção pública. 

Diante disso, assinale a alternativa que apresenta um atributo típico definido na seção privada da classe Time. 

A
void setHour(int)
B
int getHour() const
C
void setTime(int, int, int)
D
void printTime() const
E
int hour

Semana 3 9

#1

Imagine que você está organizando uma fila de atendimento em uma loja. Cada cliente na fila é representado por um cartão, e cada cartão possui uma indicação de quem é o próximo cliente. Esse sistema permite que você facilmente adicione novos clientes ao final da fila ou remova o primeiro cliente após ser atendido.

Qual das seguintes opções compreende a vantagem desse sistema de organização em comparação a um sistema onde todos os cartões estão alinhados em uma única linha e você precisa deslocar todos os cartões ao adicionar ou remover um cliente?

A
Reduz a necessidade de memória para armazenar os cartões.
B
Exige que todos os cartões sejam colocados em uma ordem específica.
C
Evita a necessidade de deslocar todos os cartões ao adicionar ou remover clientes.
D
Garante que todos os clientes são atendidos ao mesmo tempo.
E
Permite acesso direto a qualquer cliente na fila a qualquer momento.
#2

Uma das vantagens em se trabalhar com listas encadeadas é sua versatilidade em poder incluir e remover elementos da lista a qualquer momento. Remover um nó de uma lista encadeada envolve atualizar as referências para garantir a continuidade da lista. O processo de remoção pode variar dependendo da posição do nó a ser removido.

Assinale a alternativa que identifica corretamente o procedimento para remover um nó do meio de uma lista encadeada.

A
Atualizar a referência do nó anterior para apontar para o final da lista.
B
Atualizar a referência do nó anterior aponta para o próximo nó do nó a ser removido.
C
Remover o nó anterior e atualizar a cabeça no início e final da lista com novos valores.
D
Atualizar a referência do nó a ser removido para apontar para o início da lista.
E
Atualizar a referência do último nó para apontar para o próximo nó do nó a ser removido.
#3

Uma lista encadeada é uma estrutura de dados composta por nós, onde cada nó contém informações sobre a sequência de nós a ser percorrida. Ao contrário de arrays, listas encadeadas não armazenam elementos em posições contíguas na memória, mas sim as posições de apontamentos para os demais nós.

Com base no contexto apresentado e nos materiais de estudos, identifique a alternativa correta que define a principal característica das listas encadeadas. 

A
Cada nó contém um valor e a referência para o próximo nó.
B
Cada nó contém um valor e a referência para o nó anterior.
C
Listas encadeadas têm tamanho fixo definido no momento da criação.
D
Os elementos são armazenados de maneira sequencial na memória.
E
Listas encadeadas não permitem operações de inserção ou remoção de elementos.
#4

Listas circularmente encadeadas são uma variação das listas encadeadas em que o último nó aponta para o primeiro nó, formando um ciclo. Essa estrutura possui algumas vantagens sobre as demais listas quando estamos falando de acesso rápido ao final da lista e para percorrer a uma lista de modo inverso (de trás para frente) se for necessário.

Com relação a este contexto e sobre o conteúdo estudado, avalie as asserções a seguir e a relação proposta entre elas:

I. Listas circularmente encadeadas são úteis para implementar estruturas que requerem iteração contínua sobre os elementos.

PORQUE  

II. Em uma lista circularmente encadeada, o último nó aponta para o primeiro nó, permitindo um acesso contínuo aos elementos sem a necessidade de redefinir o ponto inicial após atingir o final da lista.

A respeito dessas asserções assinale a alternativa correta:

A
A asserção I é uma proposição falsa, e a II é uma proposição verdadeira.
B
A asserção I é uma proposição verdadeira, e a II é uma proposição falsa.
C
As asserções I e II são proposições falsas.
D
As asserções I e II são proposições verdadeiras, mas a II não é uma justificativa correta da I.
E
As asserções I e II são proposições verdadeiras, e a II é uma justificativa correta da I.
#5

As listas encadeadas são estruturas de dados fundamentais que oferecem uma maneira flexível de armazenar e organizar dados na memória. Diferente das listas sequenciais, as listas encadeadas permitem a inserção e remoção de elementos de forma mais eficiente em termos de alocação de memória.

Considerando a definição e as características de uma lista encadeada, qual das opções abaixo identifica corretamente uma vantagem de usar listas encadeadas em vez de listas sequenciais?

A
As listas encadeadas são sempre mais rápidas para acessar elementos que as listas sequenciais.
B
As listas encadeadas não têm vantagens significativas em relação às listas sequenciais.
C
As listas encadeadas permitem acesso aleatório constante a qualquer elemento.
D
As listas encadeadas evitam a necessidade de deslocar elementos ao inserir ou remover dados.
E
As listas encadeadas requerem que todos os elementos estejam contíguos na memória.
#6

Imagine que você está organizando uma pilha de pratos em uma cozinha. Sempre que um novo prato é lavado, ele é colocado no topo da pilha. Da mesma forma, quando alguém precisa de um prato, ele é retirado do topo da pilha. Isso garante que o prato mais recentemente lavado seja o primeiro a ser utilizado, enquanto os pratos lavados anteriormente permanecem embaixo. Essa organização é eficiente e permite fácil acesso ao prato mais limpo.

Qual das seguintes afirmações interpreta corretamente a operação de inserção (push) em uma pilha implementada com listas encadeadas, considerando as particularidades de gerenciamento de memória e desempenho?

A
A inserção de um novo elemento em uma pilha encadeada é eficiente porque adiciona o novo elemento ao início da lista e ajusta apenas o ponteiro do topo da pilha.
B
A inserção de um novo elemento em uma pilha encadeada requer a atualização de todos os ponteiros dos elementos existentes na lista.
C
A inserção de um novo elemento em uma pilha encadeada ocorre no final da lista para manter a ordem sequencial.
D
A inserção de um novo elemento em uma pilha encadeada é ineficiente devido ao tempo necessário para percorrer toda a lista antes de inserir o novo elemento.
E
A inserção de um novo elemento em uma pilha encadeada envolve realocar todos os elementos em novas posições de memória contíguas.
#7

Uma pilha é uma estrutura de dados onde a inserção e a remoção de elementos ocorrem sempre no topo. Ao criar um algoritmo que implementa esta estrutura de dados em uma listas encadeadas, algumas operações básicas são utilizadas para manipular seus elementos na estrutura a ser desenvolvida.

Complete as lacunas abaixo com as palavras corretas que representam as operações básicas de uma pilha.

A operação de inserção de um novo elemento no topo da pilha é chamada de [preencher 1], enquanto a operação de remoção do elemento no topo é chamada de [preencher 2]. A operação que permite visualizar o elemento no topo da pilha sem removê-lo é chamada de [preencher 3] .

Os termos [preencher 1], [preencher 2] e [preencher 3] são corretamente substituídos por:

A
1 add, 2 remove, 3 check
B
1 push, 2 pop, 3 peek
C
1 insert, 2 delete, 3 view
D
1 insert, 2 remove, 3 top
E
1 push, 2 delete, 3 check
#8

Na implementação de uma fila utilizando lista encadeada, os métodos de inserção e remoção são fundamentais para o funcionamento correto da estrutura. Essa organização garante a propriedade FIFO (First In, First Out), essencial para diversas aplicações como gerenciamento de tarefas em sistemas operacionais e processamento de dados em buffers. Complete as lacunas na seguinte descrição sobre os métodos de inserção e remoção em uma fila utilizando lista encadeada. 

O método [preencher 1] adiciona um novo nó ao [preencher 2] da fila, atualizando o ponteiro [preencher 3] para apontar para este novo nó. 

Os termos [preencher 1], [preencher 2] e [preencher 3] são corretamente substituídos por:

A
1 enqueue; 2 início; 3 rear
B
1 enqueue; 2 final; 3 rear
C
1 dequeue; 2 final; 3 rear
D
1 dequeue; 2 início; 3 front
E
1 enqueue; 2 início; 3 front
#9

A implementação de uma pilha utilizando uma lista encadeada que requer a criação de uma estrutura de nó onde é informado os próximos elementos da pilha e funções para realizar operações de inserção (push) um novo elemento na pilha e remoção (pop) de um elemento da pilha já existente.

Complete o código em C++ para implementar as operações básicas (push e pop) de uma pilha utilizando uma lista encadeada. Preencha os espaços em branco indicados por /* ... */ para que o código funcione corretamente.

#include <iostream>

// Estrutura do nó

struct Node {

    int data;

    Node* next;

};

// Classe Pilha com Lista Encadeada

class Stack {

private:

    Node* top;

public:

    Stack() {

        top = nullptr;

    }

    void push(int value) {

        Node* newNode = new Node();

        newNode->data = value;

        newNode->next = /* ... */;

        top = newNode;

    }

    void pop() {

        if (top == nullptr) {

            std::cout << "Stack Underflow" << std::endl;

            return;

        }

        Node* temp = top;

        top = /* ... */;

        delete temp;

    }

}

O preenchimento correto se afirma em:

A
newNode->next = top; e top = newNode->next;
B
newNode->next = nullptr; e top = top->next;
C
newNode->next = nullptr; e top = nullptr;
D
newNode->next = top; e top = top->next;
E
newNode->next = top; e top = nullptr;

Semana 4 10

#1

A função de hash desempenha um papel crucial na determinação da posição de armazenamento dos dados em uma tabela hash. Esta que é eficiente é essencial para minimizar colisões, que acontecem quando duas chaves distintas produzem o mesmo índice. Compreender o propósito e o funcionamento da função de hash é fundamental para o uso eficaz das tabelas hash.



Com base no contexto apresentado, assinale a alternativa que identifica corretamente o propósito da função de hash em uma tabela hash.

A
A função de hash verifica se a tabela hash está cheia.
B
A função de hash criptografa os dados antes de armazená-los.
C
A função de hash remove elementos duplicados da tabela hash.
D
A função de hash ordena os elementos da tabela hash em ordem crescente.
E
A função de hash calcula o índice de armazenamento na tabela, baseado na chave.
#2

Em uma tabela hash, as colisões ocorrem quando duas chaves diferentes são mapeadas para o mesmo índice do array. Diversas técnicas podem ser utilizadas para resolver essas colisões. Entre essas técnicas, o endereçamento aberto é amplamente utilizado. 


Assinale a alternativa que responde corretamente como o endereçamento aberto resolve colisões em uma tabela hash. 

A
Procurando outra posição livre na tabela.
B
Aumentando o tamanho da tabela hash.
C
Usando uma lista encadeada para cada posição da tabela.
D
Utilizando duas funções de hash diferentes.
E
Removendo elementos antigos para dar lugar aos novos.
#3

A eficiência de uma função de dispersão é determinada por várias condições essenciais para o bom funcionamento de uma tabela de dispersão. Essas condições garantem que as chaves sejam distribuídas de maneira uniforme e que o número de colisões seja minimizado.

Com relação às características e desafios na implementação de funções de dispersão, analise as asserções a seguir e a relação proposta entre elas:

I. Uma boa função de dispersão deve ser uniforme, ou seja, deve garantir que todos os compartimentos da tabela tenham a mesma probabilidade de serem escolhidos.

PORQUE

II. A uniformidade de uma função de dispersão é difícil de ser testada na prática devido à distribuição desconhecida das chaves.

A respeito dessas asserções, assinale a alternativa correta:

A
A assertiva I é verdadeira e a assertiva II é falsa.
B
A assertiva I é falsa e a assertiva II é verdadeira.
C
As assertivas I e II são falsas.
D
As assertivas I e II são verdadeiras, e a II justifica a I.
E
As assertivas I e II são verdadeiras, mas a II não justifica a I.
#4

Na implementação de tabelas hash, é importante compreender a criação de métodos construtores e de acesso para manipulação dos dados. Suponhamos que a classe Aluno está sendo implementada com dois construtores, um sem parâmetros e outro com parâmetros, além de métodos de acesso (getters) para o RA e o nome.

Considere a implementação da classe Aluno na tabela hash, leia as seguintes alternativas e assinale qual delas descreve corretamente a aplicação do método construtor sem parâmetros.

A
O construtor sem parâmetros é inicializado com qualquer atributo de valores fornecidos.
B
O construtor sem parâmetros inicializa, o RA como 0 e o nome como uma string vazia.
C
O construtor sem parâmetros inicializa, o RA com -1 e o nome com uma string qualquer.
D
O construtor sem parâmetros é irrelevante na implementação de tabelas hash.
E
O construtor sem parâmetros define o RA como 1 e o nome como "Aluno".
#5

No estudo de tabelas hash, um problema comum é a ocorrência de colisões, que ocorrem quando duas chaves diferentes geram o mesmo valor de hash e apontam para a mesma posição na tabela. Para tratar essas colisões, podem ser utilizadas várias técnicas, como o encadeamento separado e o teste linear. O encadeamento separado utiliza uma estrutura de dados adicional, geralmente uma lista encadeada, para armazenar todos os elementos que colidem em uma mesma posição.


Qual das alternativas a seguir descreve corretamente o funcionamento do encadeamento separado em uma tabela hash?

A
No encadeamento separado, elementos colididos são armazenados em uma lista encadeada associada à posição original da colisão.
B
O encadeamento separado usa uma função hash secundária para realocar elementos colididos em diferentes posições na tabela.
C
O encadeamento separado utiliza uma técnica de sondagem para encontrar a próxima posição livre na tabela onde o elemento colidido será armazenado.
D
O encadeamento separado implementa um algoritmo de ordenação para reordenar os elementos colididos em uma nova sequência.
E
No encadeamento separado, elementos colididos são descartados e armazenados em uma tabela hash auxiliar.
#6

Em uma tabela de dispersão, a eficiência da função de dispersão é fundamental para garantir uma boa performance. Uma função de dispersão eficiente deve cumprir certas condições ideais, cada uma com sua própria descrição. Essas condições incluem minimizar colisões, ser fácil de calcular e garantir que todos os compartimentos da tabela tenham a mesma probabilidade de serem escolhidos. 

Associe corretamente cada condição com a sua descrição correspondente, considerando as características essenciais para o bom funcionamento da tabela de dispersão.

Condições: Descrições:
1 - Produzir um número baixo de colisões A. Significa que todos os compartimentos têm a mesma probabilidade de serem escolhidos.
2 - Ser facilmente computável B. Importante para evitar padrões conhecidos nas chaves.
3 - Ser uniforme C. Essencial para minimizar o tempo de cálculo em tabelas armazenadas em memória.

Assinale a alternativa correta:

A
1-B, 2-C, 3-A
B
1-C, 2-A, 3-B
C
1-B, 2-A, 3-C
D
1-A, 2-B, 3-C
E
1-A, 2-C, 3-B
#7

Suponha que existam 𝑛 chaves a serem armazenadas em uma tabela 𝑇, sequencial e de dimensão 𝑚. As posições da tabela se situam no intervalo [0,m1][0, m-1]. Em um caso simples, onde o número de chaves nn n é igual ao número de compartimentos 𝑚, os valores das chaves são 0, 1, ..., m1m-1 Utiliza-se diretamente o valor de cada chave como seu índice na tabela, técnica conhecida como acesso direto. No entanto, para resolver a questão de armazenamento eficiente quando n<mn e mnm-n é grande, emprega-se a função de dispersão h(x)h(x), que transforma cada chave  𝑥  em um valor no intervalo [0,m1][0, m-1]. Se o compartimento h(x)h(x) estiver ocupado, ocorre uma colisão, é um procedimento especial é usado para o armazenamento de 𝑥.

Dada a função de dispersão h=xmod5h = x \bmod 5 e as chaves 78 e 13, qual é o compartimento da tabela que causará a colisão?

A
Compartimento 5
B
Compartimento 1
C
Compartimento 4
D
Compartimento 2
E
Compartimento 3
#8

No contexto de tabelas de dispersão, uma função de dispersão é utilizada para transformar uma chave em um índice da tabela. Este índice determina o compartimento onde a chave será armazenada. Uma técnica simples, porém  eficaz, é utilizar o valor da chave como índice diretamente na tabela. No entanto, para evitar problemas de espaço, utiliza-se uma função de dispersão, que pode causar um fenômeno onde duas ou mais chaves são mapeadas para o mesmo índice. 


Leia o trecho a seguir:


Uma técnica simples de mapeamento de chaves para índices é o [preencher 1], enquanto a função de dispersão ajuda a distribuir chaves entre os compartimentos. O fenômeno onde várias chaves são mapeadas para o mesmo índice é conhecido como [preencher 2], e o método de resolução deste problema é chamado de [preencher 3].


Os termos [preencher 1], [preencher 2] e [preencher 3] são corretamente substituídos por:

A
1 acesso direto, 2 colisões, 3 encadeamento
B
1 distribuição direta, 2 colisões, 3 encadeamento
C
1 acesso indireto, 2 distribuição, 3 tratamento
D
1 encadeamento direto, 2 colisões, 3 distribuição
E
1 acesso direto, 2 tratamento, 3 encadeamento
#9

Os métodos de dispersão desempenham um papel fundamental na eficiência das tabelas de dispersão. Dois métodos amplamente utilizados são o método da divisão e o método da dobra. Cada método possui características distintas que influenciam sua aplicabilidade e eficiência.


Sobre os métodos de dispersão utilizados em tabelas de dispersão, observe as afirmativas a seguir:

I. No método da divisão, escolher 𝑚 como uma potência de 2 é ideal para garantir uma distribuição uniforme das chaves.
II. No método da dobra, os dígitos da chave são somados sem levar em consideração o "vai um".
III. O método da divisão utiliza o resto da divisão da chave 𝑥 por 𝑚 como endereço-base.
IV. No método da dobra, a operação de "ou exclusivo" (ou ex) entre pedaços da chave pode ser utilizada para melhorar a distribuição das chaves.

Está correto o que se afirma em:

A
II, III e IV.
B
I e III, apenas.
C
I e II, apenas.
D
I, apenas.
E
II e III, apenas.
#10

As tabelas hash são estruturas de dados utilizadas para armazenar e buscar informações de maneira eficiente. Um exemplo prático da aplicação de tabelas hash é a organização de registros acadêmicos em uma universidade, onde o registro acadêmico (RA) do aluno é utilizado como chave de busca para encontrar o nome do aluno.


Com base no exemplo da aplicação de tabelas hash em uma universidade para organizar registros acadêmicos, leia as alternativas abaixo e escolha a correta.

A
A eficiência da busca na tabela hash depende da qualidade da função de hash utilizada.
B
As tabelas hash não são recomendadas para grandes volumes de dados.
C
O RA de um aluno é usado como índice na tabela hash, sem necessidade de cálculo adicional.
D
A tabela hash garante que não haverá colisões ao utilizar o RA como chave de busca.
E
A única informação armazenada na tabela hash, além do RA, é a idade do aluno.

Semana 5 11

#1

Considere a classe Aluno definida em C++ e sua utilização em uma árvore binária de busca. O código a seguir mostra a definição do nó da árvore binária de busca:


struct TreeNode {

    Aluno aluno;

    TreeNode* left;

    TreeNode* right;


    TreeNode(const Aluno& aluno) : aluno(aluno), left(nullptr), right(nullptr) {}

};


Com relação à definição e utilização de um nó do tipo Aluno em uma árvore binária de busca, observe as afirmativas a seguir:

  1. O struct TreeNode contém um objeto Aluno e dois ponteiros para outros nós.
  2. O construtor do struct TreeNode inicializa o objeto Aluno e define os ponteiros left e right como nullptr.
  3. A estrutura TreeNode permite criar uma árvore binária de busca que armazena objetos do tipo Aluno.
  4. O método insert na árvore binária de busca deve comparar os atributos nome dos objetos Aluno para inserir um novo nó corretamente.
  5. Para buscar um nó na árvore, é necessário comparar o atributo ra dos objetos Aluno.

Está correto o que se afirma em:

A
I, II e III
B
I, III, IV e V
C
I, II, III e IV
D
I, II, III e V
E
II, III, IV e V
#2

Considere a implementação da função destroyTree em uma árvore binária de busca para destruir todos os nós da árvore utilizando o caminhamento pós-ordem. O código a seguir mostra a definição da classe BinarySearchTree com o método destroyTree:


class BinarySearchTree {

private:

    struct TreeNode {

        Aluno aluno;

        TreeNode* left;

        TreeNode* right;

        

        TreeNode(const Aluno& aluno) : aluno(aluno), left(nullptr), right(nullptr) {}

    };


    TreeNode* root;


    void destroyTree(TreeNode* node) {

        if (node == nullptr) {

            return;

        }

        destroyTree(node->left);

        destroyTree(node->right);

        std::cout << "Deletando nó com RA: " << node->aluno.getRA() << std::endl;

        delete node;

    }


public:

    BinarySearchTree() : root(nullptr) {}

    ~BinarySearchTree() {

        destroyTree(root);

    }

};


Com relação ao funcionamento do método destroyTree, observe as afirmativas a seguir:

  1. O método destroyTree utiliza o caminhamento pré-ordem para deletar os nós da árvore.
  2. O método destroyTree é chamado recursivamente para deletar todos os nós da árvore.
  3. O método destroyTree deleta primeiro os nós das subárvores esquerda e direita antes de deletar o nó atual.
  4. O método destroyTree é invocado automaticamente pelo destrutor da classe BinarySearchTree.
  5. O método destroyTree não imprime nenhuma mensagem durante a destruição dos nós.


Está correto o que se afirma em:

A
II, III e IV
B
II, IV e V
C
I, II e III
D
I, IV e V
E
III, IV e V
#3

Considere o seguinte trecho de código que define um método destroyTree para destruir uma árvore binária utilizando caminhamento pós-ordem:

void destroyTree(Node* node) {

    if (node == nullptr) {

        return;

    }

    

    destroyTree(node->left);

    destroyTree(node->right);

    

    std::cout << "Deletando nó com valor: " << node->data << std::endl;

    delete node;

}


Com base no código acima, qual das alternativas a seguir apresenta a ordem nas quais os nós são deletados:

A
Os nós são deletados na ordem de visita: subárvore direita, subárvore esquerda, nó atual.
B
Os nós são deletados na ordem de visita: subárvore direita, nó atual, subárvore esquerda.
C
Os nós são deletados na ordem de visita: nó atual, subárvore esquerda, subárvore direita.
D
Os nós são deletados na ordem de visita: nó atual, subárvore direita, subárvore esquerda.
E
Os nós são deletados na ordem de visita: subárvore esquerda, subárvore direita, nó atual.
#4

Considere as seguintes definições sobre árvores em estruturas de dados: A altura de um nó é o comprimento do caminho mais longo entre o nó até uma [preencher 1]. A profundidade de um nó é a [preencher 2] percorrida da raiz até o nó. Uma árvore binária é aquela em que abaixo de cada nó existem no máximo [preencher 3] subárvores.


Os termos [preencher 1], [preencher 2][preencher 3] são corretamente substituídos por:

A
1 raiz - 2 altura - 3 três
B
1 folha - 2 altura - 3 duas
C
1 raiz - 2 distância - 3 três
D
1 folha - 2 caminho - 3 duas
E
1 folha - 2 distância - 3 duas
#5

Considere a implementação da classe BinarySearchTree em C++ e o método insert utilizado para incluir um novo aluno na árvore binária de busca:

void insert(const Aluno& aluno) {

    root = insert(root, aluno);

}


TreeNode* insert(TreeNode* node, const Aluno& aluno) {

    if (node == nullptr) {

        return new TreeNode(aluno);

    }

    if (aluno.getRA() < node->aluno.getRA()) {

        node->left = insert(node->left, aluno);

    } else if (aluno.getRA() > node->aluno.getRA()) {

        node->right = insert(node->right, aluno);

    }

    return node;
}

I. O método insert insere um novo aluno na árvore binária de busca comparando o RA do aluno a ser inserido com o RA dos nós existentes na árvore.

PORQUE,

II.se o RA do aluno a ser inserido é menor que o RA do nó atual, o método insere o aluno na subárvore direita; caso contrário, insere na subárvore esquerda.

A respeito dessas asserções, assinale a alternativa correta.

A
As asserções I e II são proposições verdadeiras, mas a II não é uma justificativa da I.
B
A asserção I é uma proposição verdadeira, e a II é uma proposição falsa.
C
As asserções I e II são falsas.
D
As asserções I e II são proposições verdadeiras, e a II é uma justificativa da I.
E
A asserção I é uma proposição falsa, e a II é uma proposição verdadeira.
#6

Considere a implementação da classe BinarySearchTree em C++ e os métodos para imprimir o conteúdo de uma árvore binária de busca em pré-ordem (pre-order), in-ordem (in-order) e pós-ordem (post-order):



void preOrderPrint() const {

    preOrderPrint(root);

}


void preOrderPrint(TreeNode* node) const {

    if (node == nullptr) {

        return;

    }

    node->aluno.display();

    preOrderPrint(node->left);

    preOrderPrint(node->right);

}


void inOrderPrint() const {

    inOrderPrint(root);

}


void inOrderPrint(TreeNode* node) const {

    if (node == nullptr) {

        return;

    }

    inOrderPrint(node->left);

    node->aluno.display();

    inOrderPrint(node->right);

}


void postOrderPrint() const {

    postOrderPrint(root);

}


void postOrderPrint(TreeNode* node) const {

    if (node == nullptr) {

        return;

    }

    postOrderPrint(node->left);

    postOrderPrint(node->right);

    node->aluno.display();
}


I. O método preOrderPrint percorre a árvore binária de busca imprimindo primeiro o nó raiz, seguido pela subárvore esquerda e, por último, a subárvore direita. 

PORQUE

II. O método postOrderPrint realiza o percurso da árvore binária de busca imprimindo os nós na seguinte ordem: subárvore esquerda, subárvore direita e, finalmente, o nó raiz.

A
As asserções I e II são falsas.
B
A asserção I é uma proposição falsa, e a II é uma proposição verdadeira.
C
As asserções I e II são proposições verdadeiras, e a II é uma justificativa da I.
D
As asserções I e II são proposições verdadeiras, mas a II não é uma justificativa da I.
E
A asserção I é uma proposição verdadeira, e a II é uma proposição falsa.
#7

Considere a implementação da classe BinarySearchTree em C++ e os métodos para imprimir o conteúdo de uma árvore binária de busca em pré-ordem (pre-order):


void preOrderPrint() const {

    preOrderPrint(root);

}


void preOrderPrint(TreeNode* node) const {

    if (node == nullptr) {

        return;

    }

    node->aluno.display();

    preOrderPrint(node->left);

    preOrderPrint(node->right);




A partir do código apresentado, analise as seguintes afirmações e determine qual conjunto de instruções sintetiza corretamente o comportamento dos métodos preOrderPrint.

A
Os métodos preOrderPrint percorrem a árvore binária de busca visitando primeiro a subárvore direita, depois o nó raiz e, finalmente, a subárvore esquerda, imprimindo os dados de cada nó na ordem em que são visitados.
B
Os métodos preOrderPrint percorrem a árvore binária de busca visitando primeiro o nó raiz, depois a subárvore esquerda e, finalmente, a subárvore direita, imprimindo os dados de cada nó na ordem em que são visitados.
C
Os métodos preOrderPrint percorrem a árvore binária de busca utilizando um algoritmo de busca em largura (breadth-first search), imprimindo os dados de cada nó na ordem em que são visitados.
D
Os métodos preOrderPrint percorrem a árvore binária de busca visitando primeiro a subárvore esquerda, depois o nó raiz e, finalmente, a subárvore direita, imprimindo os dados de cada nó na ordem em que são visitados.
E
Os métodos preOrderPrint percorrem a árvore binária de busca utilizando um algoritmo de busca em profundidade (depth-first search), visitando primeiro os nós folha e, finalmente, o nó raiz, imprimindo os dados de cada nó na ordem em que são visitados.
#8

Em estruturas de dados, uma árvore é um conjunto de nós onde existe um nó raiz r que pode conter subárvores ligadas diretamente a este nó. Uma subárvore é também uma árvore. Ressalta-se que não há um sucessor e um predecessor para cada nó de uma árvore e, por isto, estruturas lineares não são adequadas para representar este tipo de hierarquia nos dados.

Assinale a alternativa que identifica corretamente uma das características de uma árvore de estrutura de dados.

A
Uma árvore é uma estrutura linear usada para representar hierarquias.
B
Em uma árvore, cada nó tem exatamente um sucessor e um predecessor.
C
Uma subárvore em uma árvore não pode ser considerada uma árvore.
D
Estruturas lineares são adequadas para representar hierarquias nos dados.
E
Em uma árvore, um nó raiz contém zero ou mais subárvores ligadas diretamente a ele.
#9

Árvores binárias de busca são estruturas fundamentais que podem ser usadas em situações nas quais se pretende organizar os dados. Além disso, quando as inserções e remoções são bastante frequentes, estas são estruturas melhores do que arranjos ordenados.

Com base no texto apresentado, escolha as afirmativas que complementam corretamente as informações já apresentadas:
  1. Árvores binárias de busca são úteis para organizar dados utilizando uma chave de busca.
  2. Arranjos ordenados são preferíveis às árvores binárias de busca.
  3. Árvores binárias de busca são usadas para construir outras estruturas.
  4. Árvores binárias de busca são menos eficientes que arranjos ordenados quando a ordenação dos dados é necessária.
  5. Árvores binárias de busca são apropriadas para situações em que a organização dos dados é feita por meio de uma chave de busca.


Está correto o que se afirma em:

A
I, II e V, apenas.
B
I, III e V, apenas.
C
I, III, IV e V
D
III e IV, apenas.
E
II e IV, apenas.
#10

Supondo que não é permitida a duplicação em uma árvore binária de estrutura de dados, apenas é inserido um novo nó se o elemento não existe. Nesse caso, basta inserir o elemento na posição que ele estaria se fosse buscado. Para a remoção de um nó, três casos principais são considerados:
  1. O nó a ser removido é uma folha (não tem filhos).
  2. O nó a ser removido tem um único filho.
  3. O nó a ser removido tem dois filhos.

Com base nessas informações, indique qual das alternativas abaixo descreve corretamente a ação a ser tomada para remover um nó com dois filhos.

A
O nó é simplesmente removido e nenhum outro nó é movido.
B
O nó é substituído pelo maior nó da sua subárvore esquerda.
C
O nó é substituído pelo menor nó da sua subárvore direita.
D
O nó é substituído pelo seu filho esquerdo.
E
O nó é substituído pelo seu filho direito.
#11

Considere a classe Aluno definida em C++ com a seguinte declaração de atributos e métodos. A informação que se pretende armazenar é o nome do aluno, e cada RA de aluno é um número único.


class Aluno {

private:

    int ra;

    std::string nome;

public:

    Aluno();

    Aluno(int ra, std::string nome);

    void display() const;

    int getRA() const;

    std::string getNome() const;

    void setRA(int ra);

    void setNome(std::string nome);

};


Associe corretamente os métodos com suas explicações. Considere que nem todos os itens das colunas podem possuir associação ou podem possuir mais de uma correlação.


Método Explicação sobre o método
I. Aluno() A. Construtor que inicializa ra com -1 e nome com " ".
II. Aluno(int ra, std::string nome)
B. Construtor que inicializa ra e nome com valores fornecidos.
III. display() C. Método que exibe os valores de ra e nome.
IV. getRA()
D. Método que retorna o valor de ra.
V. getNome()
E. Método que retorna o valor de nome.

Assinale a alternativa que contém a associação correta.

A
I-A, II-C, III-B, IV-E, V-D
B
I-A, II-B, III-D, IV-C, V-E
C
I-C, II-A, III-B, IV-F, V-D
D
I-A, II-B, III-C, IV-D, V-E
E
I-B, II-A, III-C, IV-D, V-E