Você está na página 1de 9

Estruturas de Dados e Algoritmos (C/C++) Aula 08 (Prof.

Slvio)

pag. 1

Aula 08 - Contedo
1)
2)
3)
4)

Algoritmos de Ordenao
Algoritmos de Busca
Implementaes destes algoritmos
Exerccios

Introduo
Estudaremos, neste tpico, os seguintes mtodos de classificao:
a) Classificao por troca
Buble Sort (mtodo bolha)
Quick Sort
b) Classificao por seleo
Selection Sort (mtodo da seleo)
c) Classificao por insero
Insertion Sort (mtodo da insero)
Shell Sort
d) Classificao por intercalao
Merge Array
Merge Sort
e) Classificao de Razes
Radix Sort
Para efeitos de explicao utilizaremos tanto nos mtodos de busca quanto nos
mtodos de ordenao, nos casos que assim permitirem, um vetor x de inteiros de
tamanho n, sendo que os ndices do vetor x assumiram valores entre 0 e n-1.
Obs.: apesar dos algoritmos implementados utilizarem um vetor, podemos
estender a lgica das classificaes tambm para arquivos.

Algoritmos de Ordenao
Classificao por Troca
Buble Sort (Mtodo Bolha arquivo Ex801.cpp)
A idia bsica do Buble Sort percorrer os dados do vetor (arquivo)
sequencialmente vrias vezes. Em cada passagem pelos dados devemos comparar
cada elemento com o seu sucessor (x[k] com x[k+1]). Se os elementos no estiverem
ordenados devemos troc-los de posio.
Exemplo:
Iterao 0: 25 57 48 37 12 92 86 33
Iterao 1: 25 48 37 12 57 86 33 92
Iterao 2: 25 37 12 48 57 33 86 92
Iterao 3: 25 12 37 48 33 57 86 92
Iterao 4: 12 25 37 33 48 57 86 92
Iterao 5: 12 25 33 37 48 57 86 92
Iterao 6: 12 25 33 37 48 57 86 92
Iterao 7: 12 25 33 37 48 57 86 92

Estruturas de Dados e Algoritmos (C/C++) Aula 08 (Prof. Slvio)

pag. 2

Note que na iterao 1 o maior elemento (92) est na posio correta, na


iterao 2 o elemento 86 est na posio correta e na iterao k o elemento x[n-k]
estar na posio correta. Podemos melhorar a rapidez deste algoritmos com a
seguinte alterao:
Iterao 1:
(n-1) comparaes
Iterao 2:
(n-2) comparaes
Iterao 3:
(n-3) comparaes
:
:
ltima Iterao:
1 comparao ( x[0] com x[1] )
Obs.: note que pode ocorrer dos dados estarem ordenados antes de se efetuar (n1) passagens pelo vetor
Algoritmo Buble Sort
void buble(int x[], int n)
{
int aux, j, passo, chave = 1;
for(passo=0; passo < n-1 && chave; passo++)
{
chave = 0;
for(j=0; j < n-passo-1; j++)
{
if ( x[j] > x[j+1] )
{
chave = 1;
aux = x[j];
x[j] = x[j+1];
x[j+1] = aux;
}
}
}
}

Quicksort (Mtodo Rpido arquivo Ex802.cpp)


Devemos escolher um elemento b qualquer do vetor x (por exemplo o 1
elemento - b=x[0] ) e baseado neste elemento devemos particionar x as seguinte
forma:
colocamos b na sua posio correta j
todos os elementos entre 0 e j-1 devem ser menores do que b ( x[j] )
todos os elementos entre j+1 e n devem ser maiores do que b ( x[j] )
Aps particionarmos o vetor devemos repetir o processo para os subvetores
entre x[0] at x[j-1] e x[j+1] at x[n-1] e assim sucessivamente.
Exemplo:
25 57 48 37 12 92 86 33
12 25 48 37 57 92 86 33
12 25 48 37 57 92 86 33
12 25 33 37 48 92 86 57
12 25 33 37 48 92 86 57
12 25 33 37 48 92 86 57
12 25 33 37 48 57 86 92
12 25 33 37 48 57 86 92
12 25 33 37 48 57 86 92
Algoritmo Quicksort

