Logo Passei Direto

A maior rede de estudos do Brasil

Grátis
259 pág.
apostila

Pré-visualização | Página 32 de 50

10.18) 10 100 10000 100000000
Busca bina´ria (fig. 10.20) 3 5 10 19
Figura 10.19: Tabela resumindo nu´mero de comparac¸o˜es para algoritmos de busca.
10.1. VETORES 143
function busca (x: real ; var v: vetor r ; n: integer) : integer ;
var inicio , fim , meio: integer ;
begin
inicio :=1; (∗ aponta para o inicio do vetor ∗)
fim:= n; (∗ aponta para o fim do vetor ∗)
meio:= ( inicio + fim) div 2; (∗ aponta para o meio do vetor ∗)
while (v[meio] <> x) and (fim >= inicio ) do
begin
if v[meio] > x then (∗ vai jogar uma das duas metades fora ∗)
fim:= meio − 1 (∗ metade superior foi jogada fora ∗)
else
inicio:= meio + 1;(∗ metade inferior foi jogada fora ∗)
meio:= ( inicio + fim) div 2; (∗ recalcula apontador para meio ∗)
end;
(∗ o laco termina quando achou ou quando o fim ficou antes do inicio ∗)
i f v[meio] = x then
busca:= meio
else
busca:= 0;
end;
Figura 10.20: Busca bina´ria.
O importante do me´todo da busca bina´ria e´ que ela apresenta um cara´ter lo-
gar´ıtmico para o pior caso com relac¸a˜o ao tamanho da entrada, o que e´ bastante
significativo. Contudo, e´ absolutamente relevante destacar que este me´todo so´ pode
ser aplicado em vetores ordenados, sena˜o na˜o funciona. A questa˜o e´ saber qual o
custo de se ordenar, ou de se manter ordenado, um vetor. Isto sera´ estudado a` frente.
Manipulando vetores ordenados
Quando operac¸o˜es de inserc¸a˜o e remoc¸a˜o sa˜o feitas em vetores ordenados e´ impor-
tante que estas alterac¸o˜es em seus elementos preservem a propriedade do vetor estar
ordenado, por exemplo, para que se possa usar uma busca bina´ria.
A seguir apresentamos soluc¸o˜es para se remover ou inserir um elemento de um
vetor, iniciando pela remoc¸a˜o. O procedimento da figura 10.21 garante a remoc¸a˜o do
elemento que esta´ na posic¸a˜o pos do vetor v que tem tamanho n.
procedure remove (pos : integer ; var v: vetor r ; var n: integer) ;
var i : integer ;
begin
for i := pos to n−1 do
v[ i ]:= v[ i +1];
n:= n − 1;
end;
Figura 10.21: Removendo de um vetor ordenado.
144 CAPI´TULO 10. ESTRUTURAS DE DADOS
Remover elementos na˜o e´ ta˜o trivial quanto parece, pois na˜o podemos deixar
“buracos” no vetor. Este algoritmo enta˜o copia todos os elementos que esta˜o a` frente
daquele que foi removido uma posic¸a˜o para tra´s. Tomemos como exemplo o seguinte
vetor ordenado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 . . . 197 198 199 200
0 2 7 12 15 18 19 21 23 27 ? ? ? ? ? . . . ? ? ? ?
Para remover o elemento 12, que esta´ na posic¸a˜o 4, todos os outros sa˜o copiados,
um por um. Para na˜o perdermos elementos, este processo tem que iniciar da posic¸a˜o
onde houve a remoc¸a˜o ate´ a penu´ltima posic¸a˜o. O vetor resultante e´ o seguinte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 . . . 197 198 199 200
0 2 7 15 18 19 21 23 27 27 ? ? ? ? ? . . . ? ? ? ?
O detalhe e´ que o elemento 27 que estava na posic¸a˜o 10 continua la´, mas, como o
vetor agora tem tamanho 9 (pois um elemento foi removido) este u´ltimo 27 agora e´
lixo de memo´ria.
Com relac¸a˜o ao algoritmo de inserc¸a˜o de um elemento em um vetor ordenado,
deve-se primeiro determinar a posic¸a˜o correta de inserc¸a˜o, logo, um processo de busca
deve ser feito, iniciando do comec¸o do vetor (posic¸a˜o 1) ate´ que seja encontrado um
elemento maior que aquele que esta´ se inserindo. Para facilitar esta busca, usamos
uma sentinela.
Tomemos novamente como exemplo o vetor abaixo e consideremos que vamos
inserir o elemento 17.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 . . . 197 198 199 200
0 2 7 12 15 18 19 21 23 27 ? ? ? ? ? . . . ? ? ? ?
A posic¸a˜o correta do 17 e´ logo apo´s o elemento 15, isto e´, na posic¸a˜o 6. Para
abrirmos espac¸o no vetor e ao mesmo tempo na˜o perdermos o 18 que la´ esta´ devemos
copiar todos os elementos, um por um, uma posic¸a˜o para frente. Isto deve ser feito
de tra´s para frente, isto e´, copia-se o u´ltimo uma posic¸a˜o adiante para abrir espac¸o
para colocar o penu´ltimo, e assim por diante. O resultado seria um vetor assim:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 . . . 197 198 199 200
0 2 7 12 15 18 18 19 21 23 27 ? ? ? ? . . . ? ? ? ?
Observe que agora temos duas vezes o 18 no vetor. O primeiro deles agora pode
ser substitu´ıdo pelo novo elemento, o 17, assim:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 . . . 197 198 199 200
0 2 7 12 15 17 18 19 21 23 27 ? ? ? ? . . . ? ? ? ?
10.1. VETORES 145
procedure insere (x: real ; var v: vetor r ; var n: integer) ;
var i : integer ;
begin
v[0]:= x;
i:= n + 1;
while x < v[ i ] do
begin
v[ i+1]:= v[ i ] ;
i := i − 1;
end;
n:= n + 1;
end;
Figura 10.22: Inserindo em um vetor ordenado.
O procedimento da figura 10.22 insere um elemento x no vetor v que tem tamanho
n de maneira que ele continue ordenado. Apenas uma passagem no vetor e´ feita: ao
mesmo tempo em que ele esta´ procurando a posic¸a˜o correta do elemento ele ja´ vai
abrindo espac¸o no vetor.
No caso de vetores na˜o ordenados, os processo de inserc¸a˜o e remoc¸a˜o sa˜o mais
simples. Pode-se sempre inserir um elemento novo no final do vetor e para remover,
basta copiar o u´ltimo sobre o que foi removido.
Ha´ um u´ltimo algoritmo interessante que trabalha com vetores ordenados: a ideia
e´ fundir3 dois vetores ordenados em um terceiro, obtendo-se um vetor ordenado como
resultado contendo os mesmos elementos dos vetores anteriores.
O princ´ıpio deste algoritmo e´: atribui-se a duas varia´veis i e j o ı´ndice 1. Em
seguida se compara os respectivos elementos das posic¸o˜es i em um vetor e j no outro.
Se o elemento do primeiro vetor e´ menor do que o do segundo, ele e´ copiado no terceiro
vetor e o apontador i e´ incrementado de 1, passando a observar o pro´ximo elemento.
Sena˜o, o elemento do segundo vetor e´ menor e portanto este que e´ copiado para o
terceiro vetor e o apontador j que e´ incrementado. Quando um dos dois vetores
acabar, basta copiar o restante do outro no terceiro vetor. Um apontador k controla
o terceiro vetor. Este e´ sempre incrementado a cada co´pia.
Vejamos isto atrave´s de um exemplo. Consideremos os seguintes dois vetores
ordenados e um terceiro que vai receber a fusa˜o dos dois.
i=1 2 3 4 5
v: 2 4 5 7 9
j=1 2 3
w: 1 3 6
k=1 2 3 4 5 6 7 8
r:
3Em ingleˆs, merge
146 CAPI´TULO 10. ESTRUTURAS DE DADOS
comparam-se o elementos apontados por i e j. Como 1 < 2, copia-se o 1 no vetor r e
incrementa-se o apontador j, assim:
i=1 2 3 4 5
v: 2 4 5 7 9
1 j=2 3
w: 1 3 6
1 k=2 3 4 5 6 7 8
r: 1
Agora comparam-se o elementos apontados por i e j. Como 2 < 3, copia-se o 2 no
vetor r e incrementa-se o apontador i, assim:
1 i=2 3 4 5
v: 2 4 5 7 9
1 j=2 3
w: 1 3 6
1 2 k=3 4 5 6 7 8
r: 1 2
Repetindo-se este processo mais algumas vezes chegaremos no seguinte estado:
1 2 3 i=4 5
v: 2 4 5 7 9
1 2 j=3
w: 1 3 6
1 2 3 4 k=5 6 7 8
r: 1 2 3 4 5
Neste ponto o 6 sera´ copiado em r e o vetor w termina. Basta copiar o que sobrou
de v e terminar o processo, o que resultara´ no seguinte:
1 2 3 4 5 i=6
v: 2 4 5 7 9
1 2 3 j=4
w: 1 3 6
1 2 3 4 5 6 7 8 k=9
r: 1 2 3 4 5 6 7 9
O algoritmo da figura 10.23 implementa o que foi discutido, e´ eficiente e varre os
dois vetores apenas uma vez.
10.1. VETORES 147
procedure merge (var v: vetor r ; n: integer ; var w: vetor r ; m: integer ; r : vetor r) ;
var i , j , k, l : integer ;
begin
i := 1; j:= 1; k:= 1;
(∗ i vai controlar os elementos de v ∗)
(∗ j vai controlar os elementos de w ∗)
(∗ k vai controlar os elementos do vetor resultante da fusao , r ∗)
while ( i <= n) and ( j <= m) do
begin
if v[ i ] <= w[ j ] then (∗ se o elemento de v dh menor que o de w ∗)
begin
r [k]:= v[ i ] ;
i := i + 1;
end
else (∗ o elemento de w eh menor que o de v ∗)
begin
r [k]:= w[ j ] ;
j:= j + 1;
end;
k:= k + 1; (∗ k eh sempre incrementado ∗)
end;
(∗ quando sai do laco , um dos dois vetores acabou ∗)
i f i <= n
Página1...282930313233343536...50