Escolar Documentos
Profissional Documentos
Cultura Documentos
2007/08
A.E.D.
F.S.B.
Procura em vectores
2007/08
A.E.D.
F.S.B.
i = 0
ENQUANTO i < dim E vect[ i ] != x FAZER
i = i +1
FIM
Exemplo de uso:
if( res == -1 )
System.out.println( x + “ não foi encontrado!” );
else
System.out.println( x + “ foi encontrado na posição ” + res );
}
if( !encontrou )
return –1;
return meio;
}
Exemplo de procura do nº 10
2 3 5 7 9 10 11 12 17 19 21 28 30 33 38 42 45 55
esq dir
1ª iteração meio
2 3 5 7 9 10 11 12 17 19 21 28 30 33 38 42 45 55
esq dir
2ª iteração meio
2 3 5 7 9 10 11 12
esq dir
3ª iteração meio
9 10 11 12
Encontrou
Procura em vectores : binária
2007/08
A.E.D.
F.S.B.
Exemplo de procura do nº 4
2 3 5 7 9 10 11 12 17 19 21 28 30 33 38 42 45 55
esq dir
1ª iteração meio
2 3 5 7 9 10 11 12 17 19 21 28 30 33 38 42 45 55
esq dir
2ª iteração meio
2 3 5 7 9 10 11 12
esq dir
3ª iteração meio
2 3 5
esq
dir
4ª iteração meio
5
dir esq
5ª iteração Não encontrou
Ordenação de vectores
2007/08
A.E.D.
F.S.B.
2007/08
A.E.D.
F.S.B. Ordenação de vectores : inserção
Algoritmo de ordenação por inserção directa,
assumindo:
vect é o vector a ordenar
dim é a dimensão do vector
O índice do primeiro elemento é 0 (zero)
9 9 3 3 3 3 3 3 2 2 2
3 3 9 9 5 5 5 5 3 3 3
5 5 5 5 9 9 9 9 5 5 5
11 11 11 11 11 11 11 11 9 9 7
2 2 2 2 2 2 2 2 11 11 9
7 7 7 7 7 7 7 7 7 7 11
2007/08
A.E.D.
F.S.B. Ordenação de vectores : inserção
O algoritmo de ordenação por inserção pode ser
implementado pelo seguinte método:
int v[13] = { 2, 4, 65, 54, 34, 23, 90, 12, 6, 78, 87, 26, 42 };
ordenaInsercaoDirecta( v );
2007/08
A.E.D.
F.S.B. Ordenação de vectores : selecção
Ordenação por selecção
Neste caso percorre-se o vector, procurando o menor
elemento e coloca-se este na primeira posição
O elemento na primeira posição é colocado na
posição ocupada anteriormente pelo menor
Repete-se para os restantes elementos
2007/08
A.E.D.
F.S.B. Ordenação de vectores : selecção
Algoritmo de ordenação por selecção
assumindo:
vect é o vector a ordenar
dim é a dimensão do vector
O índice do primeiro elemento é 0 (zero)
2007/08
A.E.D.
F.S.B. Ordenação de vectores : selecção
Exemplificação do algoritmo
9 9 2 2 2 2 2 2 2 2 2
menor
3 3 3 3 3 3 3 3 3 3 3
menor
5 5 5 5 5 5 5 5 5 5 5
11 11 11 11 11 11 11 11 7 7 7
menor
menor
2 2 9 9 9 9 9 9 9 9 9
menor
7 7 7 7 7 7 7 7 11 11 11
2007/08
A.E.D.
F.S.B. Ordenação de vectores : selecção
O algoritmo de ordenação por selecção pode ser
implementado pela seguinte função:
2007/08
A.E.D.
F.S.B. Ordenação de vectores : permutação
Ordenação por permutação
Neste caso percorre-se o vector, do último para o
primeiro, comparando elementos consecutivos dois a
dois e trocando-os se estiverem na ordem inversa
Após a primeira iteração o menor valor estará na
primeira posição, pelo que as repetições seguintes,
deverão ter em conta apenas os restantes elementos
e assim sucessivamente
Chama-se a este algoritmo Bubblesort
2007/08
A.E.D.
F.S.B. Ordenação de vectores : permutação
Algoritmo da ordenação por permutação
(bubblesort) assumindo:
vect é o vector a ordenar
dim é a dimensão do vector
O índice do primeiro elemento é 0 (zero)
2007/08
A.E.D.
F.S.B. Ordenação de vectores : permutação
Pode-se fazer uma melhoria óbvia ao algoritmo:
Se não houve permutações é porque o vector já está
ordenado
ordenado = FALSO
i = 0
ENQUANTO i < dim-1 E NÃO ordenado FAZER
ordenado = VERDADE
PARA j = dim - 1 ATÉ i + 1 FAZER
SE vect[ j - 1 ] > vect[ j ] FAZER
TROCAR vect[ i ] COM vect[ j ]
ordenado = FALSO
FIM
i = i +1
FIM
2007/08
A.E.D.
F.S.B. Ordenação de vectores : permutação
Exemplificação do algoritmo
1ª iteração 2ª iteração
2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3
9 9 9 5 5 5 5 5 5
5 5 5 9 9 9 7 7 7
7 7 7 7 7 7 9 9 9
11 11 11 11 11 11 11 11 11
2007/08
A.E.D.
F.S.B. Ordenação de vectores : permutação
O algoritmo de ordenação Bubblesort pode ser
implementado pelo seguinte método:
void bubbleSort( int oVector[] ) {
boolean ordenado = false;
int i = 0;
Algoritmo de ShellSort
Inventado por Donald Shell
Neste caso percorre-se o vector ordenando apenas
elementos que se encontram afastados
Para ordenar estes usa-se o algoritmo de inserção
À distância entre elementos chama-se incremento
Depois destes estarem ordenados ordenam-se os
mais próximos até se ordenarem os elementos
adjacentes
Ou seja, vai-se diminuindo o incremento até este ser 1
Como a distância entre elementos se aproxima de 1
este algoritmo também se costuma chamar
Ordenação por incrementos decrescentes
Ordenação de vectores : ShellSort
2007/08
A.E.D.
F.S.B.
do{
h /= 3; // actualizar o h para esta iteração
for( int i = h; i < v.length; i+= h ) {
int x = v[ i ];
int j = i;
while( j > 0 && v[ j-h ] > x ){
v[ j ] = v[ j-h ];
j -= h;
}
v[ j ] = x;
}
} while( h > 1 );
}
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Algoritmo de MergeSort
Algoritmo recursivo
Divide o vector a meio, formando dois vectores
ordena-os separadamente
reagrupa-os num novo vector
Para ordenar os vectores resultantes aplica o mesmo
raciocínio
Obriga a criar um novo vector por causa do
reagrupamento
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Divisão em sub-vectores
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Neste ponto coloca-se outro problema:
Como se juntam dois vectores, já ordenados de modo
a ficarem um só vector?
O algoritmo é simples:
Verifica-se qual dos dois vectores tem o menor
número na posição inicial
Coloca-se esse elemento na primeira posição de um
novo vector
Passa-se ao elemento seguinte no vector de onde se
retirou o elemento
No vector cujo elemento não foi retirado mantém-se na
mesma posição
Repete-se o algoritmo para os restantes elementos
dos vectores, actualizando sempre o vector que foi
alterado
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Caso de junção de vectores
2 i2 = 0 2 i2 = 0 2 2 2 2
5 5 5 i2 = 1 5 i2 = 1 5 i2 = 1 5
7 7 7 7 7 7
8 8 8 8 8 8
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Caso de junção de vectores
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
1ª chamada 2ª chamada
9 9 esq = 0 3 2
9 9 esq = 0 3 3 5 3
3 3 5 5 centro = 2 9 5
5 5 11 11 9
11 11 2 2 dir = 4 11
2
2 2 centro = 4
11
7 7
12 12 7
6 6 12
8 8 dir = 8 6
8
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
1ª chamada 2ª chamada
2 2 esq = 0 3 2
9 9 esq = 0 3 3 5 3
3 3 5 5 centro = 2 9 5
5 5 9 9 9
11 11 11 11 dir = 4 11
2
2 2 centro = 4
11
7 7
12 12 6
6 6 7
8 8 dir = 8 8
12
Este vector também foi alterado
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
1ª chamada
2
9 9 esq = 0 3 2
3 3 5 3
5 5 9 5
11 11 11 6
2 2 centro = 4 7
7 7 8
12 12 6 9
6 6 7 11
8 8 dir = 8 8 12
12
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
Exemplificação do algoritmo
Reagrupar os subvectores
1ª chamada
2
2 2 esq = 0 3 2
3 3 5 3
5 5 9 5
6 6 11 6
7 7 centro = 4 7
8 8 8
9 9 6 9
11 11 7 11
12 12 dir = 8 8 12
12
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
O algoritmo MergeSort para ser implementado
exigue vários métodos:
O método inicial cria o vector novo e começa a
chamada recursiva
O método que é recursivo e vai partindo os vectores a
meio
O método que faz o reagrupamento
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
O método inicial cria o vector novo e começa a
chamada recursiva, pode ser assim
implementado
void mergeSortRec( int v[], int vAux[], int esq, int dir ) {
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
O método que faz o reagrupamento, pode ser
assim implementado
void reagrupar( int v[], int vAux[], int i1, int i2, int fim2 ) {
// a primeira parte do vector vai de i1 a i2-1
int fim1 = i2-1;
// e a segunda de i2 a fim
// … continua no seguinte
2007/08
A.E.D.
F.S.B. Ordenação de vectores : MergeSort
O método que faz o reagrupamento, pode ser
assim implementado
// … continuação do anterior
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Algoritmo de QuickSort
Algoritmo recursivo
Mais rápido algoritmo de ordenação existente
Primeiro é escolhido um valor (pivot)
Divide o vector em duas partes
A primeira parte com elementos menores que o pivot
A segunda parte com elementos maiores que o pivot
O pivot é colocado no meio das duas partes
Para ordenar as partes dai resultantes aplica-se o
mesmo raciocínio
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
9 9 6 6 2 2 2
pivot = 2
3 3 3 <7 3 3 <5 3 3
pivot = 5
5 5 5 5 5
11 11 2 2 6 >5
2 2 7
7 7 pivot = 7 12
12 12 9 >7
6 6 8
8 8 11
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
9 9 6 6 2 2
3 3 3 <7 3 3 3
pivot = 5
5 5 5 5 5
11 11 2 2 6
2 2 7
7 7 pivot = 7 12 Vindo de outra chamada
12 12 9 >7
6 6 8
8 8 11
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
1ª chamada 2ª chamada
9 9 6 2 2
3 3 3 <7 3 3
pivot = 5
5 5 5 5 5
11 11 2 6 6
2 2 7
7 7 pivot = 7 12
12 12 9 >7
6 6 8
8 8 11
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
1ª chamada 2ª chamada
9 9 2 2
3 3 3 3
5 5 5 5
11 11 6 6
2 2 7
7 7 pivot = 7 8
12 12 9
6 6 11
8 8 12
Vindo de outra chamada
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo
Usando um pivot completamente arbitrário!
1ª chamada
2 2 2
3 3 3
5 5 5
6 6 6
7 7 7
8 8 pivot = 7 8
9 9 9
11 11 11
12 12 12
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Visto assim o QuickSort até é fácil de
compreender, mas há pontos ainda em aberto:
Como se escolhe o pivot?
Como se coloca o pivot no centro do vector?
Como se divide o vector em maiores e menores?
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Escolha do pivot:
Não se deve escolher o primeiro elemento
Num vector já ordenado isso iria dividir o vector em dois
pedaços: um com um elemento (o pivot) e outro com o resto
dos elementos todos…
Não se deve escolher o último
Pelas mesmas razões
Um muito utilizado é usar a mediana de três valores
Os valores a utilizar são o primeiro, o último e o central
Escolhe-se aquele que for o valor do meio
Outra técnica é escolher um aleatoriamente
Requer um gerador de números aleatórios
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Colocação do pivot no centro do vector:
Normalmente coloca-se no final do vector
Só depois da divisão em maiores e menores é que se
recoloca no meio
Para isso troca-se o pivot com o penúltimo elemento do
vector
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Escolha do pivot:
Pode ser feita com este método
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Como se divide o vector em maiores e menores?
Existem várias técnicas
Uma muito usada é ter dois índices a percorrer o
vector
Um da esquerda para a direita
Outro da direita para a esquerda
Quando o da esquerda detecta um maior que o pivot
pára
Quando o da direita detecta um menor que o pivot
pára
Quando ambos param trocam os seus valores
Quando ambos se encontram é porque o vector já
está dividido
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo de divisão em maiores e menores
Usando um pivot mediana de 3
v[ini] > v[centro] trocam pivot está no centro Vector pronto para dividir
9 ini = 0 9 2 2 2 2
3 3 3 3 3 3
5 5 5 5 5 5
11 11 11 11 11 11
2 centro = 4 2 9 8 8 6
7 7 7 7 7 7
12 12 12 12 12 12
6 6 6 6 6 8
8 fim = 8 8 8 9 9 9
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Exemplificação do algoritmo de divisão em maiores e menores
Usando um pivot mediana de 3
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
A divisão em maiores e menores pode ser feita
com este método
void divideMaioresMenores( int v[], int ini, int fim, int pivot ) {
int i = ini;
int j = fim -1;
while( i < j ) {
while( v[ ++i ] < pivot );
while( v[ --j ] > pivot );
if( i < j )
troca( v, i, j );
}
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
Tal como no MergeSort o algoritmo exige, pelo
menos, dois métodos:
O que prepara a chamada recursiva
O que faz as chamadas recursivas
quickSortRec( v, 0, v.length -1 );
}
2007/08
A.E.D.
F.S.B. Ordenação de vectores : QuickSort
O que faz as chamadas recursivas
// determinar o pivot
int pivot = pivotMediana( v, ini, fim );
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BucketSort
Mais rápido ainda que o QuickSort!
Mas o QuickSort não era o mais rápido?
Não é genérico!
Só serve para valores numéricos inteiros positivos
Embora com adaptações sirva para negativos
O QuickSort serve para tudo, logo é o mais rápido dos
genéricos
Temos de ter a certeza que os números nunca
são maiores que um dado valor
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BucketSort
Cria-se um vector com o tamanho do maior
número presente no vector a ordenar, chamado
vector de contagem
Inicializa-se cada posição do vector de
contagem a zero
Percorre-se o vector a ordenar
Por cada elemento do vector incrementa-se no vector
de contagem a posição correspondente ao seu valor
Exemplo: o número 5 iria fazer incrementar de 1 a posição 5
do vector de contagem
No final é só alterar o vector original de acordo
com a contagem feita no vector de contagem
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BuckerSort
Exemplificação do algoritmo
Assume-se que o valor mais alto que se pode ordenar é o 14
Vector de contagem,
com 15 posições
0
0
2 1 Ocorrência de 2 incrementa posição 2 do vector
3 1 Ocorrência de 3 incrementa posição 3 do vector
5 0
5 2 2 ocorrências de 5 incrementa duas vezes a posição 5 do vector
12 0
7 1 Ocorrência de 7 incrementa posição 7 do vector
12 1 Ocorrência de 8 incrementa posição 8 do vector
8 1 Ocorrência de 9 incrementa posição 8 do vector
9 0
2 2 ocorrências de 12 incrementa duas vezes a posição 12 do vector
0 Vector de contagem completo
0 Falta repor o vector de origem
0
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BuckerSort
Exemplificação do algoritmo
Assume-se que o valor mais alto que se pode ordenar é o 14
Vector de contagem,
com 15 posições
0 Não há zeros nem uns no vector original
0
2 1 Copia 1 vez o 2 para o vector original
3 1 Copia 1 vez o 3 para o vector original
5 0
5 2 Copia 2 vezes o 5 para o vector original
7 0
8 1 Copia 1 vez o 7 para o vector original
9 1 Copia 1 vez o 8 para o vector original
12 1 Copia 1 vez o 9 para o vector original
12 0
2 Copia 2 vezes o 12 para o vector original
0
0
0
2007/08
A.E.D.
F.S.B. Ordenação de vectores : BucketSort
Este algoritmo pode ser assim implementado
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
private Object buffer[]; // onde se vai armazenar na realidade os elementos
private int nElems; // nº de elementos úteis no vector
private int capMaxima; // nº de elementos máximo no vector
}
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
private Object buffer[]; // onde se vai armazenar na realidade os elementos
private int nElems; // nº de elementos úteis no vector
private int capMaxima; // nº de elementos máximo no vector
private int incremento; // nº de elementos a adicionar quando estiver cheio
}
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Inicialização de um vector
É necessário indicar a capacidade inicial do vector
Pode ainda ser indicado o incremento a praticar
O nº de elementos úteis é zero (ainda está vazio)
Para isso a classe deve ter três construtores
Um por defeito, Um que inicialize com uma dada capacidade
inicial e outro com capacidade inicial e incremento
class Vector {
// construtor para inicializar o vector a uma dada capacidade inicial
// e um incremento com valores por defeito
public Vector();
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
nElems = 0;
buffer = new Object[ capInicial ];
capMaxima = capInicial;
incremento = incre;
}
}
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
meuVector
buffer:
nElems: 0
capMaxima: 5
incremento: 3
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
meuVector
meuVector
buffer:
buffer:
nElems: 1
nElems: 0
capMaxima: 5
capMaxima: 5
incremento: 3
incremento: 3
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
meuVector meuVector
buffer: buffer:
nElems: 2 nElems: 3
capMaxima: 5 capMaxima: 5
incremento: 3 incremento: 3
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
meuVector
buffer:
nElems: 6
capMaxima: 8
incremento: 3
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
buffer[ nElems ] = x;
nElems++;
}
buffer = novoBuffer;
capMaxima = nElems + incremento;
}
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
meuVector meuVector
buffer: buffer:
nElems: 4 nElems: 3
capMaxima: 5 capMaxima: 5
incremento: 3 incremento: 3
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
meuVector meuVector
buffer: buffer:
nElems: 3 nElems: 3
capMaxima: 5 capMaxima: 5
incremento: 3 incremento: 3
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
meuVector meuVector
buffer: buffer:
nElems: 3 nElems: 3
capMaxima: 5 capMaxima: 5
incremento: 3 incremento: 3
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
// implementar UMA das duas
// idx é o índice do elemento a remover
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
meuVector meuVector
buffer: buffer:
nElems: 4 nElems: 3
capMaxima: 5 capMaxima: 5
incremento: 3 incremento: 3
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Inserir no meio
Inserir no início
Igual a inserir no meio
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
meuVector meuVector
buffer: buffer:
nElems: 4 nElems: 5
capMaxima: 5 capMaxima: 5
incremento: 3 incremento: 3
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
if( estaCheio() )
aumentar( );
buffer[ idx ] = x;
nElems++;
}
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Procura de elementos
Devolver o índice da primeira ocorrência de um dado
elemento
Devolver o índice da primeira ocorrência de um dado
elemento após uma dada posição (procura próximo)
Devolver o índice da última ocorrência de um dado
elemento
Devolver o índice da última ocorrência de um dado
elemento antes de uma dada posição (procura
anterior)
Saber apenas se um elemento está presente no
vector
Saber quantas ocorrências de um elemento existem
no vector
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
class Vector {
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
}
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
}
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Redimensionar o vector
Para reservar logo todo o espaço que se sabe vai ser
ocupado
Evitando assim perda de tempo por realocações sucessivas
nos aumentos do vector
class Vector {
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
class Vector {
}
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Criação de sub-vectores
Entende-se por isto retornar um subvector com
elementos que pertencem ao vector
Cria-se um vector com os elementos desde um índice
inicial até ao índice final
Por norma o índice inicial é incluído mas o final não
Exemplo dos elementos 2 a 5 eram incluídos os
elementos 2, 3 e 4
A razão para isto vai ser dada quando se falarem de
iteradores
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Criação de sub-vectores
Entende-se por isto retornar um subvector com
elementos que pertencem ao vector
Cria-se um vector com os elementos desde um índice
inicial até ao índice final
class Vector {
return sub;
}
}
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Ordenação de vectores
Basta aplicar um dos algoritmos de ordenação
existentes
class Vector {
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Comparação de vectores
Um vector pode ser comparado com outro
Considera-se um vector igual a outro se:
Tiverem o mesmo tamanho
Tiverem em cada posição os mesmos elementos
Considera-se um vector menor que outro
Se na primeira posição em que são diferentes o elemento no
vector for menor que o elemento no outro vector
Se terminar primeiro com todos os elementos iguais até ai
Vectores dinâmicos
2007/08
A.E.D.
F.S.B.
Comparação de vectores
class Vector {
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Listas ligadas
2007/08
A.E.D.
F.S.B.
Chave: identifica o
conteúdo do nó
O último nó (ou
12 22 41 67
cabeça * cauda) tem a
referência a null
Conteúdo ou dados: a
Cabeça: indica qual é Referência para o nó informação que se
o 1º nó da lista seguinte pretende armazenar
(onde ela começa)
Listas ligadas
2007/08
A.E.D.
F.S.B.
Listas ligadas
2007/08
A.E.D.
F.S.B.
Conteúdo do nó
class Lista {
public ListaElemento( ){
cabeca = null;
nElementos = 0;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Listas ligadas
2007/08
A.E.D.
F.S.B.
1º passo 3º passo
Cabeça *
*
2º passo 4º passo
*
Cabeça *
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça *
* * Cabeça *
Listas ligadas
2007/08
A.E.D.
F.S.B.
private class No {
No( Object e ) {
item = e; // o item passa a ser o elemento
prox = null; // o nó é inicializado com
// prox a null (não há próximo)
}
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
novoNo.prox = cabeca;
cabeca = novoNo;
nElementos++;
}
aLista.inserirCabeca( umElemento );
Listas ligadas
2007/08
A.E.D.
F.S.B.
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça * *
ultimo
Cabeça * *
ultimo
Cabeça * *
ultimo
Cabeça *
ultimo
Listas ligadas
2007/08
A.E.D.
F.S.B.
Antes Depois
Cabeça Cabeça *
*
Listas ligadas
2007/08
A.E.D.
F.S.B.
No ultimo = cabeca;
while( ultimo.prox != null )
ultimo = ultimo.prox;
ultimo.prox = novoNo;
nElementos++;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça *
Cabeça *
anterior actual
Cabeça anterior actual
*
anterior actual
Cabeça *
anterior actual
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça * Cabeça *
anterior actual anterior actual
*
Antes Depois
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça * Cabeça
anterior actual
null
Cabeça *
anterior actual
anterior actual
Cabeça * *
anteriornull
Antes actual Depois
Listas ligadas
2007/08
A.E.D.
F.S.B.
Antes Depois
Listas ligadas
2007/08
A.E.D.
F.S.B.
novoNo.prox = actual;
if( anterior == null )
cabeca = novoNo;
else
anterior.prox = novoNo;
nElementos++;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça Cabeça *
*
anterior actual
anterior actual
Cabeça *
anterior actual
Listas ligadas
2007/08
A.E.D.
F.S.B.
int posActual = 0;
No actual = cabeca;
No anterior = null;
novoNo.prox = actual;
if( anterior == null )
cabeca = novoNo;
else
anterior.prox = novoNo;
nElementos++;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça *
actual É diferente do procurado logo passa ao próximo
Cabeça *
actual É diferente do procurado logo passa ao próximo
Cabeça *
actual É igual ao procurado logo pára
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça *
No actual = cabeca;
int pos = 0;
while( actual != null && actual.item.compareTo( e ) < 0 ) {
actual = actual.prox;
pos++;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça *
anterior
actual
Cabeça *
1º passo
anterior actual
Cabeça *
anterior actual
Cabeça * 2º passo
anterior actual
Cabeça *
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça *
anterior
actual
Cabeça * 1º passo
anterior actual
Cabeça *
anterior actual
Cabeça * * 2º passo
anterior actual
Cabeça *
Listas ligadas
2007/08
A.E.D.
F.S.B.
1º passo Cabeça *
anterior
actual
2º passo Cabeça *
actual
3º passo Cabeça *
Listas ligadas
2007/08
A.E.D.
F.S.B.
1º passo Cabeça *
anterior
actual
Cabeça null
Listas ligadas
2007/08
A.E.D.
F.S.B.
Remover o último
Igual a remover no início
Funcionamento idêntico porque o próximo do actual é null
Listas ligadas
2007/08
A.E.D.
F.S.B.
No actual = cabeca;
No anterior = null;
int pos = 0;
nElementos--;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
1 Cabeça * 5 Cabeça *
anterior actual anterior actual
2 Cabeça * 6 Cabeça *
anterior actual anterior actual
3 Cabeça * 7 Cabeça
anterior actual
Listas ligadas
2007/08
A.E.D.
F.S.B.
Listas ligadas
2007/08
A.E.D.
F.S.B.
Procura de elementos
Devolver o índice da primeira ocorrência de um dado
elemento (já feito)
Devolver o índice da primeira ocorrência de um dado
elemento após uma dada posição (procura próximo)
Devolver o índice da última ocorrência de um dado
elemento
Devolver o índice da última ocorrência de um dado
elemento antes de uma dada posição (procura
anterior)
Saber apenas se um elemento está presente na lista
Saber quantas ocorrências de um elemento existem
Listas ligadas
2007/08
A.E.D.
F.S.B.
class ListaElemento {
Listas ligadas
2007/08
A.E.D.
F.S.B.
No actual = cabeca;
int pos = 0;
Listas ligadas
2007/08
A.E.D.
F.S.B.
No actual = cabeca;
int pos = 0;
int ultimaPos = -1;
return ultimaPos;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Listas ligadas
2007/08
A.E.D.
F.S.B.
No actual = cabeca;
int pos = 0;
while( actual != null && pos < idx ) {
pos++;
actual = actual.prox;
}
return actual.item;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Alterar um elemento
Para poder actualizar o seu conteúdo
No actual = cabeca;
int pos = 0;
while( actual != null && pos < idx ) {
pos++;
actual = actual.prox;
}
Object antigo = actual.item;
actual.item = e;
return antigo;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Criação de sub-listas
Pegando na lista original devolver uma sub-lista
public Lista subLista( int ini, int fim ) {
Lista res = new ListaElemento();
No actual = cabeca;
int pos = 0;
// percorrer até à posição inicial
while( actual != null && pos < ini ) {
pos++;
actual = actual.prox;
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Inserção de sublistas
Inserir uma lista completa dentro de outra lista
Exemplo na posição 2
Deslocar na lista original
Cabeça *
até à posição de inserção
anterior actual
anterior actual
Cabeça
ultimo
Listas ligadas
2007/08
A.E.D.
F.S.B.
Inserção de sublistas
Inserir uma lista completa dentro de outra lista
Exemplo na posição 2
Cuidado, a segunda Lista ficou alterada!!!
Cabeça *
Cabeça
Listas ligadas
2007/08
A.E.D.
F.S.B.
Inserção de sublistas
Inserir uma lista completa dentro de outra lista
Atenção:
A solução anterior implica que a lista que foi inserida não
pode mais ser utilizada!
Uma solução melhor seria a inserção copiar o conteúdo da
lista a inserir e não a própria lista
Isto leva à necessidade de ter um método para
criar uma cópia de uma lista
Listas ligadas
2007/08
A.E.D.
F.S.B.
Ordenar listas:
Como o acesso a um elemento pode ser demorado os
algoritmos estudados tornam-se demasiado ineficazes
Quase nunca se ordenam listas
Estas devem ser preenchidas de forma ordenada
Caso seja necessário cria-se uma lista ordenada a partir de
uma desordenada
Listas ligadas
2007/08
A.E.D.
F.S.B.
Comparar listas:
Duas listas são iguais se tiverem o mesmo
comprimento e em cada nó os elementos são iguais
Fazer as funções de comparação como nos vectores
public int compareTo( Lista outra ) {
No actualA = cabeca;
No actualB = outra.cabeca;
while( actualA != null && actualB != null &&
actualA.item.equals(actualB.item )
){
actualA = actualA.prox;
actualB = actualB.prox;
}
if( actualA == null && actualB == null )
return 0;
if( actualA == null ) // A terminou logo A é menor
return -1;
if( actualB == null ) // B terminou, logo A é maior
return 1;
return actualA.item.compareTo( actualB.item );
}
Listas ligadas
2007/08
A.E.D.
F.S.B.
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça *
Cabeça * *
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça
Listas ligadas
2007/08
A.E.D.
F.S.B.
Cabeça * *
Cauda
Cabeça *
Cauda
Cabeça *
Listas ligadas
2007/08
A.E.D.
F.S.B.
cauda = novoNo;
nElementos++;
}
Pilha - stack
2007/08
A.E.D.
F.S.B.
Pilha - stack
2007/08
A.E.D.
F.S.B.
interface Pilha {
public void push( Object novo );
public Object pop( );
boolean estaVazia( );
boolean estaCheia( );
}
Pilha - stack
2007/08
A.E.D.
F.S.B.
Fila - queue
2007/08
A.E.D.
F.S.B.
Fila
Fila - queue
2007/08
A.E.D.
F.S.B.
interface FilaElemento {
public void enqueue( Object novo );
public Object dequeue( );
boolean estaVazia( );
boolean estaCheia( );
}
Fila - queue
2007/08
A.E.D.
F.S.B.
public Queue( ) {}
}
Árvores
2007/08
A.E.D.
F.S.B.
** *
Árvores
2007/08
A.E.D.
F.S.B.
chave
Raiz
Ancestral de Pai de
** *
Árvores
2007/08
A.E.D.
F.S.B.
Nó interno Nó de grau 3
** *
1
** *
2
** *** *** *** *** ***
3
***
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvore Binária
esquerdo direito
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
public ArvBin( ) { … }
private class No {
int chave; // elemento opcional
Object oItem;
No esq;
No dir;
No pai;
Árvores binárias
2007/08
A.E.D.
F.S.B.
ArvBin( ) {
nElems = 0;
raiz = null;
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
public ArvBinInt( ) { … }
private class No {
// reparar que não tem chave
int oElemento;
No esq;
No dir;
No pai;
Raiz
20
18 28
*
10 20 25
*
5 15 19 21 27
* * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz Raiz
20 20
* * *
28 28
* * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz Raiz
20 20
* * *
18 18
* * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
No actual = raiz;
Árvores binárias
2007/08
A.E.D.
F.S.B.
lado esquerdo
18 28
*
anterior
10 20 25
actual * * *
5 15 21
* * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
lado esquerdo
18 28
*
10 anterior 20 25
* *
5 15 19 21
* * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
18 28
Como 27 é maior que 25 *
segue para a direita
27 anterior
10 20 25
* * actual
* *
Como actual é
5 15 19 21 zero pára
* *
Árvores binárias
2007/08
A.E.D.
F.S.B.
5 15 19 21 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
novoNo.pai = anterior;
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz Raiz
20 20
* * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
novoNo.pai = anterior;
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
Procurar o elemento 20
18 28
*
10 20 25
*
5 15 19 21 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Procurar o elemento 10
Raiz
Como 10 é menor que 20
segue para a esquerda 20
Como 10 é menor que 18
segue para a esquerda
18 28
Como 10 é igual a 10 retorna
um iterador com o actual *
actual
10 20 25
*
5 15 19 21 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Procurar o elemento 21
Raiz
Como 21 é maior que 20
segue para a direita 20
Como 21 é menor que 28
segue para a esquerda
18 28
*
Árvores binárias
2007/08
A.E.D.
F.S.B.
Procurar o elemento 30
Raiz
Como 30 é maior que 20
segue para a direita 20
Como 30 é maior que 28
segue para a direita
18 28
*
actual
10 20 25 Como actual é null pára e
* devolve um iterador com o
nó a null (não encontrou)
5 15 19 21 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
Raiz
5
18 *
10
*
15
10 20 *
* 18
*
5 15 19 19 20
* * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
20
18 28
*
10 20 25
*
menor
5 15 19 21 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
IteratorBidirec menor( ) {
No actual = raiz;
if( raiz == null )
return new IteratorArvBinInt( null );
IteratorBidirec inicio( ){
return menor();
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
20
maior
18 28
*
10 20 25
*
5 15 19 21 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
IteratorBidirec maior( ){
No actual = raiz;
if( raiz == null )
return new IteratorArvBinInt( null );
IteratorBidirec fim( ){
return maior( );
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
22
18 28
*
10 20 25
*
Seguinte
5 15 19 23 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
22
Seguinte
18 28
*
10 20 25
*
5 15 19 23 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
No actual = iter.oNo;
No ancestral = actual.pai;
while( ancestral != null && ancestral.dir == actual ) {
actual = ancestral;
ancestral = ancestral.pai;
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
22
18 28
Anterior *
10 20 25
*
5 15 19 23 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
Anterior
22
18 28
*
10 20 25
* *
5 15 19 27
* * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
No actual = iter.oNo;
No ancestral = actual.pai;
while( ancestral != null && ancestral.esq == actual ) {
actual = ancestral;
ancestral = ancestral.pai;
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
depois antes 22
18 28
*
10 10 20 25
* *
5 15 5 15 19 23 27
* * * * * * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
22 22
Actual 28
*
18 28
* 25
10 20 25
23 27
*
* * * *
5 15 19 23 27
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
Depois Antes 22
Actual Actual
19 18 25
20 10 20 23 27
Sucessor * Sucessor * * * * *
19 5 15 19
* * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
10 20 23 27
Sucessor * * * * * *
5 15 19
* * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
Depois Antes
Actual Actual 22
19 18 25
21 10 21 23 27
Sucessor * Sucessor * * * * *
19 5 15 19
* * * * * *
20 20
* * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
19 19 25
21 10 21 23 27
Sucessor * * * * * *
19 5 15 20
* * * * * * *
20
* *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Eliminar a raiz
Igual a eliminar um nó qualquer com dois pormenores:
É necessário alterar o ponteiro da raiz
O Pai da raiz aponta para null
Eliminar o último
Igual a eliminar a raiz
Árvores binárias
2007/08
A.E.D.
F.S.B.
pai = aApagar.pai;
if( filho != null ) filho.pai = pai;
Árvores binárias
2007/08
A.E.D.
F.S.B.
Variáveis:
actual é o nó que contém o elemento a apagar
aApagar é o nó que vai ser libertado
filho é o filho do nó que vai ser libertado
pai é o pai do nó que vai ser libertado
Árvores binárias
2007/08
A.E.D.
F.S.B.
se ao nó actual falta pelo menos um filho é este o nó que vai ser libertado
senão o nó a apagar é o seu sucessor (ver exemplos)
pai = aApagar.pai;
if( filho != null ) filho.pai = pai;
Determinar o Pai do nó a libertar (se nó a apagar for a raiz, pai fica a null)
se houver um Filho actualiza-se o ponteiro Pai deste
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Sucessor e Predecessor:
Estas não se prestam a serem recursivas uma vez
que a solução não pode ser dividida em casos
semelhantes
Árvores binárias
2007/08
A.E.D.
F.S.B.
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
Eliminar uma árvore: 22
Eliminar primeiro a
sub-árvore esquerda 18 28
*
10 20 25
*
5 15 19 23 27
* * * * * * * * * *
Depois eliminar a
Eliminar uma árvore: sub-árvore direita
Raiz
Raiz Raiz Raiz
18
10 15 10
* * * **
10 20
5 15 5 15
eliminar a raiz
*
* * * * * * * *
Depois eliminar a 5 15 19
eliminar a raiz
sub-árvore direita * * * * * *
Raiz Raiz Raiz Raiz
eliminar a raiz
20 19 20 18
* * * ** * *
19 19 20
10
* * * *
Eliminar primeiro a 5 15 19
eliminar a raiz eliminar a raiz
sub-árvore esquerda * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
Raiz
Depois eliminar a
22 sub-árvore direita
18 28
* * *
10 20 25
** * *
5 15 19 23 27
* * * * * * * * * *
e etc ...
Árvores binárias
2007/08
A.E.D.
F.S.B.
limpar( no.esq );
limpar( no.dir );
no = null;
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
22 Raiz
18 28
*
10 20 25
* Listagem:
27 5 10 15 18 19 20 22 23 25 27 28
5 15 19 23
* * * * * * * * * *
Árvores binárias
2007/08
A.E.D.
F.S.B.
listarOrdem( no.esq );
System.out.println( no.oElemento );
listarOrdem( no.dir );
}
Árvores binárias
2007/08
A.E.D.
F.S.B.
Pós-ordem
Processa-se o nó depois dos filhos
Para cada nó imprimir o valor dos filhos
Árvores binárias
2007/08
A.E.D.
F.S.B.
10 20 25
Listagem pós-ordem:
*
5 15 10 19 20 18 23 27 25 28 22
5 15 19 23 27
* * * * * * * * * *
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
2 * 4
5 * 5
3
4 6 6
8 * 7
7
8 8
2007/08
A.E.D.
F.S.B. Tabelas de Hash – Endereçamento directo
As operações de inserção, procura e eliminação
são assim extremamente rápidas
Só dão para tabelas em que se sabe à partida
quantos elementos podem existir
Só dão para números de elementos
relativamente pequenos
2007/08
A.E.D.
F.S.B. Tabelas de Hash – Endereçamento directo
Classe para representar uma tabela de hash
com endereçamento directo
Como se vai ver, nestes casos, não é necessário
guardar a chave junto com o elemento
Para simplificar vai-se usar chaves inteiras
class TabelaHash {
2007/08
A.E.D.
F.S.B. Tabelas de Hash – Endereçamento directo
Criar uma tabela
É necessário indicar o número de posições
class TabelaHash {
2007/08
A.E.D.
F.S.B. Tabelas de Hash – Endereçamento directo
Procurar na tabela
É necessário indicar a chave a procurar
A procura é directa!
2007/08
A.E.D.
F.S.B. Tabelas de Hash – Endereçamento directo
Limpar a tabela
void limpar( ) {
}
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Tabela de hash
Elementos possíveis
0 13 Hash1( 13 ) = 0
1 1 Hash1( 1 ) = 1
2 28 Hash1( 28 ) = 2
54 2
20 50 1 3 3 Hash1( 3 ) = 3
17 3 * 4
31
6 * 5
0 22
8 6 6 Hash1( 6 ) = 6
32
43 * 7
5 13
8 8 Hash1( 8 ) = 8
4 28
* 9
7 23
* 10
* 11
* 12
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Tabela de hash
Elementos possíveis
0 Métodos
e * 1
de 2 Ambientes
Micro 3 Computação
Desenho
Métodos 4 Programação
Gráfica
Computação 5 Micro
Análise
Ambientes * 6
Matemática Programação Hash2( “Métodos” ) = 0
Hash2( “Ambientes” ) = 2
Disciplina
Hash2( “Computação” ) = 3
Hash2( “Programação” ) = 4
Hash2( “Micro” ) = 5
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
As funções de hashing:
Devem ser rápidas
Devem evitar ao máximo as colisões:
Cada posição da tabela deve ter a mesma probabilidade de
ser escolhida
A escolha de uma dada função de hashing não é pois
uma decisão directa
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
2007/08
A.E.D.
F.S.B.
Tabelas de Hash – inserção à cabeça
Para o exemplo seguinte vai-se usar a função
Hash1( x ) = x % 13
Tabela de hash
Elementos possíveis
* 0
1 14 1 *
2
54 * 2
20 50 1 3 3 *
17 3 * 4
31
6 * 5
0 22
8 6 19 6 *
32
43 * 7
5 14
8 8 *
4 19
* 9
7 23
* 10
* 11
* 12
2007/08
A.E.D.
F.S.B.
Tabelas de Hash – inserção ordenada
Para o exemplo seguinte vai-se usar a função
Hash1( x ) = x % 13
Tabela de hash
Elementos possíveis
* 0
1 1 14 *
2
54 * 2
20 50 1 3 3 *
17 3 * 4
31
6 * 5
0 22
8 6 6 19 *
32
43 * 7
5 14
8 8 *
4 19
* 9
7 23
* 10
* 11
* 12
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
class TabelaAuto {
class ListaAuto {
private class No {
String chave; // matricula
Automovel oAuto;
No prox;
}
}
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
class TabelaAuto {
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Inserir na tabela
É necessário indicar o elemento e a chave
A inserção demora um tempo constante se for à
cabeça
Se for ordenada varia de acordo com a ocupação da
lista
public boolean inserir( String chave, Automovel oAuto ) {
Função de hash
É necessário criar uma função para fazer o hashing
da matricula
Seria necessário testar várias funções para ver qual
daria os melhores resultados
long resultado = 0;
// vêem-se 6 caracteres
for( int i = 0; i < 6 && i < chave.length(); i++ )
resultado = resultado * 32 + chave.charAt( i );
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Procurar na tabela
É necessário indicar a chave a procurar
A procura demora o tempo de procura numa lista
Melhores resultados se for inserção ordenada
Eliminar da tabela
É necessário indicar a chave a eliminar
A eliminação demora o tempo de eliminação de uma
lista
Melhores resultados se for inserção ordenada (por causa da
pesquisa do elemento)
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Destruir a tabela
}
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Usar a tabela
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Usar a tabela
int lerFicheiro( String nomefich, TabelaAuto carros ) {
// abertura do ficheiro …
while( temInput )
{
// ler dados do carro
Automovel carro = new Automovel();
carro.setMatricula( … );
carro.setProprietario( … );
return nAutos;
}
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Usar a tabela
String matricula;
Automovel carro;
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Usar a tabela
int lerFicheiro( String nomefich, TabelaAuto carros ) {
int nAutos=0;
while( temInput ) {
nAutos++;
}
return nAutos;
}
Tabelas de Hash
2007/08
A.E.D.
F.S.B.
Usar a tabela