Você está na página 1de 25

Vetores

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

25 / 162

Vetores

Busca

Problema da busca
Dado x e vetor v[0 . . n1], encontrar um ndice k tal que v[k] = x.

987

0
n1
222 555 111 333 444 666 555 888 777 987 654

o problema faz sentido com qualquer n 0

se n = 0, o vetor vazio e essa instncia no tem soluo

como indicar que no h soluo?

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

26 / 162

Vetores

Busca

Problema da busca
Dado x e vetor v[0 . . n1], encontrar um ndice k tal que v[k] = x.

987

0
n1
222 555 111 333 444 666 555 888 777 987 654

o problema faz sentido com qualquer n 0

se n = 0, o vetor vazio e essa instncia no tem soluo

como indicar que no h soluo?

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

26 / 162

Vetores

Busca

Algoritmo de busca
Recebe um nmero x e um vetor v[0 . . n1] com n 0
e devolve k no intervalo 0 . . n1 tal que v[k] = x.
Se tal k no existe, devolve 1.

int Busca (int x, int v[], int n) {


int k;
k = n - 1;
while (k >= 0 && v[k] != x)
k -= 1;
return k;
}

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

27 / 162

Vetores

Busca

Deselegante e/ou ineficiente!


int k = n - 1, achou = 0;
while (k >= 0 && achou == 0) {
if (v[k] == x) achou = 1;
else k -= 1;
}
return k;

int k;
if (n == 0) return -1;
k = n - 1;
while (k >= 0 && v[k] != x) k -= 1;
return k;

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

28 / 162

Vetores

Busca

Deselegante e/ou ineficiente!


int k = n - 1, achou = 0;
while (k >= 0 && achou == 0) {
if (v[k] == x) achou = 1;
else k -= 1;
}
return k;

int k;
if (n == 0) return -1;
k = n - 1;
while (k >= 0 && v[k] != x) k -= 1;
return k;

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

28 / 162

Vetores

Busca

Deselegante, ineficiente e/ou errado!


int k = 0;
int sol = -1;
for (k = n-1; k >= 0; k--)
if (v[k] == x) sol = k;
return sol;
int k = n - 1;
while (v[k] != x && k >= 0)
k -= 1;
return k;

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

29 / 162

Vetores

Busca

Algoritmo recursivo de busca


Recebe x, v e n 0 e devolve k tal que 0 k < n e v[k] = x.
Se tal k no existe, devolve 1.

int BuscaR (int x, int v[], int n) {


if (n == 0) return -1;
if (x == v[n-1]) return n - 1;
return BuscaR (x, v, n - 1);
}

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

30 / 162

Vetores

Busca

Deselegante!
int feio (int x, int v[], int n) {
if (n == 1) {
if (x == v[0]) return 0;
else return -1;
}
if (x == v[n-1]) return n - 1;
return feio (x, v, n - 1);
}

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

31 / 162

Vetores

Remoo

Problema de remoo
Remover o elemento de ndice k de um vetor v[0 . . n1].
Decises de projeto:

suporemos 0 k n 1

novo vetor fica em v[0 . . n2]

algoritmo devolve algo?

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

32 / 162

Vetores

Remoo

Problema de remoo
Remover o elemento de ndice k de um vetor v[0 . . n1].
Decises de projeto:

suporemos 0 k n 1

novo vetor fica em v[0 . . n2]

algoritmo devolve algo?

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

32 / 162

Vetores

Remoo

Algoritmo de remoo
Remove o elemento de ndice k do vetor v[0 . . n1]
e devolve o novo valor de n. Supe 0 k < n.

int Remove (int k, int v[], int n) {


int j;
for (j = k; j < n-1; j++)
v[j] = v[j+1];
return n - 1;
}

funciona bem mesmo quando k = n 1 ou k = 0

exemplo de uso:

P. Feofiloff (IME-USP)

n = Remove (51, v, n);

Algoritmos em C

Campus/Elsevier

33 / 162

Vetores

Remoo

Algoritmo de remoo
Remove o elemento de ndice k do vetor v[0 . . n1]
e devolve o novo valor de n. Supe 0 k < n.

int Remove (int k, int v[], int n) {


int j;
for (j = k; j < n-1; j++)
v[j] = v[j+1];
return n - 1;
}

funciona bem mesmo quando k = n 1 ou k = 0

exemplo de uso:

P. Feofiloff (IME-USP)

n = Remove (51, v, n);

Algoritmos em C

Campus/Elsevier

33 / 162

Vetores

Remoo