Estruturas de Dados e Algoritmos (C/C++) Aula 08 (Prof. Slvio)

pag. 3

void Particionar(int x[], int lb, int ub, int *pj)


{
int a, temp, down, up;
a = x[lb];
up = ub;
down = lb;
while ( down < up )
{
while ( x[down] <= a && down < ub ) down++;
while ( x[up] > a ) up--;
if ( down < up )
{
temp = x[down];
x[down] = x[up];
x[up] = temp;
}
}
x[lb] = x[up];
x[up] = a;
*pj = up;
}
void Quicksort(int x[], int lb, int ub)
{
int j;
if ( lb >= ub ) return;
Particionar(x,lb,ub,j);
Quicksort(x,lb,j-1);
Quicksort(x,j+1,ub);
}

Classificao por Seleo


Selection Sort (Mtodo da Seleo arquivo Ex803.cpp)
Este mtodo consiste em encontrar repetidamente o maior elemento do vetor x
(ou subvetor) e coloc-lo na sua devida posio.
Maior dos (n-1) elementos:
trocar com o n-simo elemento
Maior dos (n-2) elementos:
trocar com o (n-1)-simo elemento
:
:
Maior dos 2 ltimos elementos torcar com o segundo elemento
Exemplo:
Iterao 0:
Iterao 1:
Iterao 2:
Iterao 3:
Iterao 4:
Iterao 5:
Iterao 6:
Iterao 7:

25
25
25
25
25
25
25
12

57
57
57
33
33
33
12
25

48
48
48
48
12
12
33
33

Algoritmo Selection Sort


void selectSort(int x[], int n)
{
int i, indx, j, maior;
for(i=n-1; i > 0; i--)
{

37
37
37
37
37
37
37
37

12
12
12
12
48
48
48
48

92
33
33
57
57
57
57
57

86
86
86
86
86
86
86
86

33
92
92
92
92
92
92
92

Estruturas de Dados e Algoritmos (C/C++) Aula 08 (Prof. Slvio)

pag. 4

maior = x[0];
indx = 0;
for(j=1; j <= i; j++)
{
if ( x[j] > maior )
{
maior = x[j];
indx = j;
}
}
x[indx] = x[i];
x[i] = maior;
}
}

Classificao por Insero


Insertion Sort (Mtodo da Insero arquivo Ex804.cpp)
Neste mtodo devemos inserir os elementos nas suas posies corretas
utilizando o arquivo (vetor) original de dados. Em cada iterao tomamos um
elemento e o colocamos na sua posio correta deslocando os elemenstos que esto
em posies incorretas.
Exemplo:
Iterao 0:
Iterao 1:
Iterao 2:
Iterao 3:
Iterao 4:
Iterao 5:
Iterao 6:
Iterao 7:

25
25
25
25
12
12
12
12

57
57
48
37
25
25
25
25

48

37

12

92

86

33

57
48
37
37
37
33

57
48
48
48
37

57
57
57
48

92
86
57

92
86

92

Algoritmo Insertion Sort


void InsertSort(int x[], int n)
{
int i,k,y;
for(k=1; k<n; k++)
{
y = x[k];
for(i=k-1; i >= 0 && y < x[i]; i--)
x[i+1] = y;
}
}

x[i+1] = x[i];

Shell Sort (arquivo Ex805.cpp)


A classificao Shell ou classificao de incremento decrescente particiona o
arquivo (vetor) original em k subarquivos (subvetores) e depois classifica cada um
deles. Aps a ordenao dos k subarquivos, ser definido um novo valor de k (menor
que o anterior) e o processo de particionamento e classificao de subarquivos
continuar at o arquivo (vetor) original estar ordenado.
Exemplo:
Seja o arquivo (vetor) original abaixo:
x = (25 57 48 37 12 92 86 33)

Estruturas de Dados e Algoritmos (C/C++) Aula 08 (Prof. Slvio)

pag. 5

Considere a seqncia de incrementos k = (5, 3, 1)


