Capítulo 5 Abstracção de dados 5. Exercícios de revisão. Diga o que é um tipo abstracto de informação.. Diga qual é a diferença entre tipos de informação elementares e tipos de informação estruturados. 3. Explique em que consiste a abstracção de dados, usando os termos barreiras de abstracção, encapsulação da informação e anonimato da representação. 4. Explique quais são as vantagens da abstracção de dados. 5. Compare a abstracção de dados com a abstracção procedimental. 6. Justifique a seguinte afirmação a abstracção de dados aumenta o poder expressivo da nossa linguagem de programação. 7. Quais são os quatro passos a seguir na definição de um tipo abstracto de informação? Explique em que consiste cada um deles. 8. Diga o que são operações básicas de um tipo abstracto de informação e quais os grupos em que estas são divididas. 9. Explique o que são as barreiras de abstracção criadas por um tipo de informação e quais os inconvenientes de não as respeitar. 0. Apresente a metodologia dos tipos abstractos de informação e explique porque é que esta metodologia garante a abstracão de dados.. Diga o que é o anonimato da representação e qual a sua importância.. Na criação de um tipo abstracto de informação, há dois tipos de representação a considerar. Diga quais são e descreva cada um deles. 3. Diga o que é uma árvore binária e quais são as suas operações básicas, classificando-as de acordo com os vários grupos de operações. 43
44 CAPÍTULO 5. ABSTRACÇÃO DE DADOS 5. Exercícios de programação 5.. Caixas e ponteiros. () Considere a seguinte estrutura de pares usando a notação de caixas e ponteiros(correspondente à variável Estr): Para cada uma das seguintes expressões escreva o seu valor (o qual pode ser um número inteiro, uma estrutura de pares ou pode originar um erro). No caso de a expressão originar um erro explique a razão do erro. (a) (car Estr) (b) (car (car (cdr Estr))) (c) (cdr (cdr (cdr Estr))). () Represente as seguintes estruturas, usando a notação de caixas e ponteiros: (a) (. ) (b) (. ("bom dia". 3)) (c) (. (. (3. 4))) (d) ((. ). ((3. (4. 5)). (7. 8))) 5.. Tipo tempo Suponha que desejava criar o tipo tempo em Scheme. Suponha que o tempo é caracterizado por um certo número de horas (um inteiro não negativo), minutos (um inteiro entre 0 e 59) e segundos (um inteiro entre 0 e 59).. () Especifique as operações básicas para o tipo tempo.. () Escolha uma representação interna para o tipo tempo usando pares. 3. () Escreva em Scheme as operações básicas, de acordo com a representação escolhida.
5.. EXERCÍCIOS DE PROGRAMAÇÃO 45 4. () Supondo que a representação externa para os elementos do tipo tempo é h : mm : ss (em que h é um inteiro positivo que representa as horas, mm são dois dígitos que identificam os minutos e ss são dois dígitos que identificam os segundos) escreva o transformador de saída escreve-tempo para o tipo tempo. Por exemplo, > (escreve-tempo (faz-tempo 9 34)) 9:0:34 5. () Escreva o procedimento em Scheme diferenca-segundos que calcula o número de segundos entre dois instantes de tempo. Este procedimento apenas deve produzir um valor se o segundo tempo for maior do que o primeiro, gerando uma mensagem de erro se essa condição não se verificar. > (diferenca-segundos (faz-tempo 0 34) (faz-tempo 34)) 3600 6. () Escreva o procedimento em Scheme diferenca-tempo que calcula a diferença entre dois instantes de tempo retornando o valor em termos de horas, minutos e segundos. Este procedimento apenas deve produzir um valor se o segundo tempo for maior do que o primeiro, gerando uma mensagem de erro se essa condição não se verificar. > (escreve-tempo (diferenca-tempo (faz-tempo 0 34) (faz-tempo 4 39))) :0:05 7. () Escreva o procedimento em Scheme soma-tempos que calcula o tempo resultante da soma entre dois instantes de tempo. > (escreve-tempo (soma-tempos (faz-tempo 45 30) (faz-tempo 0 40))) 4:06:0 8. () Suponha agora que pretende representar os elementos do tipo tempo através de inteiros positivos com a forma hmmss, em que h é um inteiro não negativo que representa o número de horas, mm e ss são dois inteiros entre 0 e 59 cada um e que representam, respectivamente, os minutos e os segundos do tempo. Escreva em Scheme as operações básicas, de acordo com esta nova representação. 9. () Seria possível utilizar as operações definidas nos exercícios anteriores, 4 7, usando esta nova representação? Justifique. 5..3 Tipo data Suponha que desejava criar o tipo data em Scheme. Suponha que uma data é caracterizada por um dia (um inteiro entre e 3), um mês (um inteiro entre e ) e um ano. Para cada data, deve ser respeitado o limite de dias de cada mês, incluindo o caso de Fevereiro nos anos bissextos.. () Especifique as operações básicas para o tipo data.
46 CAPÍTULO 5. ABSTRACÇÃO DE DADOS. () Escolha uma representação interna para o tipo data usando pares. 3. () Escreva em Scheme as operações básicas, de acordo com a representação escolhida. 4. () Supondo que a representação externa para um elemento do tipo data é d/m/a (em que d representa o dia, m o mês e a o ano) escreva o transformador de saída para o tipo data. Por exemplo, > (escreve-data (faz-data 5 9 0)) 5/9/0 5. () Tendo em conta as operações básicas do tipo data, defina um procedimento chamado anterior? que recebe como argumentos duas datas e tem o valor verdadeiro se a primeira data for anterior à segunda e falso em caso contrário. > (anterior? (faz-data 003) (faz-data 005)) 6. () Tendo em conta as operações básicas do tipo data, defina um procedimento idade que recebe como argumentos a data de nascimento de uma pessoa e outra data posterior e devolve a idade da pessoa na segunda data. > (idade (faz-data 003) (faz-data 005)) > (idade (faz-data 003) (faz-data 3 006)) 3 5..4 Listas. () Escreva um procedimento em Scheme ultimo que recebe uma lista não vazia, e devolve o último elemento da lista. > (ultimo (4 5 6)) 6 > (ultimo ()). () Escreva um procedimento em Scheme produto-lista que recebe uma lista, e devolve o produto de todos os elementos da lista. Considere que o produto dos elementos de uma lista vazia tem o valor. > (produto-lista (4 5 6)) 0 > (produto-lista ())
5.. EXERCÍCIOS DE PROGRAMAÇÃO 47 3. () Escreva um procedimento em Scheme conta-pares que recebe uma lista, e devolve o número de elementos pares na lista. > (conta-pares (4 5 6)) > (conta-pares (3 5 7)) 0 4. () Escreva um procedimento em Scheme conta-menores que recebe uma lista lst e um número inteiro n, e devolve o número de elementos da lista lst menores que n. > (conta-menores (4 5 6) 4) 0 > (conta-menores (3 5 7) 6) 5. () Escreva um procedimento em Scheme numero-ocorrencias que recebe uma lista e um número inteiro n, e devolve o número de vezes que n ocorre na lista. > (numero-ocorrencias (4 5 6) 5) > (numero-ocorrencias (3 5 7) ) 0 6. () Escreva um procedimento em Scheme todos-pares? que recebe uma lista, e devolve verdadeiro se a lista for constituída exclusivamente por números pares e falso no caso contrário. > (todos-pares? (4 5 6)) > (todos-pares? (4 4 6)) 7. () Escreva um procedimento em Scheme ocorre-lista? que recebe uma lista e um número inteiro n, e devolve verdadeiro se o número n ocorrer na lista e falso no caso contrário. > (ocorre-lista? (3 4) 3) > (ocorre-lista? (3 4) ) 8. (3) Escreva um procedimento em Scheme maximo-lista que recebe uma lista não vazia, e devolve o maior elemento da lista. > (maximo-lista (4 5 6)) 6 > (maximo-lista (7 3 6)) 7
48 CAPÍTULO 5. ABSTRACÇÃO DE DADOS 9. () Escreva um procedimento em Scheme quadrados-lista que recebe uma lista lst, e devolve a lista que resulta de elevar todos os números da lista lst ao quadrado. > (quadrados-lista (3 4)) (9 4 6) 0. () Escreva um procedimento em Scheme substitui que recebe uma lista lst, um número v (velho) e um número n (novo), e devolve a lista que resulta de substituir em lst todas as ocorrências de v por n. > (substitui (4 3 4) 4 5) (5 3 5). () Escreva um procedimento em Scheme insere-no-fim que recebe uma lista lst e um número n, e devolve a lista que resulta de inserir o elemento n no final da lista lst. > (insere-no-fim 3 (3 4)) (3 4 3) > (insere-no-fim 3 ()) (3). () Escreva um procedimento em Scheme remove-ultimo que recebe uma lista não vazia, e devolve a lista que resulta de remover o último elemento da lista. > (remove-ultimo (3 4)) (3 ) > (remove-ultimo (4)) () 3. () Escreva um procedimento em Scheme junta que recebe duas listas, e devolve a lista que resulta de juntar a segunda lista no final da primeira. > (junta (3 4) ( 3)) (3 4 3) > (junta () (4 5 3)) (4 5 3) > (junta ( 3) ()) ( 3) 4. () Escreva um procedimento em Scheme inverte que recebe uma lista, e devolve a lista que resulta de inverter a lista original. Sugestão: Utilize o procedimento insere-no-fim definido no exercício ou os procedimentos ultimo e remove-ultimo definidos nos exercícios e. > (inverte (3 4)) (4 3)
5.. EXERCÍCIOS DE PROGRAMAÇÃO 49 5. () Escreva um procedimento em Scheme aumenta que recebe, no mínimo, um argumento inteiro e devolve a lista que se obtém somando o primeiro argumento a cada um dos restantes elementos. > (aumenta 0 5 8) ( 5 8) > (aumenta 8 0) (8) > (aumenta 3) () > (aumenta) procedure aumenta: expects at least argument, given 0 6. (3) Escreva um procedimento em Scheme alisa que recebe uma lista, cujos elementos podem ser listas, e devolve a lista com todos os elementos atómicos da lista original. Sugestão: Utilize o procedimento junta definido no exercício 3. > (alisa ((((3))) 4 5 (8 (9)))) (3 4 5 8 9) 7. (3) Escreva um procedimento em Scheme sublistas que recebe uma lista, e conta o número total de sublistas que esta contém. > (sublistas ( 3)) 0 > (sublistas (() (3))) > (sublistas ((((()))))) 4 8. () Escreva um procedimento em Scheme selecciona-pares que recebe uma lista, e devolve a lista com todos os números pares da lista original. > (selecciona-pares (4 3 4)) (4 4) > (selecciona-pares (7 3 5)) () 9. () Escreva um procedimento em Scheme selecciona-menores que recebe uma lista e um número n, e devolve a lista com todos os números da lista original menores que n. > (selecciona-menores (4 3 4) 4) (3 ) > (selecciona-menores (7 3 5) ) () 0. () Escreva um procedimento em Scheme selecciona-primos que recebe uma lista, e devolve a lista com todos os números primos da lista original.
50 CAPÍTULO 5. ABSTRACÇÃO DE DADOS > (selecciona-primos (4 3 4)) (3 ) > (selecciona-primos (4 6 8 9)) (). () Escreva um procedimento em Scheme remove-elemento que recebe uma lista e um número n, e devolve a lista que resulta de remover todas as ocorrências do elemento n da lista original. > (remove-elemento (4 3 4) 4) (3 ) > (remove-elemento (7 3 5) ) (7 3 5). () Escreva um procedimento em Scheme altera-posicao que recebe uma lista e dois números p e n, e devolve a lista que resulta de alterar o elemento na posição p da lista para n. Caso a lista tenha menos de p posições deverá devolver a lista original. > (altera-posicao (4 3 4) 4 0) (4 3 0 4) > (altera-posicao (4 3 4) 00 8) (4 3 4) 3. () Escreva um procedimento em Scheme posicoes-lista que recebe uma lista e um número n, e devolve a lista de todas as posições em que o número n ocorre na lista. > (posicoes-lista (4 3 4) 4) ( 6) > (posicoes-lista (4 3 4) 6) () 4. () Escreva um procedimento em Scheme posicoes-dos-pares que recebe uma lista, e devolve a lista de todas as posições da lista em que ocorrem números pares. > (posicoes-dos-pares (4 3 4)) ( 3 4 6) > (posicoes-dos-pares (5 3 5 3 )) () 5. () Escreva um procedimento em Scheme ordenada? que recebe uma lista, e devolve verdadeiro se a lista estiver ordenada de forma crescente e falso no caso contrário. > (ordenada? (3 3)) > (ordenada? (3 5 7 8))
5.. EXERCÍCIOS DE PROGRAMAÇÃO 5 6. (3) Escreva um procedimento em Scheme intercala que recebe duas listas, e devolve a lista que resulta de intercalar os elementos das duas listas. Se as listas não forem do mesmo tamanho, o que restar da lista maior deverá ser adicionado no fim. > (intercala (3 4) ( 3)) (3 4 3) > (intercala ( 3) (4 5 8 6)) ( 4 3 5 8 6) 7. () Escreva um procedimento em Scheme insere-ordenado que recebe uma lista ordenada e um número n, e devolve a lista que resulta de inserir o número n na posição certa na lista de modo a que o resultado continue uma lista ordenada. > (insere-ordenado (3 5 7 8) 7) (3 5 7 7 8) > (insere-ordenado (3 5 7 8) ) ( 3 5 7 8) > (insere-ordenado (3 5 7 8) 5) (3 5 7 8 5) 8. (3) Escreva um procedimento em Scheme parte que recebe uma lista lst e um número n, e devolve uma lista contendo na primeira posição a lista com os elementos de lst menores que n, e na segunda posição a lista com os elementos de lst maiores ou iguais a n. A ordem pela qual os elementos aparecem nas listas devolvidas é irrelevante. > (parte (6 9 7) 3) (( ) (6 9 7)) > (parte (6 3 9 7) 3) (( ) (6 3 9 7)) > (parte (9 5) 4) (() (9 5)) 9. () Escreva um procedimento em Scheme capicua? que recebe uma lista, e devolve verdadeiro se a lista for uma capicua e falso no caso contrário. Sugestão: Utilize os procedimentos ultimo e remove-ultimo definidos nos exercícios e. > (capicua? (3 3)) > (capicua? (3 3)) > (capicua? (3 3 3)) 30. (3) Escreva um procedimento em Scheme capicua que recebe uma lista, e devolve a lista que se obtém construindo uma capicua com a lista original. Sugestão: Utilize o procedimento insere-no-fim do exercício.
5 CAPÍTULO 5. ABSTRACÇÃO DE DADOS > (capicua (3 4 7 )) (3 4 7 7 4 3) > (capicua ( )) ( ) 3. (3) Escreva um procedimento em Scheme remove-duplicados que recebe uma lista lst, e fica apenas com uma cópia de cada elemento de lst. A ordem pela qual os elementos aparecem na lista devolvida é irrelevante. Sugestão: Utilize o procedimento remove-elemento do exercício. > (remove-duplicados (4 3 4)) (4 3 ) > (remove-duplicados (4 3 4 )) (4 3 ) > (remove-duplicados (7 5 3 4 6 )) (7 5 3 4 6 ) 3. (3) Escreva um procedimento em Scheme elementos-repetidos que recebe uma lista, e devolve a lista com uma cópia de cada elemento que aparece repetido na lista. A ordem pela qual os elementos aparecem na lista devolvida é irrelevante. e remove-elemento dos exercí- Sugestão: Utilize os procedimentos ocorre-lista? cios 7 e. > (elementos-repetidos (3 4 4 4 3 6 7)) (3 4) > (elementos-repetidos (3 4 6 7)) () 33. (3) Escreva um procedimento em Scheme conta-elementos que recebe uma lista de inteiros, e devolve uma lista de pares em que cada par contém como primeiro elemento um elemento da lista e como segundo elemento o número de vezes que este aparece na lista. A ordem pela qual os pares aparecem na lista devolvida é irrelevante. Respeite as barreiras de abstracção, mas lembre-se que está a lidar com dois tipos estruturados, a lista e o par. e remove-elemento dos exercí- Sugestão: Utilize os procedimentos ocorre-lista? cios 7 e. > (conta-elementos (3 4 5 5 3 3 9 3 3 3 )) ((3. 6) (4. ) (5. ) (9. ) (. )) 34. () Escreva um procedimento em Scheme lista-inteiros que recebe um inteiro positivo n, e devolva uma lista com todos os inteiros entre 0 e n (a ordem pela qual os números aparecem na lista não é relevante). > (lista-inteiros 7) (0 3 4 5 6 7)
5.. EXERCÍCIOS DE PROGRAMAÇÃO 53 (a) O seu procedimento é um procedimento recursivo? Porquê? (b) O seu procedimento gera um processo iterativo ou recursivo? Porquê? (c) Se o seu procedimento gera um processo iterativo, escreva um que gere um processo recursivo. Se gera um processo recursivo, escreva um que gere um processo iterativo. 35. (4) O Crivo de Eratóstenes é um algoritmo para calcular números primos que, segundo a tradição, foi criado pelo matemático grego Eratóstenes (c. 85-94 a.c.), o terceiro bibliotecário-chefe da Biblioteca de Alexandria. O algoritmo calcula os números primos inferiores a n. Para isso, começa-se por criar uma lista com todos os inteiros positivos de an e seleccionar o número. Enquanto o número seleccionado for menor que n:(a) removem-se da lista todos os múltiplos desse número; (b) passa-se ao número seguinte na lista. No final do algoritmo, quando o número seleccionado for superior a n,alista apenas contém números primos. Escreva um procedimento em Scheme para calcular a lista de números primos inferiores a n de acordo com o Crivo de Eratóstenes. Sugestão: Defina um procedimento remove-multiplos que dado uma lista lst e um inteiro n, remove da lista todos os múltiplos de n. > (lista-primos 0) ( 3 5 7 3 7 9) > (lista-primos 00) ( 3 5 7 3 7 9 3 9 3 37 4 43 47 53 59 6 67 7 73 79 83 89 97) 5..5 Árvores Binárias Definições e Notação Nesta secção deve considerar os seguintes procedimentos sobre árvores binárias: (nova-arv) cria uma árvore vazia. (cria-arv r arve arvd) cria uma árvore binária com raiz r, árvore esquerda arve e árvore direita arvd. (raiz arv) dada uma árvore binária arv devolve a sua raiz. (arv-esq arv) dada uma árvore binária arv devolve a sua árvore esquerda. (arv-dir arv) dada uma árvore binária arv devolve a sua árvore direita. (arvore-vazia? arv) devolve verdadeiro se a árvore binária arv é vazia e falso no caso contrário. (arvore? x) devolve verdadeiro se o objecto x for uma árvore binária e falso no caso contrário. (arvores=? arv arv) devolve verdadeiro se as árvores binárias arv e arv forem iguais e falso no caso contrário. Um nó de uma árvore a é a raiz de uma das sub-árvores de a. As raízes das sub-árvores esquerda e direita de um nó r dizem-se os filhos de r. Neste caso r diz-se o pai dos dois nós. Dois nós dizem-se irmãos se tiverem o mesmo pai. Uma folha de uma árvore é um nó sem filhos.
54 CAPÍTULO 5. ABSTRACÇÃO DE DADOS A profundidade de um nó é o comprimento do caminho desde a raiz até ele. A profundidade de uma árvore é o comprimento do caminho desde a raiz até ao nó mais profundo. O nó d diz-se descendente de a se existir um caminho na árvore de a para d e a profundidade de a é menor que a profundidade de d. Umnóa diz-se ascendente de d se d for descendente de a. O tamanho de um nó é o número de seus descendentes, incluindo o próprio. O tamanho de uma árvore é o tamanho da sua raiz. Suponha definidas as seguintes árvores binárias (define a (cria-arv 3 (cria-arv (cria-arv 5 (nova-arv) (nova-arv)) (cria-arv 7 (nova-arv) (nova-arv))) (cria-arv 5 (cria-arv (nova-arv) (nova-arv)) (cria-arv 6 (nova-arv) (nova-arv))))) (define a (cria-arv 0 (cria-arv (nova-arv) (nova-arv)) (cria-arv (cria-arv 8 (nova-arv) (nova-arv)) (cria-arv (nova-arv) (nova-arv))))) (define a3 (cria-arv 5 (nova-arv) (cria-arv 0 (cria-arv 8 (nova-arv) (nova-arv)) (cria-arv 0 (nova-arv) (nova-arv))))) cujas representações gráficas são dadas por 3 0 5 5 0 5 7 6 8 8 0 Exercícios. () Escreva um procedimento em Scheme folha? que recebe uma árvore binária, e devolve verdadeiro se a árvore for uma folha e falso no caso contrário. > (folha? (arv-esq a)) > (folha? (arv-esq a)). () Escreva um procedimento em Scheme tamanho que recebe uma árvore binária, e devolve o número de nós da árvore.
5.. EXERCÍCIOS DE PROGRAMAÇÃO 55 > (tamanho a) 7 3. () Escreva um procedimento em Scheme soma-arvore que recebe uma árvore binária, e devolve a soma de todos os nós da árvore. > (soma-arvore a) 9 4. () Escreva um procedimento em Scheme procura? que recebe uma árvore binária e um número, e devolve verdadeiro se o número ocorre num dos nós da árvore e falso no caso contrário. > (procura? a 8) > (procura? a 8) 5. () Escreva um procedimento em Scheme todos-pares? que recebe uma árvore binária, e devolve verdadeiro se a árvore for constituída exclusivamente por números pares e falso no caso contrário. > (todos-pares? a3) > (todos-pares? (arv-dir a3)) 6. () Escreva um procedimento em Scheme conta-pares-arvore que recebe uma árvore binária, e conta quantos números pares ocorrem na árvore. > (conta-pares-arvore a) 7. () Escreva um procedimento em Scheme numero-folhas que recebe uma árvore binária, e devolve o número de folhas da árvore. > (numero-folhas a) 4 > (numero-folhas a) 3 > (numero-folhas a3) 8. () Escreva um procedimento em Scheme profundidade que recebe uma árvore binária, e devolve a profundidade da árvore. > (profundidade a) 3
56 CAPÍTULO 5. ABSTRACÇÃO DE DADOS 9. () Escreva um procedimento em Scheme pai? que recebe uma árvore binária e dois números p e f, e devolve verdadeiro se p for pai de f na árvore e falso no caso contrário. > (pai? a 3 7) > (pai? a 3 9) > (pai? a 5 ) 0. () Escreva um procedimento em Scheme filho? que recebe uma árvore binária e dois números f e p, e devolve verdadeiro se f for filho de p na árvore e falso no caso contrário. > (filho? a 6 3) > (filho? a 9 3) > (filho? a 5 ) > (filho? a 5 3). () Escreva um procedimento em Scheme irmaos? que recebe uma árvore binária e dois números n e m, e devolve verdadeiro se os números forem irmãos na árvore e falso no caso contrário. > (irmaos? a 7) > (irmaos? a 5). () Escreva um procedimento em Scheme ascendente? que recebe uma árvore binária e dois números a e d, e devolve verdadeiro se a for ascendente de d na árvore e falso no caso contrário. Sugestão: Utilize o procedimento procura? definido no exercício 4. > (ascendente? a 3 6) > (ascendente? a 3 9) > (ascendente? a 5) > (ascendente? a 3 5) 3. () Escreva um procedimento em Scheme descendente? que recebe uma árvore binária e dois números d e a, e devolve verdadeiro se d for descendente de a na árvore e falso no caso contrário.
5.. EXERCÍCIOS DE PROGRAMAÇÃO 57 > (descendente? a 6 5) > (descendente? a 7 3) > (descendente? a 5) 4. () Uma árvore binária diz-se própria se todos os seus nós têm dois filhos ou são folhas. Escreva um procedimento em Scheme arv-propria? que recebe uma árvore binária, e devolve verdadeiro se a árvore for própria e falso no caso contrário. > (arv-propria? a) > (arv-propria? a) > (arv-propria? a3) 5. () Uma árvore binária diz-se perfeita se é própria e todas as suas folhas estão ao mesmo nível. Escreva um procedimento em Scheme arv-perfeita? que recebe uma árvore binária, e devolve verdadeiro se a árvore for perfeita e falso no caso contrário. Sugestão: Utilize o procedimento profundidade definido no exercício 8. > (arv-perfeita? a) > (arv-perfeita? a) > (arv-perfeita? a3) 6. (3) Uma árvore binária diz-se balanceada se for própria e todas as suas folhas diferem no máximo de um nível. Escreva um procedimento em Scheme arv-balanceada? que recebe uma árvore binária, e devolve verdadeiro se a árvore for balanceada e falso no caso contrário. Sugestão: Utilize o procedimento profundidade definido no exercício 8. > (arv-balanceada? a) > (arv-balanceada? a) > (arv-balanceada? a3) 7. (3) Escreva um procedimento em Scheme maximo que recebe uma árvore binária não vazia, e devolve o maior elemento da árvore. > (maximo a) 7
58 CAPÍTULO 5. ABSTRACÇÃO DE DADOS 8. (3) Escreva um procedimento em Scheme minimo que recebe uma árvore binária não vazia, e devolve o menor elemento da árvore. > (minimo a) 9. (4) Uma árvore binária diz-se de pesquisa se a sua raíz é maior que todos os elementos da sua sub-árvore esquerda, menor ou igual que todos os elementos da sua sub-árvore direita, e o mesmo se passa para todas as suas sub-árvores. Escreva um procedimento em Scheme arv-pesquisa? que recebe uma árvore binária, e devolve verdadeiro se a árvore for uma árvore binária de pesquisa e falso no caso contrário. > (arv-pesquisa? a) > (arv-pesquisa? a3) 0. () Escreva um procedimento em Scheme procura-pesquisa? que recebe uma árvore binária de pesquisa e um número n, e devolve verdadeiro se o número n ocorre num dos nós da árvore e falso no caso contrário. Nota: O seu procedimento deve tirar partido do facto de receber uma árvore binária de pesquisa e não uma árvore binária qualquer. > (procura-pesquisa? a3 8) > (procura-pesquisa? a3 9). (3) Escreva um procedimento em Scheme mais-profundo que recebe uma árvore binária não vazia, e devolve o nó mais profundo da árvore. Caso existam vários à mesma profundidade deverá devolver o mais à esquerda na árvore. Sugestão: Utilize o procedimento profundidade definido no exercício 8. > (mais-profundo a) 5 > (mais-profundo a) 8. (4) Escreva um procedimento em Scheme profundidade-minima que recebe uma árvore binária não vazia e um número n, e devolve a profundidade mínima a que n ocorre na árvore. Caso o número não ocorra na árvore deverá devolver falso. Sugestão: Utilize o procedimento mais-profundo definido no exercício. > (profundidade-minima a 5) > (profundidade-minima a ) 3 > (profundidade-minima a 9)
5.. EXERCÍCIOS DE PROGRAMAÇÃO 59 3. () Escreva um procedimento em Scheme lista-folhas que recebe uma árvore binária, e devolve a lista com todas as suas folhas começando da mais à esquerda para a mais à direita. Sugestão: Utilize o procedimento junta definido no exercício 3. > (lista-folhas a) ( 8 ) > (lista-folhas a3) (8 0) 4. () Escreva um procedimento em Scheme espelha que recebe uma árvore binária e devolve uma nova árvore binária idêntica à recebida, mas em que em cada nível da árvore se trocou a árvore esquerda com a direita, mantendo-se a raiz. > (espelha a) deve devolver a árvore cuja representação gráfica é 3 5 6 7 5 5. () Escreva um procedimento em Scheme substitui que recebe uma árvore binária, um número v (velho) e um número n (novo), e devolve a árvore que resulta de substituir todas as ocorrências de v por n. > (substitui a 5 8) deve devolver a árvore cuja representação gráfica é 3 8 8 7 6 6. () Escreva um procedimento em Scheme poda que recebe uma árvore binária, e devolve a árvore que resulta de remover todas as folhas da árvore. > (poda a) deve devolver a árvore cuja representação gráfica é
60 CAPÍTULO 5. ABSTRACÇÃO DE DADOS 0 7. (4) Escreva um procedimento em Scheme promove-irmao que recebe uma árvore binária, e que em cada uma das suas sub-árvores coloca o irmão maior como raiz da árvore direita. > (promove-irmao a) deve devolver a árvore cuja representação gráfica é 0 8 8. (4) Escreva um procedimento em Scheme promove-descendente que recebe uma árvore binária, e que em cada uma das suas sub-árvores coloca o seu maior elemento na raiz. Nos casos em que há troca da raiz r por m, então r deverá ocupar o lugar onde m estava. Sugestão: Defina um procedimento substitui que recebe uma árvore arv e dois números v e n e substitui uma única ocorrência de v por n na árvore arv. > (promove-descendente a) deve devolver a árvore cuja representação gráfica é 7 5 6 3 5 9. () Escreva um procedimento em Scheme cria-arvore-pesquisa que recebe zero ou mais argumentos, e devolve uma árvore binária de pesquisa criada a partir desses argumentos. O primeiro argumento, caso exista, deverá ser a raíz da árvore. > (cria-arvore-pesquisa 5 3) deve devolver a árvore cuja representação gráfica é 5 3