TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS TURMA 2008/1 – 2 PERÍODO – MÓDULO 3 AVALIAÇÃO MP2 – DATA 2/10/2008 ESTRUTURAS DE DADOS 2008/2 Dados de identificação do Acadêmico: Nome: _______________________________________ Login:___________ CA:__________________ Cidade:____________________________UF____ CARTÃO – RESPOSTA QUESTÃO RESPOSTA QUESTÃO RESPOSTA A 1 2 3 4 F 1 2 3 4 B 1 2 3 4 G 1 2 3 4 C 1 2 3 4 H 1 2 3 4 D 1 2 3 4 I 1 2 3 4 E 1 2 3 4 J 1 2 3 4 Dados de identificação do Tutor: Nome: _______________________________________ Login:___________ CA:__________________ Cidade:__________________UF______________ INSTRUÇÕES: A prova está composta de 10 questões de A a J, e 4 alternativas enumeradas de 1 a 4. Utilize caneta esferográfica azul ou preta para preenchimento do cartão-resposta. O cartão-resposta deve ser preenchido, assinado, destacado e entregue ao Tutor. Questões rasuradas serão anuladas. Sem o devido preenchimento do CAMPO DE IDENTIFICAÇÃO, o cartão-resposta não terá validade. Somente terão acesso às notas lançadas no boletim os acadêmicos regularmente matriculados. Os acadêmicos têm três dias após a divulgação do gabarito oficial para requerer revisão de questões (recursos). Devem constar os seguintes dados para análise: Tipo da avaliação, Etapa, identificação da questão e justificativa do pedido. Mais esclarecimentos acerca dos procedimentos para pedidos de Recursos acessem a página WWW.unitins.br/logisticaavaliacao. _____________________________________ Assinatura do acadêmico ______________________________________ Assinatura do Tutor __________________________________________, _____/_____/2008 Local 1 ESTRUTURAS DE DADOS PROFESSORES: ALEXANDRE ROSSINI CARLOS HENRIQUE CORRÊA TOLENTINO ALEX COELHO MARCO ANTONIO YZAAC GONÇALVES A. Analise a função principal e a estrutura de fila apresentada no exemplo a seguir, e considerando as funções enqueue e dequeue para inserção e remoção respectivamente, assinale a alternativa INCORRETA. 1 struct fila{ 2 int inicio; 3 int final; 4 int conteudo[10]; 5 }; 6 int main(){ 7 int i, dados; 8 struct fila nova_fila; 9 nova_fila.inicio=0; 10 nova_fila.final=0; 11 12 for(i=0;i < 10;i++){ 13 enqueue(&nova_fila, i); 14 if(i%2 == 0 ){ 15 dados = dequeue(&nova_fila); 16 printf("Removido\n"); 17 printf("%d\n", dados); 18 } 19 } 20 printf("%d", nova_fila.inicio); 21 system("pause"); 22 } Observe as afirmações a seguir e assinale a que for verdadeira. 1. O valor impresso para o inicio da fila será 5; 2. A fila implementada consiste em uma fila com alocação seqüencial de memória; 3. São excluídos da fila todos os elementos no qual o resultado do resto da divisão de seu conteúdo por dois seja igual a zero; 4. A cada iteração do laço “for” são inseridos na fila, como conteúdo, os valores da variável i. COMENTÁRIO: A alternativa verdadeira para a questão (a que satisfaz o enunciado), ou seja, a INCORRETA é a alternativa 3. Analisando o exemplo vemos que, a cada iteração do laço FOR, o valor da variável de controle “i” é inserido na fila (alternativa 4 é CORRETA), fazendo com que, por coincidência, o conteúdo das posições da fila sejam preenchidos com esses valores. Em seguida, é verificado se o resto da divisão da variável de controle “i” – e não o conteúdo da fila – por 2 é igual a zero, caso seja verdade, é executada a operação dequeue (alternativa 3 INCORRETA), o elemento do início da fila é removido e apresentado na tela. A seqüência de entrada dos elementos é 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Considerando que 5 elementos serão removidos (observe que a variável de controle “i” assume valor par em 5 situações) o primeiro elemento da fila será 5 (alternativa 1 é CORRETA). Como podemos perceber na declaração da estrutura 2 “fila”, um vetor é utilizado para armazenar os elementos, o que caracteriza alocação seqüencial de memória (alternativa 2 CORRETA). B. Analise o código a seguir, no qual são apresentadas as funções de uma fila e sua estrutura, e escolha a alternativa CORRETA. Considere que os campos da estrutura são inicializados no programa principal. 1 typedef struct fila{ 2 int inicio; 3 int ocupado; 4 int final; 5 int conteudo[4]; 6 }fila; 7 void enqueue(fila *f, int dados){ 8 if(f->ocupado == 4) 9 printf("\n!!!!!!Fila cheia!!!!!!!!\n"); 10 else { 11 f->conteudo[f->final] = dados; 12 f->final++; 13 f->ocupado++; 14 if(f->final > 3) 15 f->final=0; 16 } 17 } 18 int dequeue(fila *f){ 19 if( f->ocupado == 0 ) 20 printf("\n!!!!!!!!!Fila vazia!!!!!!!!!!!!!!\n"); 21 else{ 22 f->inicio++; 23 if (f->inicio==4) 24 f->inicio=0; 25 f->ocupado- -; 26 return f->conteudo[f->inicio-1]; 27 } 28 } 1. Ocorrerá um erro na função enqueue, linha 11. 2. O código consiste na implementação de uma fila circular. 3. A função dequeue remove elementos a partir do final da fila. 4. Nenhuma das alternativas está correta. COMENTÁRIO: A alternativa correta da questão é a de número 2. A alternativa 1 está INCORRETA, pois na linha 11 o valor armazenado no campo “final” é usado como índice para referenciar uma posição no vetor que armazena os elementos. Sendo um valor inteiro, não há problemas com a declaração. A alternativa 2 está CORRETA. Observe as linhas 14-15 e 23-24 e perceba que, sempre que o início ou o final da fila assume um valor maior que 3 (última posição do vetor), eles recebem o valor 0, implementando o princípio da circularidade nessa fila. A alternativa 3 está INCORRETA, pois em qualquer fila a operação dequeue remove um elemento do INÍCIO da fila. A alternativa 4 é INCORRETA, já que a a alternativa 2 é correta. 3 C. Classifique em (V)erdadeira ou (F)alsa as afirmações sobre lista simplesmente encadeada, e escolha a opção que apresenta a seqüência CORRETA: I – Possui apenas um ponteiro para o próximo nó da lista. II – Utiliza somente a quantidade de memória necessária. III – Possui uma estrutura do tipo FIFO. 1. V, V, F 2. F, F, F 3. V, V, V 4. F, F, V COMENTÁRIO: A resposta correta é a alternativa 1. A afirmativa I é verdadeira e segundo Forbellone e Eberspacher (2005, p. 153) e exposto na apostila (página 58) lista simplesmente encadeada é definida como um “conjunto de elementos individualizados em que cada um referencia um outro elemento distinto como sucessor”. Nessa definição está claro que há somente um encadeamento (realizado por apenas um ponteiro) que referencia (aponta) um elemento (nó) sucessor (próximo). Além disso, na página 61 da apostila é apresentada a estrutura (struct) do nó de uma lista simplesmente encadeada, o que confirma o explicado anteriormente. A afirmativa II é verdadeira porque, de acordo com o algoritmo de inserção desta estrutura, aloca-se um novo nó somente quando da inserção de um elemento nela. Se aloca-se memória somente durante a inserção, então ela utiliza somente a quantidade de memória necessária. A afirmativa III é falsa, isso porque, de acordo com o segundo parágrafo da página 48 da apostila, a estrutura do tipo FIFO (First-In/First-Out – Primeiro a entrar/Primeiro a sair) é a fila e não a lista simplesmente encadeada. D. Considere as alternativas a seguir sobre lista ordenada simplesmente encadeada e assinale a INCORRETA: 1. São funções de uma lista ordenada simplesmente encadeada a inserção, remoção e busca. 2. NULL é usado para indicar o final de uma lista. 3. Na remoção, na existência de elementos repetidos, será sempre excluído o último elemento da lista. 4. Na existência de elementos repetidos a função busca pode retorna a posição da primeira ocorrência do elemento procurado. COMENTÁRIO: A resposta a ser assinalada é a alternativa 3. Como relatado na apostila no terceiro parágrafo da página 61, para uma lista simplesmente encadeada costuma-se implementar três operações básicas, sendo a Ins, Rem e Find, que são responsáveis pela inserção, remoção e busca, respectivamente. Portanto, a assertiva 1 está correta, ou seja, não é a resposta esperada para a questão, já que procura-se pela alternativa incorreta. A assertiva 2 indica que NULL é utilizado para caracterizar o final de uma lista. A afirmação é verdadeira e pode ser comprovada observando os últimos parágrafos da página 61 da apostila. Assim, essa também não é a alternativa correta para a questão. A assertiva 4 faz alusão à busca de dados em uma lista que possui elementos repetidos. Tratando-se de uma função de busca, a idéia é retornar positivamente quando um elemento procurado é encontrado. Esse retorno positivo pode ser caracterizado com a posição do elemento procurado. Uma das maneiras de otimizar a busca é retornar positivamente assim que encontrar uma ocorrência do elemento procurado, ou seja, na primeira ocorrência do elemento. Assim, a assertiva 4 está correta e não é a opção adequada para resolução da questão. A assertiva 3, faz a afirmação de que na existência de elementos repetidos, sempre será excluído o último elemento da lista (independente de ser o procurado), o que não faz sentido, pois em uma 4 lista a remoção ocorre em um elemento determinado e previamente procurado. Por tanto, a afirmação de que sempre será excluído o último elemento de uma lista no caso de ocorrer repetição de elementos é incorreta, ou seja, essa é a alternativa adequada para questão. E. Ao longo da disciplina diversas estruturas de dados foram estudas e é de fundamental importância conhecer as particularidades de cada uma das estruturas. Considerando o trecho de código a seguir, efetue a associação do código com seu respectivo tipo de estrutura de dado, sua funcionalidade e assinale a alternativa CORRETA. Considere que a verificação se a estrutura está ou não vazia é realizada no bloco principal do programa. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1. 2. 3. 4. #define MAX 10 typedef struct estrutura{ int inicio; int final; int conteudo[10]; }nova_estrutura; void funcao(nova_estrutura *estruturaLocal) { int i; for (i=1; i<estruturaLocal->final; i++) estruturaLocal->conteudo[i-1]=estruturaLocal->conteudo[i]; estruturaLocal->final- -; } O trecho de código realiza a inserção em uma fila circular. O trecho de código realiza a inserção em uma pilha. O trecho de código realiza a remoção em uma fila. O trecho de código realiza a inserção em uma fila. COMENTÁRIO: A resposta correta é a alternativa 3, ou seja, é realizada a remoção do primeiro elemento da fila, sendo que os elementos seguintes ocupam novas posições na fila, sendo deslocados uma posição adiante. Analisando a função “funcao” o laço for existente é o responsável por percorrer toda a fila, sendo que o inicio do processo é realizado a partir do segundo elemento da fila já que a variável i é inicializada com o valor 1. Assim na primeira iteração na fila seqüencial o elemento da posição 0 será sobrescrito pelo da posição 1. A cada iteração do laço o elemento da posição i sobrescreve o elemento da posição anterior, no caso a posição i-1. Após ter sido percorrido todo o loop o elemento que indica o final da fila é decrementado, de maneira a indicar a nova posição do último elemento. F. Observe a seguinte função em linguagem C e assinale a alternativa INCORRETA. 1 int busca(int vetor[30], int n) 2 { 3 int i=0; 4 while(i<30) 5 { 6 if(vetor[i] == n) 7 return i; 8 i++; 9 } 5 10 11 } return -1; 1. Esta função implementa um método de busca mais eficiente, em todos os casos, do que a busca binária quando aplicadas sobre um vetor ordenado. 2. Se usarmos esta função para procurar um elemento que não se encontra no vetor, mesmo o vetor estando ordenado, esta função irá percorrer todo o vetor. 3. Esta função implementa uma busca seqüencial por um elemento “n” em um vetor de, no máximo, 30 posições. 4. O método de busca implementado na função é mais adequado do que a busca binária quando aplicadas a vetores não ordenados. COMENTÁRIO: A alternativa a ser assinalada é a de número 1. Assim, a alternativa 1 está INCORRETA, já que a busca implementada na função seria menos eficiente que uma busca binária sobre um vetor ordenado. Por exemplo, se o elemento estivesse localizado após a metade do vetor, sendo que para a localização com um busca binária seriam necessários, no pior caso, 6 passos, enquanto no pior caso de uma busca seqüencial igual a realizada na „funcao‟ em seu pior caso serão necessário 30 passos, correspondendo ao tamanho do vetor, ou seja, as interações seriam reduzidas drasticamente. A alternativa 2 está correta pois, ordenado ou desordenado, caso o elemento não esteja no vetor isso só será constatado quando a busca tiver ocorrido sobre todas as posições do vetor, já que ele só irá para caso o elemento seja encontrado. A alternativa 3 também está correta, uma vez que é realizada uma busca do elemento „n‟ passado como argumento na linha 1, sobre um vetor de 30 posições que também foi passado como argumento na mesma linha 1. A alternativa 4 também está correta, pois caso o vetor não esteja ordenado não há como determinar qual das ramificações devem ser percorridas pela busca binária. G. Relacionando métodos de busca e ordenação com listas encadeadas, analise as seguintes afirmações e aponte a alternativa CORRETA. 1. Em listas ordenadas simplesmente encadeadas, é natural que os elementos sejam inseridos ordenadamente, não necessitando aplicar um algoritmo específico para ordenação. 2. Para ordenar uma lista simplesmente encadeada, o método QuickSort é o mais adequado uma vez que percorre menos vezes a lista, resultando em menor tempo de processamento. 3. Listas simplesmente encadeadas são ordenadas de maneira mais eficiente pelo método BubbleSort do que pelo Quicksort. 4. Listas duplamente encadeadas são geralmente ordenadas utilizando métodos binários de ordenação. COMENTÁRIO: A resposta da questão é a de número 1. A alternativa 1 está correta, pois as listas ordenadas simplesmente encadeadas não necessitam de aplicação de nenhum método de ordenação já que seus elementos são inseridos em ordem adequada. Esta técnica é chamada InsertionSort. As assertivas 2 e 3 não estão corretas, pois não se aplica métodos de ordenação por partição, como o QuickSort, às estruturas de dados não indexadas. A assertiva 4 não é correta, pois não existe método binário de ordenação. H. Analise as seguintes afirmações e assinale a INCORRETA. 1. O método BubbleSort é um dos métodos de ordenação mais simples, contudo o seu desempenho é considerado ruim. Porém, em casos específicos, por exemplo, quando o conjunto está quase 6 completamente ordenado, este método pode apresentar bons resultados em termos de tempo de processamento. 2. O método de ordenação BubbleSort é baseado na idéia de fazer sucessivas varreduras no conjunto de valores e realizar trocas de posição entre os elementos. Um elevado número de trocas pode tornar a ordenação mais lenta. 3. O método de ordenação QuickSort é essencialmente um método recursivo. 4. Os métodos de ordenação BubblesSort e QuickSort são adequados somente quando os conjuntos a serem ordenados tiverem grande quantidade de elementos. COMENTÁRIO: A resposta correta é a alternativa 4. A alternativa 1 é verdadeira e sua veracidade pode ser verificada analisando as duas afirmações contidas nela. A primeira afirmação “O método BubbleSort é um dos métodos de ordenação mais simples, contudo o seu desempenho é considerado ruim” pode ser encontrado no primeiro parágrafo da página 81 da apostila. A segunda afirmação também é verdade segundo o primeiro parágrafo da página 84 da apostila “o algoritmo (bubblesort) vai rodar um pouco mais rápido quando forem realizadas trocas. Por exemplo, isso ocorre caso o vetor já esteja ordenado” (PREISS, 2000). A alternativa 2 é verdadeira e pode ser constatada que a idéia do bubblesort é de fazer sucessivas varreduras no segundo parágrafo da página 81 da apostila. Contrapondo-se a afirmação de Preiss, citada anteriormente, é verdade que um elevado número de trocas pode tornar a ordenação mais lenta. A alternativa 3 também é verdadeira, pois o quarto passo do algoritmo quicksort (página 84) indica “realize o quicksort recursivamente para as partições [...]”. Por fim, a alternativa 4 é falsa porque bubblesort e quicksort podem ser aplicados para conjuntos a serem ordenados com uma pequena quantidade de elementos. Para confirmar isso, nas páginas 81 e 85 da apostila existe um conjunto com 10 elementos sendo ordenado com o bubblesort e quicksort, respectivamente. I. Tratando-se de listas ordenadas duplamente encadeadas alguns cuidados devem ser tomados ao realizar a remoção de um elemento. Dentre as considerações expostas a seguir, assinale a alternativa que NÃO faz referência às considerações necessárias à remoção de um elemento de uma lista ordenada duplamente encadeada. 1. Verificar se a lista ordenada está vazia. 2. Verificar se o elemento a ser removido é menor que o primeiro elemento da lista ordenada. 3. Verificar se o elemento a ser removido é maior que o primeiro elemento. 4. Verificar se a lista ordenada está cheia. COMENTÁRIO: A alternativa correta para a questão é a assertiva 4. As opções 1, 2 e 3 estão presentes na apostila na página 73. Os cuidados necessários para efetuar a remoção de um elemento de uma lista ordenada duplamente encadeada são: verificar se a lista está vazia, ou seja, não é possível remover um elemento de onde não há elementos; verificar se o elemento a ser removido é menor que o primeiro elemento da lista. Esse é um caso especial pois passa a ser necessário fazer a readequação do local para onde o ponteiro externo que armazena o início da lista para o novo início; verificar se o elemento a ser removido é maior que o primeiro elemento é outro cuidado, e nesse caso, faz-se necessário percorrer a lista em busca do elemento a ser removido; a assertiva 4 não está correta, pois, teoricamente, não existe lista encadeada cheia e no caso de não ser uma lista encadeada, não justificaria verificar se a lista está cheia se a operação a ser executada é de remoção. 7 J. Considerando o trecho de código fonte transcrito a seguir, analise-o e assinale a alternativa CORRETA. Considere que o ponteiro externo lista aponta para o meio da lista (nó central). 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. no *temp=(no*)malloc(sizeof(no)); temp->conteudo=elemento; no *auxiliar=lista; if (temp->conteudo < auxiliar->conteudo) { while (temp->conteudo < auxiliar->conteudo) auxiliar=auxiliar->anterior; temp->proximo=auxiliar->proximo; temp->anterior=auxiliar; auxiliar->proximo->anterior=temp; auxiliar->proximo=temp; } else { while (temp->conteudo > auxiliar->conteudo) auxiliar=auxiliar->proximo; temp->proximo=auxiliar; temp->anterior=auxiliar->anterior; auxiliar->anterior->proximo=temp; auxiliar->anterior=temp; } 1. Caso o teste condicional existente na linha 4 do trecho de código seja verdadeiro, ocorrerá a remoção do menor valor presente na lista. 2. O desvio condicional composto da linha 4 faz com que a navegação na lista ocorra em direção ao ponto apropriado para inserção de um novo nó à lista. 3. O trecho de código em questão faz referência ao procedimento de remoção de um nó em uma lista ordenada duplamente encadeada. 4. A linha 19 do trecho de código indica que o nó novo passa a ser o anterior do nó próximo do auxiliar. COMENTÁRIO: A resposta correta é a alternativa 2. A alternativa 1 é falsa porque o trecho de código é da função de inserção e não remoção. A alternativa 2 é verdadeira porque o desvio condicional composto (if...else) da linha 4 indica se deve-se percorrer, partindo-se do meio, para os nós anteriores (entre as linhas 6 e 11) ou próximos (entre as linhas 15 e 20). A alternativa 3 é falsa porque, apesar de ser uma lista ordenada duplamente encadeada, o trecho de código não é de remoção, mas de inserção. A alternativa 4 é falsa porque a linha 19 indica que o próximo nó apontado pelo nó anterior ao auxiliar passa a ser temp e não o nó novo passar a ser o anterior do nó próximo do auxiliar, como indica a alternativa. Coordenação do curso de Superior em Tecnologia em Análise e Desenvolvimento de Sistemas UNITINS - EAD 8