Iterao 1 (k = 5) subarquivos (subvetores) abaixo
(25 92) (x[0] x[5]) => (25 92)
(57 86) (x[1] x[6]) => (57 86)
(48 33) (x[2] x[7]) => (33 48)
(37)
(x[3])
=> (37)
(12)
(x[4])
=> (12)
x = (25 57 33 37 12 92 86 48)

Iterao 2 (k = 3) subarquivos (subvetores) abaixo


(25 37 86) (x[0] x[3] x[6]) => (25 37 86)
(57 12 48) (x[1] x[4] x[7]) => (12 48 57)
(33 92)
(x[2] x[5])
=> (33 92)
x = (25 12 33 37 48 92 86 57)
Iterao 2 (k = 1) subarquivo (subvetor) abaixo
(25 12 33 37 48 92 86 57) (x[0] x[1] ... x[7])
x = (25 12 33 37 48 92 86 57)

Algoritmo Shell Sort


void ShellSort(int x[], int n, int incrmnts[], int numinc)
{
int incr,j,k,tam,y;
for(incr = 0; incr < numinc; incr++)
{
tam = incrmnts[incr];
for(j = tam; j < n; j++)
{
y = x[j];
for(k = j-tam; k >= 0 && y < x[k]; k -= tam)
x[k+tam]=x[k];
x[k+tam] = y;
}
}
}

Classificao por Intercalao


A classificao por intercalao tem como idia principal combinar dois ou
mais vetores (arquivos) classificados num outro vetor (arquivo) tambm classificado.
Merge Array (arquivo Ex806.cpp)
O mtodo abaixo toma dois vetores j ordenados a e b de tamanhos na e nb,
respectivamente, e monta um vetor c de tamanho nc (na+nb), tambm ordenado,
atravs da intercalao dos elementos de a e b.
Exemplo:
a = (5 7 10 15 20 25)
na = 6
b = (2 4 12 13 17 32 40) nb = 7
c = (2 4 5 7 10 12 13 15 17 20 25 32 40) nc = 13
Algoritmo Merge Array

Estruturas de Dados e Algoritmos (C/C++) Aula 08 (Prof. Slvio)

pag. 6

void MergeArr(int a[],int b[],int c[],int na,int nb,int nc)


{
int ap, bp, cp;
if ( nc != na+nb )
{
cout << tamanhos dos vetores incompatveis;
exit;
}
ap = bp = 0;
for(cp = 0; ap < na && bp < nb; cp++)
{
if ( a[ap] < b[bp] ) c[cp] = a[ap++];
else c[cp] = b[bp++];
}
while ( ap < na ) c[cp++] = a[ap++];
while ( bp < nb ) c[cp++] = b[bp++];
}

Merge Sort (arquivo Ex807.cpp)


Neste mtodo devemos dividir o vetor (arquivo) em n subvetores (subarquivos)
de tamanho 1 e intercalar pares de vetores adjacentes. Neste ponto teremos
aproximadamente n/2 vetores ordenados de tamanho 2. Devemos agora intercalar os
vetores adjacentes de tamanho 2 em vetores de tamanho 4. Teremos o vetor
totalmente ordenado se repetirmos este processo at obtermos um nico vetor de
tamano de n.
Exemplo:
Vetor original:
Iterao 1:
Iterao 2:
Iterao 3:

25
25
25
12

57
57
37
25

48
37
48
33

37
48
57
37

12
12
12
48

92
92
33
57

86
33
86
86

Algoritmo Merge Sort


#define NUMELEM 1000
void MergeSort(int x[], int n)
{
int aux[NUMELEM],i,j,k,a1,a2,u1,u2,tam;
tam = 1; //intercala subvetores de tamanho 1
while (tam < n )
{
a1 = k = 0;
while ((a1 + tam) < n )
{
a2 = a1 + tam;
u1 = a2 1;
u2 = (a2+tam-1 < n) ? a2+tam-1 : n-1;
for(i = a1, j = a2; i <= u1 && j <= u2; k++)
{
if (x[i] <= x[j]) aux[k] = x[i++];
else aux[k] = x[j++];
}
for( ; i <= u1; k++) aux[k] = x[i++];
for( ; j <= u2; k++) aux[k] = x[j++];
a1 = u2+1;
}
//copia o restante de x em aux
for(i = a1; k < n; i++) aux[k++] = x[i];
//copia aux em x

33
86
92
92

Estruturas de Dados e Algoritmos (C/C++) Aula 08 (Prof. Slvio)

pag. 7

for(i = 0; i < n; i++) x[i] = aux[i];


tam *= 2;
}
}

