exemplos - DI PUC-Rio

Propaganda
ALGUMAS ESTRUTURAS MATEMÁTICAS
BÁSICAS PARA A CIÊNCIA DA COMPUTAÇÃO
Bruno Maffeo
Departamento de Informática
PUC-Rio
CONJUNTOS
DEFINIÇÕES BÁSICAS
O conceito de conjunto associa-se ao modelo de dados mais fundamental da Ciência da Computação. Mais
freqüentemente, devido a seu elevado nível de abstração, associa-se ao modelo conceitual de uma realidade
em estudo.
Qualquer conceito associado a modelagem de dados, de árvores a números reais, pode ser expresso
matematicamente como um tipo especial de conjunto. Assim, por referir-se tanto à modelagem conceitual
quanto ao design de sistemas de software, não é surpreendente que conjunto seja um conceito fundamental em
Ciência da Computação.
Como no caso de “ponto” e “reta” em Geometria, em Matemática, o termo “conjunto” não é definido de
maneira explícita. Assim sendo, um conjunto específico será definido seja através da enumeração de seus
membros, seja através das propriedades que seus membros possuem em comum.
A noção de pertinência, especificamente, só faz sentido no caso de conjuntos. Quando C é um conjunto e x
representa uma coisa qualquer, é possível a pergunta: “O valor de x é membro do conjunto C?”. O conjunto
C será constituído por todos os valores de x para os quais a resposta a essa pergunta for afirmativa.
Os itens a seguir resumem notações importantes para referir-se a conjuntos.
♦ A fórmula x ∈ C indica, quando seu valor é VERDADEIRO, que o valor representado por x é um
membro do conjunto C.
♦ Se x 1, x 2, ... , x n são todos membros do conjunto C, pode-se escrever C = {x 1, x 2, ... , x n}. Aqui, cada
um dos valores de x é distinto, não sendo permitida mais de uma ocorrência de um valor em um conjunto.
Além disso, é irrelevante a ordem de ocorrência dos valores entre as chaves.
♦ O conjunto vazio, denotado por ∅, é o conjunto que não possui membros. Isto é, x ∈ ∅ é falso para
todo valor de x.
⇒
exemplos
♦ Seja C = {1, 3, 6}, isto é, o conjunto C possui como membros os números inteiros 1, 3 e 6 e
nada mais. Pode-se escrever 1 ∈ C, 3 ∈ C e 6 ∈ C. Entretanto, a fórmula 2 ∈ C tem valor
FALSO, da mesma forma que teria para qualquer número distinto de 1, de 3 e de 6.
♦ Conjuntos também podem ser membros de conjuntos. Seja D = {{1, 2}, 3, ∅}. Neste caso, D
possui três membros: o conjunto {1, 2}, o número inteiro 3 e o conjunto vazio ∅. São
verdadeiras as fórmulas: {1, 2} ∈ D, 3 ∈ D e ∅ ∈ D. Entretanto, a fórmula 1 ∈ D tem valor
FALSO, pois, mesmo sendo membro de um membro de D, 1 não é membro do próprio D.
Conjuntos e Seqüências
B. Maffeo
página 2 de 32
ÁTOMOS
Na teoria formal de conjuntos, nada existe além de conjuntos.
Entretanto, na teoria informal de conjuntos aqui apresentada, bem como na definição de estruturas de dados
que implementam conjuntos e de algoritmos que implementam operações sobre conjuntos, é conveniente
assumir a existência de átomos, elementos que não são conjuntos e que podem ser membros de conjuntos.
É importante lembrar que embora não possua membros, da mesma forma que um átomo, o conjunto vazio,
∅, é um conjunto e não um átomo.
Será adotada a convenção de que números inteiros e letras minúsculas denotam átomos.
Ao abordar estruturas de dados, é conveniente, com freqüência, utilizar tipos de dados complexos,
estruturados, como tipos de átomos. Assim, átomos podem ter a estrutura de registro ou de arranjo.
DEFINIÇÃO DE CONJUNTO POR MEIO DE PROPRIEDADE
A enumeração de seus membros não é a única forma de definir conjuntos. Com freqüência, é mais
conveniente começar com algum conjunto C e alguma propriedade de membros representada por um
predicado P e definir o conjunto dos membros de C que possuem a propriedade representada por P.
A notação para essa operação, denominada abstração, é {x | x ∈ C ∧ P (x)}, que designa a expressão “x
é uma variável tal que os valores do seu domínio são membros do conjunto C e possuem a propriedade
representada por P”. O símbolo ∧ designa o operador lógico AND.
A expressão {x | x ∈ C ∧ P (x)} é dita um construtor de conjunto.
A variável x, nesse construtor, é local à expressão, conseqüentemente, para descrever o mesmo conjunto,
poderia ser utilizada a expressão {y | y ∈ C ∧ P (y)} .
⇒
exemplos
♦ Seja C = {1, 3, 6} e É_ímpar o predicado que representa a propriedade “é ímpar”.
Assim, {x | x ∈ C ∧ É_ímpar (x)} é outra maneira de definir o conjunto {1, 3}. Isto é, aceita-se
os elementos 1 e 3 por serem ímpares e rejeita-se (abstrai-se) 6 por ser par.
♦ Seja D = {{1, 2}, 3, ∅}. Então, {A | A ∈ D ∧ É_conjunto (A)} denota o conjunto {{1, 2}, ∅}.
♦ Seja o conjunto de números inteiros não negativos (ou “números naturais”), freqüentemente
denotado por N. Seja É_primo o predicado que representa a propriedade que caracteriza um
número primo  isto é, um número inteiro maior do que 1 que não possui divisor além de 1 e de si
mesmo  . Então, o conjunto de números primos é denotado por {x | x ∈ N ∧ É_primo (x)}.
Essa expressão denota o conjunto infinito {1, 3, 5, 7, 11, ...}.
Conjuntos e Seqüências
B. Maffeo
página 3 de 32
CONJUNTOS INFINITOS
É confortável pensar que conjuntos possuem cardinalidade finita, isto é, que existe algum número inteiro n
particular de maneira que o conjunto em questão possui exatamente n membros. Por exemplo, o conjunto
{1, 3, 6} possui três membros.
Alguns conjuntos, entretanto, são infinitos, o que significa que não há um número inteiro que estabeleça limite
para o número de membros do conjunto. Comumente, são conhecidos:
N,
Z,
R,
C,
o conjunto dos números inteiros não negativos
o conjunto dos números inteiros negativos e não negativos
o conjunto dos números reais
o conjunto dos números complexos.
A partir desses, é possível construir, por abstração, outros conjuntos infinitos.
⇒
exemplos
O construtor {x | x ∈ Z ∧ x < 3}
acrescido de 0, 1 e 2.
designa o conjunto de todos os números inteiros negativos
O construtor {x | x ∈ Z ∧ x 1/2 ∈ Z} representa o conjunto de todos os números inteiros que são
quadrados perfeitos, ou seja {0, 1, 4, 9, 16, ...}.
OPERAÇÕES BÁSICAS SOBRE CONJUNTOS
União, Interseção e Diferença
♦ A união de dois conjuntos C e D, denotada por C ∪ D, é o conjunto que contém membros encontrados
em C, em D ou em ambos. Formalmente: C ∪ D = {x | x ∈ C ∨ x ∈ D} , onde símbolo ∨ designa o
operador lógico OR.
♦ A interseção de dois conjuntos C e D, denotada por C ∩ D, é o conjunto que contém os membros
encontrados em C e em D. Formalmente: C ∩ D = {x | x ∈ C ∧ x ∈ D} .
♦ A diferença entre dois conjuntos C e D, denotada por C − D, é o conjunto que contém os membros
encontrados em C, mas não em D. Formalmente: C − D = {x | x ∈ C ∧ ¬ x ∈ D} , onde símbolo ¬
designa o operador lógico NOT.
⇒
exemplos
Seja C = {1, 2, 3} e D = {3, 4, 5}.
Então C ∪ D = {1, 2, 3, 4, 5}, C ∩ D = {3} e C − D = {1, 2}.
Conjuntos e Seqüências
B. Maffeo
página 4 de 32
Diagramas de Venn
Freqüentemente, é útil representar as operações envolvendo conjuntos através de figuras denominadas
Diagramas de Venn.
Um Diagrama de Venn reproduzindo dois conjuntos, C e D, cada um deles representado por uma elipse, é
exibido pela figura a seguir. As duas elipses dividem o plano em quatro regiões, numeradas de 1 a 4.
1. a região 1 representa os elementos
que não estão, seja em C, seja em D.
2. a região 2 representa C − D,
membros em C que não estão em D.
região 1
C
D
região 2
região 3
região 4
3. a região 3 representa C ∩ D,
membros que estão em C e em D.
4. a região 4 representa D − C,
membros em D que não estão em C.
5. as regiões 2, 3 e 4, combinadas
representam C ∪ D, membros que
estão em C, em D ou em ambos.
Conjuntos e Seqüências
B. Maffeo
página 5 de 32
SUBCONJUNTOS
Há uma família de operadores de comparação entre subconjuntos análoga à família existente para números.
Sejam C e D conjuntos.
♦ Diz-se que C ⊆ D quando todo membro de C é, também, membro de D. Em linguagem corrente, diz-se
que "C é um subconjunto de D" ou "D contém C".
Formalmente: C ⊆ D ↔ ∀x ( x ∈ C → x ∈ D ) , onde símbolo → designa o operador lógico de
implicação e o símbolo ∀ designa o quantificador universal da lógica.
♦ Diz-se que C ⊂ D quando C ⊆ D e existe pelo menos um membro de D que não é membro de C. A
relação C ⊂ D pode ser expressa, igualmente, através de: "C é um subconjunto próprio de D" ou "D é
um superconjunto próprio de C" ou "C está propriamente contido em D" ou, ainda, "D contém
propriamente C".
Formalmente: C ⊂ D ↔ ∀x ( x ∈ C → ( x ∈ D ∧ ∃y (y ∈ D ∧ ¬ y ∈ C ) ) , onde o símbolo ∃
designa o quantificador existencial da lógica.
De maneira análoga à relação "menor do que", é possível inverter o sentido dos operadores: C ⊃ D é
sinônimo de D ⊂ C e C ⊇ D é sinônimo de D ⊆ C.
⇒
exemplo
♦ As seguintes comparações são verdadeiras:
• {1, 2} ⊆ {1, 2, 3}
• {1, 2} ⊂ {1, 2, 3}
• {1, 2} ⊆ {1, 2}
♦ A próxima, entretanto, é falsa:
• {1, 2} ⊂ {1, 2}
A seguir, algumas leis algébricas que envolvem operadores de comparação.
♦ ∅ ⊆ C, para qualquer conjunto C.
♦ Se C ⊆ D, então:
• (C ∪ D) ≡ D
• (C ∩ D) ≡ C
• (C − D) ≡ ∅.
Conjuntos e Seqüências
B. Maffeo
página 6 de 32
CONJUNTO POTÊNCIA DE UM CONJUNTO
Seja C um conjunto qualquer. O conjunto potência de C é o conjunto dos subconjuntos de C, denotado por
P (C). Formalmente: P (C) = { X | X ⊆ C } .
⇒
exemplos
♦ Seja C = {1, 2, 3}. Então,
P (C) = {∅, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}}
♦ P (∅) = {∅}
Note-se que {∅}, conjunto unitário que contém o conjunto vazio, não é equivalente a ∅, conjunto que
não possui membros.
Cardinalidade de um Conjunto Potência
Se C possui n membros, então P (C) possui 2n membros, tal como é demonstrado a seguir para
C = {a1, a2, ... , an} , empregando indução sobre n.
base
Se n = 0, então C = ∅ e P (∅) é um conjunto unitário, logo, a cardinalidade de P (C) é dada por 2n.
passo indutivo
Considera-se verdadeira a hipótese indutiva: com C = {a1, a2, ... , an}, a cardinalidade de P (C) é dada por
2n.
Seja an+1 um novo membro e seja D = C ∪ {an+1} um conjunto com n + 1 membros. Um subconjunto de D
possui ou não o membro an+1. Assim, considera-se as duas possibilidades:
♦ Os subconjuntos de D que não possuem an+1 são, também, subconjuntos de C e, por definição, são
membros de P (C). Pela hipótese indutiva, o número desses subconjuntos é dado exatamente por 2n.
♦ Se F for um subconjunto de D que inclua an+1, seja G = F − {an+1}; isto é, G é obtido de F removendo-se
o membro an+1. Pela hipótese indutiva, existem 2n subconjuntos do tipo de G, cada um deles
correspondendo-se com um único conjunto do tipo F, posto que F = G ∪ {an+1}.
Conclui-se que existem exatamente 2 × 2n, ou 2n+1 subconjuntos de D, metade constituída de subconjuntos de
C e metade formada por um subconjunto de C acrescido do membro an+1.
Dessa forma, provou-se o passo indutivo: dado que qualquer conjunto C de n membros possui 2n
subconjuntos, mostrou-se que qualquer conjunto contendo n + 1 membros possui 2n+1 subconjuntos.
Conjuntos e Seqüências
B. Maffeo
página 7 de 32
DICIONÁRIO
Uma atividade comum, refletida em um grande número de programas de computador, consiste na manutenção
de um conjunto de valores sobre o qual deseja-se:
♦ inserir elementos
♦ retirar elementos
♦ verificar se um dado elemento faz parte desse conjunto.
Um exemplo é o de um dicionário de palavras em Inglês onde, de tempos em tempos, é inserida uma nova
palavra, tal como fax, é retirada uma palavra que caiu em desuso, como aegilops, ou é verificado se uma
determinada cadeia de letras é ou não uma palavra (como parte de um programa de verificação ortográfica,
por exemplo).
Em virtude desse exemplo familiar, denomina-se dicionário um conjunto sobre o qual são executadas as
operações inserir, suprimir e buscar, independentemente do tipo dos elementos do conjunto.
Como outro exemplo de dicionário, é possível considerar a “lista de presença” de uma disciplina:
ocasionalmente, um estudante será acrescentado à turma (uma inserção), será retirado dela (uma supressão)
ou terá sua alocação verificada (uma busca).
Visando-se à realização eficiente dessas operações básicas, um dos temas primordiais em Ciência da
Computação é uma boa escolha de design  ou seja, do modelo de dados  no caso de ser necessário
implementar um dicionário.
Conjuntos e Seqüências
B. Maffeo
página 8 de 32
SEQÜÊNCIAS
Denomina-se seqüência a estrutura matemática linear na qual os itens que a compõem mantêm um
posicionamento relativo bem definido.
Embora a notação para seqüências, (x 1, x 2, ... , x n), e a notação para conjuntos, {x 1, x 2, ... , x n}, sejam
muito semelhantes, há diferenças significativas entre os dois conceitos.
Em primeiro lugar, a ordem dos membros de um conjunto é irrelevante O conjunto {1, 2} pode ser
igualmente denotado por {2, 1}. Opostamente, a seqüência (1, 2) é diferente da seqüência (2, 1).
Em segundo lugar, qualquer elemento pode ocorrer mais de uma vez, mantendo sua individualidade, em uma
seqüência; essa individualidade é estabelecida pela posição relativa ocupada pela ocorrência específica do
elemento. A seqüência (1, 2, 2), por exemplo, possui três elementos: O primeiro é 1, o segundo é 2 e o
terceiro é, também, 2. Já a notação {1, 2, 2} não faz sentido pois não pode haver mais de uma ocorrência de
membro em um conjunto. Se fizesse sentido, essa notação denotaria o mesmo conjunto denotado por {1, 2}
ou {2, 1}.
Algumas vezes, há referência ao conceito de multiconjunto, ou bolsa, que é um conjunto onde qualquer
membro pode ocorrer mais de uma vez, isto é, cada membro possui uma multiplicidade associada. Seria
possível, por exemplo, falar de um multiconjunto que contivesse 1 uma vez e 2 duas vezes. Multiconjuntos,
entretanto, não são o mesmo que seqüências pois não admitem qualquer relação posicional entre seus
membros.
Assim como se admite a noção de conjunto vazio, denotado pelo símbolo ∅, admite-se a ocorrência de
seqüência vazia, denotada pelo símbolo seq-vazia, correspondendo a uma seqüência que não possui itens.
OPERAÇÕES BÁSICAS SOBRE SEQÜÊNCIAS
Cabeça, Cauda e Insere
♦ A função cabeça (seq) retorna o item, denominado cabeça, situado na primeira posição da seqüência
seq.
♦ A função cauda (seq) retorna a seqüência, denominada cauda, constituída pela seqüência seq da qual é
retirado o cabeça
♦ A função insere (item, seq) retorna a seqüência constituída pelo valor de seq no qual estará inserido o
valor de item na primeira posição
⇒
exemplos
Seja seq = (1, 2, 3) e item = 5.
Então cabeça (seq) = 1, cauda (seq) = {2, 3} e insere (item, seq) = {5, 1, 2, 3}.
Conjuntos e Seqüências
B. Maffeo
página 9 de 32
BIBLIOGRAFIA UTILIZADA
Foundations of Computer Science
Alfred V. Aho e Jeffrey D. Ullman
( Computer Science Press, 1992 )
seções: 7.2, 7.3, 7.4, 7.5, 7.6
Conjuntos e Seqüências
B. Maffeo
página 10 de 32
RELAÇÕES
DEFINIÇÕES BÁSICAS
Geralmente, considera-se que são atômicos (sem estrutura) os elementos de um conjunto. Entretanto, na
prática, é útil considerar tais elementos como possuindo alguma estrutura.
Por exemplo, numa aplicação clássica do tipo dicionário, considera-se que os membros do conjunto
relevante, as palavras dicionarizadas, são cadeias de caracteres. Referindo-se a outras realidades, será
conveniente o uso de tuplas para representar os membros do conjunto. Este será o caso, por exemplo, em
uma aplicação do tipo dicionário relativa a alunos de uma universidade, a respeito dos quais deseja-se
registrar informações de distintas categorias (por exemplo: nome, endereço, telefone, …).
Tupla
Uma seqüência de elementos será chamada de tupla e cada elemento da seqüência será chamado de
componente.
O número de componentes de uma tupla é chamado de aridade. Por exemplo, (a, b) é uma tupla de aridade
2. Seu primeiro componente é a e seu segundo componente é b.
De um modo geral, tupla é o modelo matemático apropriado para cada membro de um conjunto cujos
membros:
♦ possuem uma mesma estrutura
♦ essa estrutura é uma seqüência.
Relação
Um conjunto de elementos, cada um deles sendo uma tupla e todos possuindo a mesma aridade  seja
k  é denominado relação. A aridade da relação é k.
Uma tupla, ou relação, de aridade 1 é dita unária. Se a aridade for 2, será dita binária e, em geral, se a
aridade for k, será dita k-ária. Uma tupla de aridade k é também chamada k-tupla.
⇒
exemplo
A relação R = {(1, 2), (1, 3), (2, 2)} tem aridade 2, ou seja, é uma relação binária. Seus elementos
são (1, 2), (1, 3) e (2, 2), cada um deles sendo uma tupla de aridade 2.
Relações e Funções
B. Maffeo
página 11 de 32
PRODUTO CARTESIANO
Um produto cartesiano é uma operação definida sobre conjuntos.
Sejam os conjuntos A e B. O produto cartesiano de A e B, denotado por A × B, é definido como o conjunto
de todos os pares nos quais o primeiro componente é escolhido de A e o segundo, de B. Assim,
A × B = {(a, b) | a ∈ A ∧ b ∈ B}
Se A e B são conjuntos finitos de cardinalidade m e n, respectivamente, a cardinalidade de A × B é mn.
⇒
exemplos
♦ considerando que o símbolo Z denota, convencionalmente, o conjunto de todos os números inteiros,
Z × Z representa o conjunto de todos os pares de números inteiros
♦ se A = {1, 2} e B = {a, b, c}, então
A × B = {(1, a), (1, b), (1, c), (2, a), (2, b), (2, c)}
RELAÇÕES BINÁRIAS
Uma relação binária R é um conjunto de pares que é subconjunto do produto cartesiano de dois conjuntos.
Formalmente, sendo esses conjuntos A e B : R ⊆ A × B .
Se a relação R é um subconjunto de A × B, diz-se que R é de A para B.
O conjunto A constitui o domínio e o conjunto B constitui a imagem da relação.
Se B coincide com A, diz-se que R é uma relação sobre A ou sobre o domínio de A.
⇒
exemplos
♦ A relação aritmética < sobre os números inteiros é um subconjunto de Z × Z consistindo nos
pares (a, b) tais que o valor de a é menor do que o valor de b. Assim, o símbolo < pode ser
entendido como o nome do conjunto
{(a, b) | (a, b) ∈ Z × Z ∧ (o valor de a é menor do que o valor de b)}.
Usa-se a abreviatura a < b significando “(a, b) ∈ <” .
As demais relações aritméticas sobre números inteiros, tais como > ou ≤ , podem ser definidas
analogamente. Da mesma forma, as comparações sobre números reais.
Relações e Funções
B. Maffeo
página 12 de 32
♦ Seja R = {(1, 2), (1, 3), (2, 2)}.
São incertos o domínio e a imagem dessa relação.
Certamente, 1 e 2 pertencem ao domínio de R, pois aparecem como primeiros componentes das
tuplas em R.
Analogamente, a imagem de R deve incluir 2 e 3.
Entretanto, é possível ver R como uma relação de {1, 2} para {2, 3} ou como uma relação sobre Z,
dois exemplos tomados dentre uma infinidade de escolhas possíveis.
O segundo exemplo indica que o uso consistente dos conceitos aqui apresentados exige que sejam
especificados o domínio e a imagem da relação considerada.
Notação In-Fixada para Relações Binárias
É comum o uso da notação in-fixada para representar a fórmula que indica a pertinência de um dado elemento
a uma relação binária.
Assim, as fórmulas 1 < 2 e 4 ≥ 4 são usadas, normalmente, no lugar das escolhas mais rebuscadas
(1, 2) ∈ < e (4, 4) ∈ ≥ .
⇒
exemplo
A mesma notação pode ser usada para relações binárias quaisquer e, no caso do exemplo anterior, a
relação R poderia ser escrita como os três “fatos” 1R2, 1R3 e 2R2.
PRODUTO CARTESIANO ENVOLVENDO MAIS DE DOIS CONJUNTOS
Diferentemente do produto aritmético, o produto cartesiano não goza das propriedades de comutatividade e
de associatividade . É fácil encontrar exemplos onde A × B ≠ B × A, invalidando a comutatividade. A lei
associativa nem mesmo faz sentido, pois (A × B) × C teria, como elementos, pares do tipo ((a, b), c),
enquanto A × (B × C) apresentaria pares do tipo (a, (b, c)).
Entretanto, o conceito de produto cartesiano pode ser estendido, visando fundamentar a existência de tuplas
com mais de dois componentes, para um conceito de produto cartesiano envolvendo mais de dois conjuntos.
Para isso, considera-se que A1 × A2 × ... × Ak designa o produto cartesiano dos conjuntos A1, A2, ... , Ak ,
isto é, designa o conjunto de k-tuplas (a1, a2, ... , ak) tal que a1 ∈ A1, a2 ∈ A2, ... e ak ∈ Ak.
⇒
exemplo
Z × Z × Z representa o conjunto de triplas de números inteiros (i, j, k)  contendo, por exemplo, a
tripla (1, 2, 3)  . Esse produto não deve ser confundido com (Z × Z) × Z, que representa pares
como ((1, 2), 3), ou com Z × (Z × Z), que representa pares como (1, (2, 3 )).
Relações e Funções
B. Maffeo
página 13 de 32
GRAFOS REPRESENTANDO RELAÇÕES
Uma relação R, cujos domínio A e imagem B são conjuntos finitos, pode ser representada por um grafo.
Desenha-se um nodo para cada elemento em A e/ou B. Se aRb, desenha-se um arco de a para b.
⇒
exemplo
R = {(1, 2), (1, 3), (2, 2)} pode ser representada por
2
1
3
Relações e Funções
B. Maffeo
página 14 de 32
FUNÇÕES
DEFINIÇÕES BÁSICAS
Seja uma relação R, do domínio A para a imagem B, com a propriedade: “para todo membro a em A existe,
no máximo, um elemento b em B tal que aRb”. Então, R é considerada uma função parcial do domínio A
para a imagem B.
Formalmente:
f ⊆ { (a,b) |
a ∈ A ∧ b ∈ B ∧ aRb ∧ R ⊆ A × B ∧
∀a, b1, b2 ( b1 ∈ B ∧ b2 ∈ B ∧ aRb1 ∧ aRb2 → b1 = b2 ) }
Se, para cada membro a em A, existir exatamente um elemento b em B tal que aRb, então R é considerada
uma função total de A para B.
Formalmente:
f ⊆ { (a,b) |
aRb ∧ R ⊆ A × B ∧ ∀a ( a ∈ A → ∃b ( b ∈ B ∧ aRb ) ) ∧
∀a, b1, b2 ( b1 ∈ B ∧ b2 ∈ B ∧ aRb1 ∧ aRb2 → b1 = b2 ) }
A diferença entre uma função parcial e uma função total é que uma função parcial pode ser indefinida sobre
alguns elementos de seu domínio. Por exemplo, para algum a em A, pode não existir b em B tal que aRb.
Aqui, o termo função será utilizado para referências à noção mais geral de função parcial.
Notação comumente usada para função:
f: A→B
(denotando a relação R de A para B)
com
f (a) = b
(o uso de f no lugar de R convencionando a unicidade
de cada par associado a um dado elemento do domínio).
⇒
exemplo
Seja Q a função total de Z para Z dada por
Q ⊆ { (a, b) | aRb ∧ R ⊆ Z × Z ∧ ∀a ( a ∈ Z → ∃b ( b ∈ Z ∧ b = a ∗ a ) ) },
conjunto dos pares de inteiros cujo segundo componente é o quadrado do primeiro componente.
Então Q possui membros tais como (3, 9), (−4, 16) e (0, 0).
É possível, também, expressar que Q é a função “elevar ao quadrado”, escrevendo-se Q (3) = 9,
Q (−4) =16 e Q (0) = 0.
Relações e Funções
B. Maffeo
página 15 de 32
AS MUITAS NOTAÇÕES PARA FUNÇÃO
Uma função f, de A × B para C, é, formalmente, um subconjunto de (A × B) × C.
Um par típico na função f teria a forma ((a, b), c), ande a, b e c, seriam membros de A, B e C,
respectivamente. Utilizando a notação especial para funções, pode-se escrever f (a, b) = c.
f pode ser vista como uma relação binária de A × B para C, uma vez que toda função é uma relação.
Utilizando a notação in-fixada para denotar relações, a ocorrência de ((a, b), c) em f pode ser também
escrita (a, b) f c.
Ao estender-se para mais de dois conjuntos o conceito de produto cartesiano, pode ser desejável remover os
parênteses da expressão para o produto. Assim, estariam sendo identificadas duas expressões formalmente
não equivalentes, (A × B) × C e A × B × C. Nesse caso, se f for armazenada como um conjunto de triplas,
será necessário lembrar que os dois primeiros componentes fazem parte do domínio da função e o terceiro
componente faz parte da imagem da função.
FUNÇÃO EM SCHEME
Note-se que o conceito de função baseado em Teoria de Conjuntos não é muito diferente da noção de função
encontrada em Scheme.
Seja a declaração da “função Scheme” q
(define q (lambda (x) (* x x)) )
que recebe um número inteiro e retorna seu quadrado.
Usualmente, pensa-se em q (a) como sendo o mesmo que a função Q (a) do exemplo precedente, embora
(q a) expresse um modo de computar quadrado de a e Q seja somente a definição abstrata da operação
“elevar ao quadrado”. Ou seja, Q constitui o modelo conceitual da operação “elevar ao quadrado” e
(q a) é uma implementação em Scheme dessa operação.
Note-se, também, que, na prática, (q a) é sempre uma função parcial, pois existem muitos valores de a para
os quais (q a) não retornará um número inteiro em virtude da finitude da aritmética de computadores.
A linguagem Scheme permite definir funções com mais de um argumento.
Uma “função Scheme” que recebe dois argumentos a e b do tipo inteiro e retorna um número inteiro é uma
função de Z × Z para Z. De maneira análoga, se os tipos dos argumentos a e b são tais que a e b
pertençam, respectivamente, aos conjuntos A e B e f retorne um membro de tipo C, então f é uma função
de A × B para C. Mais geralmente, se f recebe k argumentos  por exemplo, dos conjuntos
A1, A2, ... , Ak , respectivamente  e retorna um membro do conjunto B, então diz-se que f é uma função
de A1 × A2 × ... × Ak para B.
Por exemplo, sendo L uma lista em cujas posições encontram-se valores do tipo T, pode-se considerar a
função (member x L) como uma função de T × LISTA para {TRUE, FALSE}. Aqui, T designa o conjunto
de valores desse tipo e LISTA designa o conjunto de listas de itens do tipo T. Escrita em Scheme, essa
estrutura não é revelada pela declaração da função (member x L) pois Scheme não é uma linguagem tipada.
Relações e Funções
B. Maffeo
página 16 de 32
Formalmente, uma função de um domínio A1 × A2 × ... × Ak para uma imagem B é um conjunto de pares da
forma ( (a1, a2, ... , ak) , b), onde cada ai pertence ao conjunto Ai e b pertence ao conjunto B. Note-se
que o primeiro elemento do par é, ele próprio, uma k-tupla.
Por exemplo, a função (member x L), acima considerada, pode ser vista como o conjunto de pares
((x, L), y), onde x é um valor do tipo T, L é uma lista de elementos desse tipo e y é ou TRUE ou
FALSE, dependendo de x estar ou não contido na lista L.
Seja em Scheme, seja a partir da definição formal baseada na Teoria de Conjuntos, é possível pensar em
uma função como uma caixa que recebe um valor do conjunto domínio e produz um valor do conjunto
imagem, tal como é sugerido, a seguir, para a função (member x L).
(x, L)
member
y
CORRESPONDÊNCIA UM - PARA - UM
Seja F uma função parcial do domínio A para a imagem B, com as seguintes propriedades:
1. Para cada elemento a em A, existe um elemento b em B tal que F (a) = b.
Formalmente: F ⊆ { (a,b) | ∀a ( a ∈ A → ∃b ( b ∈ B ∧ aRb ) ) ∧
∀a, b1, b2 ( b1 ∈ B ∧ b2 ∈ B ∧ aRb1 ∧ aRb2 → b1 = b2 ) }
2. Para cada elemento b em B, existe algum a em A tal que F (a) = b.
Formalmente: F ⊆ { (a,b) | ∀b ( b ∈ B → ∃a ( a ∈ A ∧ aRb ) ) }
3. Para nenhum elemento b em B, existem dois elementos a1 e a2 em A tais que F (a1) = F (a2) = b.
Formalmente: F ⊆ { (a,b) | ∀b, a1, a2 ( b ∈ B ∧ a1 ∈ A ∧ a2 ∈ A ∧ a1Rb ∧ a2Rb →
a1 = a2 ) }
Nessas condições, F é considerada uma correspondência um-para-um de A para B. Também é usado o
termo bijeção para designar esse tipo de correspondência.
A propriedade 1 estabelece que F é uma função total de A para B.
A propriedade 2 estabelece que F é uma função total de A sobre B. Também é usado o termo surjeção para
designar esse tipo de correspondência.
A propriedade de 3 permite definir una função, inversa de F, de B para A. As propriedades 2 e 3,
conjuntamente, estabelecem que essa função comporta-se como uma função total de B para A.
Uma função total F que goze da propriedade 3 estabelece uma correspondência que é designada, também,
pelo termo injeção.
Relações e Funções
B. Maffeo
página 17 de 32
Uma correspondência um-para-um é basicamente uma função total nas duas direções, mas é importante
ressaltar que o fato de ser F uma correspondência um-para-um depende, não só dos pares em F, mas,
também, do domínio e da imagem especificados. Por exemplo, é possível, a partir de uma correspondência
um-para-um de A para B, alterar o domínio acrescentando a A algum novo elemento x não mencionado em
F. Nessas condições, F não seria uma correspondência um-para-um de A ∪ {x} para B.
⇒
exemplos
♦ A função “eleva ao quadrado” Q, de Z para Z, não é uma correspondência um-para-um. Q satisfaz
a propriedade 1, pois, para cada número inteiro i, existe algum número inteiro, seja i2, tal que
Q (i) = i2. Entretanto, Q não satisfaz a propriedade 2, pois há elementos b em Z  em particular,
todos os números negativos  que não são Q (a) para algum a. Q também não satisfaz a
propriedade 3, pois existem muitos exemplos de valores distintos de a para os quais Q (a) é igual ao
mesmo b. Por exemplo, Q (3) = 9 e Q (−3) = 9.
♦ Seja a função total P de Z para Z, definida por P (a) = a+1. Ou seja, P adiciona 1 a qualquer
número inteiro. Por exemplo, P (5) = 6 e P (−5) = −4.
Formas alternativas de representação seriam o conjunto de tuplas
{..., (−2, −1), (−1, 0), (0, 1), (1, 2), ...}
ou o grafo
...
−2
−1
0
1
2
...
Aqui, P é uma correspondência um-para-um, de inteiros para inteiros, pois:
• P é uma função parcial, pois quando se adiciona 1 a um inteiro a obtém-se um único inteiro a + 1
• P satisfaz a propriedade 1, pois para cada inteiro a existe algum inteiro a + 1
• P satisfaz a propriedade 2, pois para cada inteiro b existe algum inteiro, seja b − 1, tal que
P (b − 1) = b
• P satisfaz a propriedade 3, pois para um inteiro qualquer b não existem dois inteiros distintos tais
que, somados a 1, resultam b.
♦ P não é uma correspondência um-para-um, de reais para reais, pois não possui pares para reais
não inteiros.
Uma correspondência um-para-um de A para B é uma forma de estabelecer uma associação única entre os
elementos de A e de B, como a que existe entre os “dedos” de uma luva e os dedos da mão que a luva veste.
Relações e Funções
B. Maffeo
página 18 de 32
Analogamente, é possível imaginar essa associação como sendo uma definição da função inversa, ou seja, uma
correspondência de A para B pode ser invertida trocando-se a ordem dos componentes em seus pares,
obtendo uma correspondência um-para-um de B para A.
Uma conseqüência de haver essa correspondência entre “a luva e a mão” é a igualdade do número de dedos
na luva e na mão.
Isso parece ser uma noção natural e intuitiva: dois conjuntos possuem mesma cardinalidade quando existe uma
correspondência um-para-um de um conjunto para o outro. Entretanto, quando os conjuntos possuem um
número infinito de elementos, chega-se a algumas conclusões surpreendentes a partir dessa definição de
“mesma cardinalidade”.
A relevância desse tipo de correspondência para a Ciência da Computação revela-se de diferentes maneiras.
Uma delas, bastante importante, relaciona-se à área de bancos de dados e associa-se, na modelagem
conceitual, ao conceito de atributo determinante e, nos níveis de design e de implementação, ao conceito
de chave.
IMPLEMENTANDO FUNÇÕES COMO DADOS
Em um programa de computador, funções são, normalmente, implementadas como subprogramas, mas, no
caso de funções finitas cujo domínio seja pequeno, elas podem ser implementadas com o uso de técnicas
bastante similares às técnicas utilizadas para conjuntos, ou seja, empregando estruturas de dados do tipo lista
e arranjo.
OPERAÇÕES BÁSICAS SOBRE FUNÇÕES
Inserir, Suprimir e Buscar
As operações básicas sobre funções são similares àquelas aplicadas a estruturas do tipo dicionário.
Seja F uma função do domínio conjunto A para a imagem conjunto B. Pode-se, então:
♦ Inserir um novo par (a, b) tal que F (a) = b. Como F deve ser uma função, se já houver um par (a, c),
esse par deve ser substituído por (a, b).
♦ Suprimir o valor associado a F (a). Aqui, é necessário apenas o valor a do domínio. Se houver algum b tal
que F (a) = b, então o par (a, b) deve ser removido do conjunto. Não havendo esse par, nada ocorre.
♦ Buscar o valor associado a F (a). Isto é, dado o valor a do domínio, retornar o valor b tal que
F (a) = b. Não havendo o par (a, b) no conjunto, retorna-se algum valor especial para avisar que F (a) é
indefinido.
Relações e Funções
B. Maffeo
página 19 de 32
⇒
exemplos
Seja F designando o conjunto {(3, 9), (−4, 16), (0, 0)}, isto é, F (3) = 9, F (−4) = 16 e F (0) = 0.
Nessas condições, busca (3) retorna 9 e busca (2) retorna um valor, por exemplo −1, indicando que
não há valor definido para F (2).
A operação suprime (3) retira o par (3, 9), enquanto que suprime (2) nada faz.
Executando-se insert (5, 25), o par (5, 25) é adicionado ao conjunto F ou, de maneira equivalente,
tem-se, agora, F (5) = 25.
Executando-se insere (3, 10), o antigo par (3, 9) é retirado do conjunto F e o novo par (3, 10) é
acrescentado, de modo que, agora, F (3) = 10.
Funções como Subprogramas e Funções como Dados
Precedentemente, foi traçada uma forte analogia entre a noção abstrata de função e o tipo de subprograma
função implementado na linguagem de programação Scheme. Convém, entretanto, notar uma diferença
importante.
Se F é uma “função Scheme” e x é um membro de seu conjunto domínio, então F especifica como deve ser
computado o valor F (x). O mesmo subprograma será executado, uniformemente, para qualquer valor de x.
Entretanto, quando uma função é representada por meio de dados, supõe-se que:
♦ a função consiste em um conjunto finito de pares
♦ é normal a imprevisibilidade dos pares.
Isso significa que não haverá, eventualmente, uma forma conveniente de, dado um x, computar F (x). O
melhor que pode ser feito é criar-se uma tabela contendo cada um dos pares
(a1, b1), (a2, b2), ..., (an, bn)
tais que F (ai) = bi .
Nesse caso, a função constitui-se, efetivamente, de dados e não de um subprograma, mesmo que seja criado
um algoritmo para armazenar a tabela como parte de um programa e para, nessa tabela interna, dado x,
buscar F (x).
Entretanto, uma abordagem mais produtiva é armazenar a tabela separadamente, como uma estrutura de
dados externa e independente do programa, e buscar valores nela contidos através de um subprograma de
propósito geral aplicável a qualquer função representada como dados.
Nessas condições, quando uma função é representada por meio de dados, especifica-se o que ela é
(modelagem conceitual), sem haver a preocupação de especificar como ela é computada.
Relações e Funções
B. Maffeo
página 20 de 32
BIBLIOGRAFIA UTILIZADA
Foundations of Computer Science
Alfred V. Aho e Jeffrey D. Ullman
( Computer Science Press, 1992 )
seções: 7.7, 7.8, 7.9
Relações e Funções
B. Maffeo
página 21 de 32
ÁRVORES BINÁRIAS
DEFINIÇÃO
Em uma árvore binária, um nodo pode ter, no máximo, dois filhos, denominados filho à esquerda e filho à
direita.
⇒
exemplos
A figura a seguir mostra duas árvores binárias, ambas enraizadas no nodo n1.
n1
A raiz possui o nodo n2 como filho à esquerda e nenhum
filho à direita.
n2
n1
n2
A raiz possui o nodo n2 como filho à direita e nenhum filho à
esquerda.
Essas são as únicas árvores binárias de dois nodos, onde n2 não possui filhos, seja à esquerda, seja à
direita.
É importante entender que, enquanto árvores binárias exigem que seja distinguido se um filho está à esquerda
ou à direita, uma árvore “ordinária” não exige tal distinção. Ou seja, uma árvore binária não é somente uma
árvore onde cada nodo pode ter no máximo dois filhos; deve também ficar explícita a relação de posição
envolvendo os dois filhos.
As duas árvores binárias consideradas no exemplo não são apenas distintas mas, também, desprovidas de
relação com a árvore “ordinária” formada por um nodo raiz n1, nodo esse possuindo um único filho n2, e
representada por
n1
n2
Outra diferença é que, no caso de uma árvore “ordinária”, presume-se que a árvore tenha pelo menos um
nodo, o nodo raiz. Uma árvore binária, entretanto, pode ser uma árvore vazia.
Árvores Binárias
B. Maffeo
página 22 de 32
TERMINOLOGIA BÁSICA
Aplicam-se a árvores binárias os conceitos de filho, irmão, caminho, ancestral, descendente e folha,
definidos para árvores “ordinárias”.
Os filhos à esquerda e à direita são ambos considerados como filhos.
Os dois filhos de um nodo, se existirem, são irmãos.
Um caminho de n1 para nk é a seqüência de nodos n1,n2, ... , nk tal que ni+1 é um filho (à esquerda ou à
direita) de ni, para i < (k − 1).
É permitido o caso k = 1, no qual existe apenas um nodo.
Ancestral de um nodo n é qualquer nodo situado no caminho que liga a raiz da árvore a n. Em particular,
n é ancestral de si mesmo.
Descendente de um nodo n é qualquer nodo do qual n seja ancestral. Em particular, n é descendente
de si mesmo.
Uma folha é um nodo que não possui filhos ou, de maneira equivalente, é um nodo cujas sub-árvores à
esquerda e à direita são ambas vazias.
Um nodo interior é aquele que não é uma folha.
Os conceitos de comprimento de caminho, altura e profundidade são também idênticos àqueles referentes
a árvores “ordinárias”.
O comprimento de um caminho é medido por uma unidade a menos que o número de nodos que o
caminho engloba, isto é, esse comprimento é igual ao número de arcos pai-filho existentes ao longo do
caminho.
A altura de um nodo n é o comprimento do caminho mais longo entre n e uma folha descendente.
A altura de uma árvore binária é igual à altura de sua raiz.
A profundidade de um nodo n é o comprimento do caminho entre a raiz e n.
Árvores Binárias
B. Maffeo
página 23 de 32
TIPOS DE ÁRVORE BINÁRIA
Uma árvore é denominada estritamente binária quando cada nodo possui 0 ou 2 filhos.
Uma árvore binária completa é aquela que apresenta a seguinte propriedade: se n é um nodo tal que
alguma sub-árvore é vazia, então n localiza-se no nível mais profundo ou no penúltimo nível da árvore.
Uma árvore binária cheia é aquela em que, se n é um nodo com alguma de suas sub-árvores vazia, então n
localiza-se no último nível. Segue-se que toda a árvore binária cheia é completa e estritamente binária.
Árvores Binárias
B. Maffeo
página 24 de 32
⇒
exemplos
n1
n2
n3
São as cinco possíveis árvores binárias
formadas por três nodos.
Em cada uma, n3 é um descendente de n1 e
existe um caminho de n1 para n3.
Nas cinco árvores, o nodo n3 é uma folha.
O nodo n2 é folha somente na árvore do meio,
sendo, nas demais, um nodo interior.
A altura de n3 é 0 em cada árvore.
A altura de n1 é 2 em todas as árvores salvo na
do meio, onde sua altura é 1.
A altura de cada árvore é a altura de n1 nessa
árvore.
A profundidade do nodo n3 é 2 em todas as
árvores salvo na do meio, onde sua
profundidade é 1.
n1
n2
n3
n1
n3
n2
n1
n2
Ou seja, cada árvore binária é invariante
sob qualquer operação que, mantida sua
estrutura, simplesmente troque a posição
dos nodos n1 n2 n3.
n3
n1
n2
n3
Árvores Binárias
B. Maffeo
página 25 de 32
DEFINIÇÃO RECURSIVA EQUIVALENTE
Uma árvore binária A é um conjunto finito de elementos interligados, denominados nodos, para o qual é
imposta :
♦ uma relação hierárquica, do tipo pai-filho, entre quaisquer dois nodos adjacentes
♦ a seguinte formulação recursiva
caso base
A = ∅ e a árvore é dita vazia.
passo indutivo
Se r é um nodo e A1 e A2 são árvores binárias, então há uma árvore binária com raiz r, sub-árvore à
esquerda A1 e sub-árvore à direita A2, conforme a ilustração a seguir.
A raiz de A1 é o filho à esquerda de r, a menos que A1 seja vazia,
caso em que r não possui filho à esquerda.
r
Da mesma forma, a raiz de A2 é o filho à direita de r, a menos que
A2 seja vazia, caso em que r não possui filho à direita.
A1
A2
Ou seja, uma árvore binária é um conjunto de elementos
submetidos a uma estruturação hierarquizada ternária (um pai tem
no máximo dois filhos).
Note-se que, se A1 = A2 = ∅, então o nodo r é isolado e { r } é uma árvore binária de um só nodo.
Árvores Binárias
B. Maffeo
página 26 de 32
BIBLIOGRAFIA UTILIZADA
Foundations of Computer Science
Alfred V. Aho e Jeffrey D. Ullman
( Computer Science Press, 1992 )
seções: 5.2, 5.3, 5.4, 5.6
Árvores Binárias
B. Maffeo
página 27 de 32
ÁRVORES BINÁRIAS DE BUSCA
DEFINIÇÃO
Uma árvore binária de busca (BST - binary search tree) é uma árvore binária rotulada na qual vale a
seguinte propriedade para cada nodo n:
Todos os nodos situados na sub-árvore à esquerda de n possuem rótulos de valor inferior ao
valor do rótulo de n e todos os nodos situados na sub-árvore à direita de n possuem rótulos de
valor superior ao valor do rótulo de n.
ABB é uma estrutura de armazenamento muito favorável à solução de problemas de busca em que, dado um
conjunto de elementos onde cada elemento é identificado univocamente por uma chave, o objetivo é localizar
no conjunto o elemento correspondente a uma chave específica.
Numa ABB, os elementos do conjunto são previamente distribuídos pelos nodos da árvore de forma
ordenada conveniente à busca. A localização da chave desejada é, então, obtida por meio de um percurso
apropriado na árvore.
É importante ressaltar a relevância desse problema na área de computação, especialmente nas aplicações não
numéricas. Sem dúvida, a operação de busca é uma das operações realizadas com maior freqüência em
sistemas de informação baseados em computador.
⇒
exemplo
Seja S = {s1, s2, ... ,sn} um conjunto de chaves satisfazendo s1 < s2 < ... < sn.
A figura a seguir apresenta duas ABBs construídas sobre S.
s3
s2
s1
s7
s1
s4
Árvores Binárias de Busca
s3
s5
s2
s4
s5
s6
s6
B. Maffeo
página 28 de 32
s7
DICIONÁRIO
O emprego de ABB é uma boa escolha de design no caso de um dicionário.
Assume-se que os rótulos dos nodos são escolhidos dentro de um conjunto cujos elementos podem obedecer
a uma relação de ordem do tipo “menor do que”, simbolizado pelo caractere < . Exemplos disso são os
números inteiros ou reais com a ordenação comparativa usual ou cadeias de caracteres onde é possível
estabelecer uma ordem lexicográfica, ou alfabética, representada por < .
⇒
exemplo
(para o conjunto {Hairy, Bashful, Grumpy, Sleepy, Sleazy, Happy} onde < é a
ordem lexicográfica)
Hairy
Bashful
Grumpy
Sleepy
Sleazy
Note-se que os nomes da sub-árvore à esquerda
da raiz são todos lexicograficamente menores do
que Hairy, enquanto que os da sub-árvore à
direita são todos maiores.
Essa propriedade vale para cada nodo da árvore
considerada.
Happy
BUSCANDO UM ELEMENTO NA ABB
Deseja-se verificar se um dado elemento x está presente no dicionário representado pela ABB A.
Comparando-se x com o elemento na raiz de A, usa-se vantajosamente a propriedade de ordenação da ABB
para localizar x com bastante rapidez ou verificar que x não está presente.
procedimento informal
Se x estiver na raiz, a busca estará concluída.
Se não, se x for menor do que o elemento na raiz, x só poderá ser encontrado na sub-árvore à esquerda da
raiz (devido à propriedade de ABB s). Se x for maior, então só poderá ser encontrado na sub-árvore à direita
da raiz (novamente, devido à propriedade de ABB s).
Assim, verifica-se que a operação de busca pode ser expressa formalmente através de um procedimento
recursivo.
Árvores Binárias de Busca
B. Maffeo
página 29 de 32
método indutivo
base
Se a árvore A for vazia, então x não estará presente e a busca está concluída.
Se A não for vazia e x encontrar-se na raiz, então pesquisa-se a raiz e a busca está concluída.
passo indutivo
Se A não for vazia mas x não se encontrar na raiz, seja y o elemento contido na raiz:
♦ se x < y, então x deve ser buscado na sub-árvore à esquerda da raiz
♦ se x > y, então x deve ser buscado na sub-árvore à direita da raiz.
A propriedade de ABBs garante que x não pode ser encontrado na sub-árvore que não for verificada.
Esse método caracteriza uma alternativa de design da operação de busca definida no nível conceitual e usa
uma ABB como modelo de dados. Mais concretamente, ele pode ser implementado por meio de um
algoritmo recursivo escrito em Scheme, o qual deve processar listas que implementam ABBs.
Vale notar que o método indutivo acima apresentado como solução do problema é uma alternativa de design
porque o problema é formulado em termos da estrutura matemática conjunto, a qual caracteriza o nível
conceitual da especificação. Outra alternativa de design possível, porém menos eficiente que o emprego de
uma ABB, seria utilizar uma seqüência ordenada.
Tratando-se de um problema formulado em termos de ABB diretamente, a solução apresentada em termos do
método indutivo estaria situada no nível conceitual da especificação.
INSERINDO UM ELEMENTO NA ABB
método indutivo
base
Se A for a árvore vazia, substitui-se A por um novo nodo e coloca-se x nesse nodo.
Se A não for a árvore vazia e sua raiz contiver o elemento x, então x já se encontra no dicionário e não há
nada a ser feito.
passo indutivo
Se A não for a árvore vazia e sua raiz não contiver o elemento x, então x deve ser inserido na sub-árvore
à esquerda quando x < y (y sendo o elemento contido na raiz) ou deve ser inserido na sub-árvore à direita
quando x > y.
Árvores Binárias de Busca
B. Maffeo
página 30 de 32
SUPRIMINDO UM ELEMENTO DA ABB
Suprimir um elemento de uma ABB é um pouco mais complexo do que inserir ou buscar.
procedimento informal
Inicialmente, é necessário localizar o nodo que contém x, o elemento a ser retirado. Se não existir esse nodo,
nada há a ser feito uma vez que x não está contido no dicionário.
Se x estiver contido em uma folha, basta retirar essa folha.
Se, entretanto, x estiver contido em um nodo interior n, não será possível retirá-lo, pois a retirada de um nodo
interior ocasionaria uma ruptura na árvore. Nesse caso, é necessário rearranjar a ABB de modo que:
♦ seja mantida sua propriedade de ordenação
♦ x deixe de ocorrer em qualquer de seus nodos.
Para executar essa reordenação há duas possibilidades a considerar.
1. Se n possuir apenas um filho, é possível substituir n por esse filho, mantendo-se, assim, a propriedade da
ABB.
2. Se n possuir os dois filhos, uma estratégia é encontrar o nodo m com rótulo y, sendo esse o menor
elemento da sub-árvore à direita de n, e substituir x por y no nodo n, tal como é sugerido na figura a
seguir. Remove-se, então, o nodo m da sub-árvore à direita de n.
n
n
x
y
⇒
<x
>x
<y
>y
A propriedade da ABB continua valendo pelo fato de x ser maior do que qualquer elemento contido na subárvore à esquerda de n.
Assim, y, que, por pertencer à sub-árvore à direita de n, é maior do que x, é, também, maior do que qualquer
elemento contido na sub-árvore à esquerda de n. Logo, no que concerne à sub-árvore à esquerda de n, y é
elemento adequado para ser armazenado em n. Quanto à sub-árvore à direita de n, y é igualmente adequado
para ser armazenado em n, pois foi escolhido como sendo o menor elemento dessa sub-árvore.
Árvores Binárias de Busca
B. Maffeo
página 31 de 32
BIBLIOGRAFIA UTILIZADA
Foundations of Computer Science
Alfred V. Aho e Jeffrey D. Ullman
( Computer Science Press, 1992 )
seção: 5.8, 5.9
Árvores Binárias de Busca
B. Maffeo
página 32 de 32
Download