Introdução aos Algoritmos e Estruturas de Dados 2 o Teste - A LEIC Alameda, 2007/2008 Data: 12 de Junho de 2008 2 o Semestre Duração: 2h RESOLUÇÃO I. (2.5+2.5 = 5.0 val.) I.a) Suponha que está a trabalhar com uma estrutura de dados que é uma árvore binária, em que a estrutura de cada nó foi declarada da seguinte forma: typedef struct node { int value; struct node *left; struct node *right; Node_t; Nesta estrutura de dados, todos os nós internos têm dois filhos, e as folhas têm ambos os ponteiros (left e right) com o valor NULL. Escreva uma função que aceite como argumento um ponteiro para um nó desta árvore e determine o número de folhas na árvore enraizada nesse nó que estão à profundidade máxima da árvore. Relembre que a profundidade da árvore é a distância entre a folha mais profunda e a raiz da árvore. Solução: A definir. 1/12
I.b) Escreva uma função que aceite como argumentos duas tabelas de inteiros, e respectivas dimensões. As tabelas estão ordenadas por ordem crescente. A função deverá retornar numa terceira tabela (que é o quinto argumento da função, e cuja dimensão é suficiente) uma lista ordenada dos valores presentes nas duas primeiras tabelas. A função deve retornar o valor da dimensão da tabela resultado. Por exemplo, se a função for chamada com os argumentos: ({1, 3, 7, 8, {2, 4, 9, 4, 3,...) deverá escrever na tabela resultado {1,2,3,4,7,8,9 e retornar o valor 7. O protótipo da função pretendida é: int merge(int tab1[], int tab2[], int n1, int n2, int tabres[]); Solução: A definir. 2/12
Grupo II (1.5+1.5+1.5+1.5 = 6.0 val.) II.a) Indique qual dos seguintes vectores corresponde a um amontoado (heap). a. < 10,5,2,7,4,2,1,2,1 > b. < 10,9,8,7,6,9,8,7,6 > c. < 10,7,9,8,6,5,4,8,9 > d. < 8,10,9,7,6,5,4,8,9 > e. < 50,20,13,12,11,9,8,14,15 > f. < 50,20,10,16,18,9,8,15,14 > g. < 50,20,11,9,8,12, 10,7, 6 > Solução: A resposta certa é a f. 3/12
II.b) Considere a seguinte implementação do algoritmo heapsort em C: void heapsort(item a[], int l, int r) { 01 int k, N = r-l+1; 02 Item* pq = a+l-1; 03 for (k = N/2; k >= 1; k--) 04 fixdown(pq, k, N); 05 while (N > 1) { 06 exch(pq[1], pq[n]); 07 fixdown(pq, 1, --N); 08 A primeira operação do algoritmo heapsort é transformar o vector num amontoado. Considere a execução da função acima para a totalidade do seguinte vector: < 20,11,16,9,12,14,17,19, 13,15 > Indique qual o conteúdo do vector, imediatamente antes da execução da linha 05. a. < 20,17,19,15,13,16, 14,11,12, 9 > b. < 20,19,17,13,15,9,16,14, 12,11 > c. < 20,17,16,19,15,14, 13,12,11, 9 > d. < 20,19,17,15,13,16, 14,9, 11,12 > e. < 20,17,19,16,15,14, 13,12,11, 9 > f. < 20,19,17,13,15,14, 16,9, 11,12 > g. < 20,17,19,14,15,13, 9,16, 12,11 > Solução: A resposta certa é a f. 4/12
II.c) Considere a aplicação do algoritmo bubblesort ao seguinte vector: < 20,11,16,9,12,14,17,19, 13,15 > Supondo que o algoritmo percorre o vector da esquerda para a direita em cada iteração, qual o conteúdo do vector após as duas primeiras iterações do algoritmo bubblesort? a. < 9,12,11,13,14,16,15,17, 19,20 > b. < 11,16,9,12,14,17,19,13, 15,20 > c. < 11,9,12,14,16,17,13,15, 19,20 > d. < 9,11,12,14,16,13,15,17, 19,20 > e. < 9,11,12,13,14,16,15,17, 19,20 > f. < 11,9,12,16,13,14,15,17, 19,20 > g. < 9,11,12,15,13,17,14,16, 19,20 > Solução: A resposta certa é a c. 5/12
II.d) Considere a seguinte implementação em C do procedimento partition do algoritmo quicksort: void partition(int* A, int p, int r) { int x = A[r], i, j, a; for (i = p-1, j = p; j < r; j++) { if (A[j] <= x) { i++; a = A[i]; A[i] = A[j]; A[j] = a; a = A[r]; A[r] = A[i+1]; A[i+1] = a; Qual o conteúdo do vector A após invocar a função com os argumentos abaixo? A =< 20,11,16,9,12,14,17,19, 13,15 >, p = 0, r = 9 a. < 11,9,12,14,13,15,17,19, 16,20 > b. < 11,9,13,12,14,15,17,19, 16,20 > c. < 9,11,12,14,13,15,17,16, 20,19 > d. < 9,11,12,13,14,15,17,19, 16,20 > e. < 11,9,12,14,13,15,19,17, 20,16 > f. < 9,11,12,14,13,15,19,16, 20,17 > g. < 11,9,14,12,13,15,19,17, 20,16 > Solução: A resposta certa é a a. 6/12
Grupo III (1.5+1.5+1.5 = 4.5 val.) III.a) Relativamente a árvores red-black, qual das seguintes afirmações é falsa? a. Um nó ou tem côr vermelha ou côr preta. b. Todos os caminhos de um nó até qualquer folha contêm sempre o mesmo número de nós de côr preta. c. O caminho mais longo, desde a raíz até qualquer folha, tem no pior caso comprimento igual ao dobro do comprimento do caminho mais curto, da raíz até qualquer folha. d. As folhas têm côr preta. e. Os filhos de nós de côr vermelha têm côr preta. f. A raiz tem côr preta. g. Os filhos de nós de côr preta têm côr vermelha. Solução: A resposta certa é a g. 7/12
III.b) Considere a implementação em C de uma árvore de pesquisa binária para inteiros, cujo o código é parcialmente reproduzido abaixo. #include <stdlib.h> struct BSTnode { int item; struct BSTnode* l; struct BSTnode* r; ; typedef struct BSTnode* link; static link head, z; link NEW(int item, link l, link r) { link x = malloc(sizeof(struct BSTnode)); x->item = item; x->l = l; x->r = r; return x; void BSTinit() { head = (z = NEW(0, NULL, NULL)); link insertr(link h, int item) { if (h == z) return NEW(item, z, z); if (item < h->item) h->l = insertr(h->l, item); else h->r = insertr(h->r, item); return h; void BSTinsert(int item) { head = insertr(head, item);... Assuma que, após invocar a função BSTinit(), invoca a função BSTinsert() para cada um dos elementos do seguinte vector, começando no primeiro e acabando no último: < 3,10,7,4,2,1,9,8, 5, 6 > Qual será a sequência de elementos visitados se, após a inserção dos elementos do vector acima, efectuarmos uma travessia em preorder da referida árvore? a. < 1,2,3,4,5,6,7,8, 9,10 > b. < 1,2,6,5,4,9,8,7, 10,3 > c. < 1,2,9,5,4,6,8,7, 10,3 > d. < 1,2,9,4,5,6,8,7, 10,3 > e. < 3,2,1,10,7,4,5,6,9,8 > f. < 3,2,6,10,8,4,5,1,9,7 > g. < 10,9,8,7,6,5,4,3,2,1 > Solução: A resposta certa é a e. 8/12
III.c) Considere uma tabela de dispersão com resolução por procura linear (linear probing), que permite guardar números inteiros. A tabela tem dimensão M = 10, e a respectiva função de dispersão é: hash(k) = k mod M Indique, para a inserção na tabela da sequência de números inteiros abaixo, qual será o índice da entrada da tabela em que é inserido o último elemento? < 10,18,5,25,46,101,39,17 > Nota: O operador mod representa o resto da divisão inteira (módulo). a. 1 b. 2 c. 3 d. 5 e. 7 f. 8 g. 9 Solução: A resposta certa é a b. 9/12
Grupo IV (1.5+1.5+1.5 = 4.5 val.) IV.a) Considere a seguinte implementação em C do algoritmo counting sort, em que as linhas foram reordenadas aleatoriamente: void distcount(int a[], int l, int r) { 01 b[cnt[a[i]]++] = a[i]; 02 int i, j, cnt[m+1]; 03 cnt[a[i]+1]++; 04 for (i = l; i <= r; i++) 05 for (i = l; i <= r; i++) 06 for (j = 1; j < M; j++) 07 for (j = 0; j <= M; j++) 08 int b[maxn]; 09 for (i = l; i <= r; i++) 10 a[i] = b[i]; 11 cnt[j] = 0; 12 cnt[j] += cnt[j-1]; Qual a ordenação correcta para as linhas desta função? a. 08, 02, 04, 03, 07, 11, 05, 01, 06, 12, 09, 10 b. 08, 02, 04, 03, 07, 11, 09, 01, 05, 12, 06, 10 c. 08, 02, 07, 10, 09, 03, 06, 12, 05, 01, 04, 11 d. 02, 08, 04, 03, 07, 11, 09, 01, 05, 12, 06, 10 e. 02, 08, 07, 11, 04, 03, 06, 12, 05, 01, 09, 10 f. 02, 08, 05, 01, 09, 10, 07, 11, 04, 03, 06, 12 g. 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12 Solução: A resposta certa é a e. 10/12
IV.b) Considere o seguinte vector de números inteiros sem sinal de 6 bits: < 32,1,34,9,6,2,20,18,10 > Qual o conteúdo do vector após o primeiro passo do algoritmo de ordenação radix sort MSD, em que em cada passo os elementos são ordenados considerando 2 bits (ou seja, byte = 2 bits)? Nota: considere que o algoritmo é baseado numa versão estável do algoritmo counting sort. O algoritmo deve apenas processar os 6 bits menos significativos de cada número, independentemente dos números poderem ser guardados em palavras com maior número de bits. a. < 32,1,34,9,6,2,20,18,10 > b. < 1,9,6,2,10,20,18,32,34 > c. < 1,2,6,9,10,18,20,32,34 > d. < 10,18,20,2,6,9,34, 1,32 > e. < 1,9,2,6,10,18,20,32,34 > f. < 1,2,6,9,10,32,34,20,18 > g. < 1,10,18,2,20,32, 34,6, 9 > Solução: A resposta certa é a b. 11/12
IV.c) Considere a aplicação do algoritmo radix sort LSD ao seguinte vector de cadeias de caracteres: < aba,bca,abc,aab,baa,bcb,aaa,abb,cac > Assumindo que em cada passo de execução do algoritmo é analizado um caracter, qual será o conteúdo do vector após a execução do segundo passo? a. < aba,bca,baa,aaa,aab,bcb,abb,abc,cac > b. < aaa,aab,aba,abb,abc,baa,bca,bcb,cac > c. < aba,abc,aab,aaa,abb,bca,baa,bcb,cac > d. < aab,aaa,aba,abc,abb,baa,bca,bcb,cac > e. < baa,aaa,aab,cac,aba,abb,abc,bca,bcb > f. < baa,aaa,aba,bca,aab,abb,bcb,cac,abc > g. < aaa,baa,aba,bca,aab,abb,bcb,cac,abc > Solução: A resposta certa é a e. 12/12