Verso recursiva
int RemoveR (int k, int v[], int n) {
if (k == n-1) return n - 1;
else {
v[k] = v[k+1];
return RemoveR (k + 1, v, n);
}
}

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

34 / 162

Vetores

Insero

Problema de insero
Inserir um novo elemento y entre as posies k 1 e k
de um vetor v[0 . . n1].
Decises de projeto:

se k = 0 ento insere no incio

se k = n ento insere no fim

novo vetor fica em v[0 . . n+1]

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

35 / 162

Vetores

Insero

Problema de insero
Inserir um novo elemento y entre as posies k 1 e k
de um vetor v[0 . . n1].
Decises de projeto:

se k = 0 ento insere no incio

se k = n ento insere no fim

novo vetor fica em v[0 . . n+1]

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

35 / 162

Vetores

Insero

Algoritmo de insero
Insere y entre as posies k 1 e k do vetor v[0 . . n1]
e devolve o novo valor de n. Supe que 0 k n.

int Insere (int k, int y, int v[], int n) {


int j;
for (j = n; j > k; j--)
v[j] = v[j-1];
v[k] = y;
return n + 1;
}

estamos supondo n < N

exemplo de uso:

P. Feofiloff (IME-USP)

n = Insere (51, 999, v, n);

Algoritmos em C

Campus/Elsevier

36 / 162

Vetores

Insero

Algoritmo de insero
Insere y entre as posies k 1 e k do vetor v[0 . . n1]
e devolve o novo valor de n. Supe que 0 k n.

int Insere (int k, int y, int v[], int n) {


int j;
for (j = n; j > k; j--)
v[j] = v[j-1];
v[k] = y;
return n + 1;
}

estamos supondo n < N

exemplo de uso:

P. Feofiloff (IME-USP)

n = Insere (51, 999, v, n);

Algoritmos em C

Campus/Elsevier

36 / 162

Vetores

Insero

Verso recursiva
int InsereR (int k, int y, int v[], int n) {
if (k == n) v[n] = y;
else {
v[n] = v[n-1];
InsereR (k, y, v, n - 1);
}
return n + 1;
}

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

37 / 162

Vetores

Busca seguida de remoo

Problema de busca-e-remoo
Remover todos os elementos nulos de um vetor v[0 . . n1].
Algoritmo
Remove todos os elementos nulos de v[0 . . n1],
deixa o resultado em v[0 . . i1], e devolve o valor de i.
int RemoveZeros (int v[], int n) {
int i = 0, j;
for (j = 0; j < n; j++)
if (v[j] != 0) {
v[i] = v[j];
i += 1;
}
return i;
}

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

38 / 162

Vetores

Busca seguida de remoo

Problema de busca-e-remoo
Remover todos os elementos nulos de um vetor v[0 . . n1].
Algoritmo
Remove todos os elementos nulos de v[0 . . n1],
deixa o resultado em v[0 . . i1], e devolve o valor de i.
int RemoveZeros (int v[], int n) {
int i = 0, j;
for (j = 0; j < n; j++)
if (v[j] != 0) {
v[i] = v[j];
i += 1;
}
return i;
}

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

38 / 162

Vetores

Busca seguida de remoo

Funciona bem mesmo em casos extremos:

quando n vale 0

quando v[0 . . n1] no tem zeros

quando v[0 . . n1] s tem zeros

Invariantes
No incio de cada iterao

ij

v[0 . . i1] o resultado da remoo dos zeros


do vetor v[0 . . j1] original

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

39 / 162

Vetores

Busca seguida de remoo

Funciona bem mesmo em casos extremos:

quando n vale 0

quando v[0 . . n1] no tem zeros

quando v[0 . . n1] s tem zeros

Invariantes
No incio de cada iterao

ij

v[0 . . i1] o resultado da remoo dos zeros


do vetor v[0 . . j1] original

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

39 / 162

Vetores

Busca seguida de remoo

Mau exemplo: deselegante e ineficiente


int i = 0, j = 0;
/* "j = 0" suprfluo */
while (i < n) {
if (v[i] != 0) i += 1;
else {
for (j = i; j+1 < n; j++) /* ineficiente */
v[j] = v[j+1];
/* ineficiente */
--n;
}
}
return n;

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

40 / 162

Vetores

Busca seguida de remoo

Verso recursiva
int RemoveZerosR (int v[], int n) {
int m;
if (n == 0) return 0;
m = RemoveZerosR (v, n - 1);
if (v[n-1] == 0) return m;
v[m] = v[n-1];
return m + 1;
}

P. Feofiloff (IME-USP)

Algoritmos em C

Campus/Elsevier

41 / 162

Você também pode gostar