Classificao de Razes
Radix Sort (arquivo Ex808.cpp)
Este mtodo de classificao baseia-se nas representaes posicionais dos
valores dos dgitos dos nmeros a serem classificados.
Exemplo:
Vetor original x = (25 57 48 37 12 92 86 33)
Filas baseadas no dgito menos significativo
Incio
Final
Fila [0]
Fila [1]
Fila [2]
12
...
92
Fila [3]
33
Fila [4]
Fila [5]
25
Fila [6]
86
Fila [7]
57
...
37
Fila [8]
48
Fila [9]
Aps a primeira passagem temos:
Vetor x = (12 92 33 25 86 57 37 48)

Estruturas de Dados e Algoritmos (C/C++) Aula 08 (Prof. Slvio)

pag. 8

Filas baseadas no dgito mais significativo


Incio
Final
Fila [0]
Fila [1]
12
Fila [2]
25
Fila [3]
33
...
37
Fila [4]
48
Fila [5]
57
Fila [6]
Fila [7]
Fila [8]
86
Fila [9]
92
Aps a segunda passagem temos:
Vetor x = (12 25 33 37 48 57 86 92)
Algoritmo Radix Sort em notao algoritmica
Para (k=dgito menos signif; k <= dgito mais signif; k++) faa
{
para (i = 0; i < n; i++) faa
{
y = x[i];
j = k simo dgito de y;
InsFila(fila[j],y);
}
k = 0;
para (q = 0; q < 10; q++) faa
{
Enquanto ( no FilaVazia(fila[q]) )
{
y = DelFila(fila[q]);
x[k++] = y;
}
}

Algoritmo Radix Sort em C


//as funes utilizadas no cdigo abaixo e no apresentadas neste
//documento esto implementadas no arquivo Ex808.cpp
void radix(int x[], int n)
{
int k,i,j,ndig,y;
Inic_Vetor(F,Livre);
for(k=0; k < 10; k++ ) Inic_Fila(frente[k],fim[k]);
ndig = num_digitos(x[pega_maior(x,n)]);
for(k=0; k < ndig; k++)
{
for(i=0; i < n; i++)
{
y = pega_digito(x[i],k+1);
Ins_Fila(F,x[i],frente[y],fim[y],Livre);
}
j = 0;
for(i=0; i < 10; i++)
{
while( !Fila_Vazia(fim[i]) )
{
Del_Fila(F,y,frente[i],fim[i],Livre);
x[j++] = y;
}
}
for(i=0; i < n; i++ ) cout << x[i] << " ";

Estruturas de Dados e Algoritmos (C/C++) Aula 08 (Prof. Slvio)

pag. 9

cout << endl;


}
}

Algoritmos de Busca
Sequential Search (Busca Seqencial arquivo Ex809.cpp)
Devemos percorrer o vetor x sequencialmente at encontrar o elemento desejado
ou o seu final.
Algoritmo Sequential Search
int SeqSearch(int x[], int n, int chave)
{
int k;
for(k=0; k < n; k++)
if ( x[k] == chave ) return(k);
return(-1);
}

Binary Search (Busca Binria arquivo Ex809.cpp)


Este mtodo exige que os dados estejam previamente ordenados e um dos
mtodos mais eficientes de busca.
Algoritmo Binary Search
int BinSearch(int x[], int n, int chave)
{
int low, hi, mid;
low = 0;
hi = n-1;
while ( low <= hi )
{
mid = (low + hi) /2;
if ( x[mid] == chave ) return(mid);
if ( chave < x[mid] ) hi = mid - 1;
else low = mid + 1;
}
return(-1);
}

Busca Utilizando rvores (arquivo Ex501.cpp Ex701.cpp)


As Aulas 05, 06 e 07 abordaram vrias estruturas e mtodos de busca utilizando
rvores.

Você também pode gostar