Вы находитесь на странице: 1из 37

Estrutura de Dados

Algoritmos de Ordenao

Prof. Othon M. N. Batista


Mestre em Informtica
Roteiro
Introduo
Ordenao por Insero Insertion Sort
Ordenao por Seleo Selection Sort
Ordenao por Bolha Bubble Sort
Ordenao por Mistura Merge Sort
Ordenao por rvore Heap Sort
Ordenao Rpida Quick Sort
Introduo
Como ordenam-se dois nmeros???
Simples! Basta compar-los e saber qual o
maior ou menor e coloc-los na ordem desejada.
Trecho de cdigo em C:

num1 = 100;
num2 = 200;
if (num1 > num2) maior = num1; else maior = num2;
printf(Maior: %d\nMenor: %d\n, maior, menor);
Introduo
E se forem trs nmeros para ordenar???
J no to simples!
A quantidade de comparaes aumenta...
Trecho de cdigo em C:
num1 = 100;
num2 = 200;
num3 = 150;
if (num1 >= num2 && num1 >= num3) {maior1 = num1;
if (num2 > num3)
{maior2 = num2; maior3 = num3;} else
{maior2 = num3; maior3 = num2;}}
...
Introduo
Continuando o raciocnio para vrios nmeros,
no vivel testar um contra os outros desta
forma!
Portanto, precisamos de algoritmos que, dados
vrios valores que admitem ordem em uma
estrutura linear (como um vetor), ordene-os o
mais rpido possvel.
Como ordenar a lista de nmeros: 200, 324,
123, 12, 1, 4, 6, 789, 34, 2345, 324, 100?
Ordenao por Insero
Insertion Sort
Jogadores de baralho sabem ordenar as cartas
ao receb-las:
a primeira carta est ordenada;
com todas as outras:
procure do fim para o incio uma carta maior do que a
recebida;

mova todas as menores uma posio para cima;

insira a nova carta.


Ordenao por Insero
Insertion Sort
Cartas na mo:

Carta nove de ouro recebida. Procure do


fim para o incio uma carta maior:

Mova as cartas menores para a direita:

Insira a carta recebida no local.


Ordenao por Insero
Insertion Sort
Complexidade:
para cada carta:
procurar O(n)

mover para cima O(n)

inserir O(1)

Para n cartas O(n2)


Ordenao por Insero
Insertion Sort
Trecho de cdigo em C. O elemento a inserir
est na ltima posio do vetor:
void insertion_sort (int A[], int tamanho)
{
int i, k, elemento;
for (k = 0; k < tamanho; ++ k)
{
elemento = A[k];
i = k 1;

while ((i >= 0) && (A[i] > elemento))


{
A [i + 1] = A [i];
i = i 1;
A [i + 1] = elemento;
}
}
}
Ordenao por Seleo
Selection Sort
A ordenao por seleo faz com que
o menor (ou o maior) valor passe para
a primeira posio, o segundo menor
para a segunda posio, e assim
sucessivamente...

A complexidade do algoritmo no pior


caso de O(n2).
Ordenao por Seleo
Selection Sort
Exemplo:
Passo 1 (1 ao 5): Passo 3 (3 ao 5):
29 26 2 13 17 2 13 29 26 17
Menor = 2 Troca Menor = 17 Troca
com 29! com 29!
Passo 2 (2 ao 5): Passo 4 (4 ao 5):
2 26 29 13 17 2 13 17 26 29
Menor = 13 Troca Menor = 26 Troca
com 26! com 26!
Fim Vetor Ordenado
2 13 17 26 29
Ordenao por Seleo
Selection Sort
Trecho de cdigo em C:
void selection_sort(int num[], int tam) {
int i, j, min;
for (i = 0; i < (tam-1); i++) {
min = i;
for (j = (i+1); j < tam; j++) {
if(num[j] < num[min]) {
min = j;
}
}
if (i != min) {
int swap = num[i];
num[i] = num[min];
num[min] = swap;
}
}
}
Ordenao por Bolha
Bubble Sort
Um dos mais simples algoritmos de ordenao.
Ler vrias vezes os elementos de uma lista e a
cada lida passar para o topo o maior (menor)
elemento.
Parece com as bolhas subindo em um
reservatrio de gua.
A complexidade do algoritmo O(n2).
Ordenao por Bolha
Bubble Sort
Exemplo:
Passo 1 (at 4): Passo 2 (at 3):
29 26 2 13 17 26 2 13 17 29
29 > 26 Troca! 26 > 2 Troca!

26 29 2 13 17 2 26 13 17 29
29 > 2 Troca! 26 > 13 Troca!

26 2 29 13 17 2 13 26 17 29
29 > 13 Troca! 26 > 17 Troca!

26 2 13 29 17
29 > 17 Troca! Continua...
Ordenao por Bolha
Bubble Sort
Passo 3 (at 2): Passo 4 (at 1):
2 13 17 26 29 2 13 17 26 29
2 < 13 No troca! 2 < 13 No troca!

2 13 17 26 29
13 < 17 No troca!
Fim Vetor Ordenado
2 13 17 26 29
Ordenao por Bolha
Bubble Sort
Cdigo em C:
void bubbleSort (int *primeiro, int *ultimo)
{
bool naoTrocou;
int *posAtual;
for (; ultimo > primeiro; --ultimo)
{
naoTrocou = true;
for (posAtual = primeiro; posAtual < ultimo; ++posAtual)
{
if (*posAtual > *(posAtual+1))
{
troca (posAtual, posAtual+1);
naoTrocou = false;
}
}
if (naoTrocou) return;
}
}
Ordenao por Mistura
Merge Sort
O algoritmo de ordenao por mistura pertence
a classe dividir e conquistar.
Ele um algoritmo recursivo composto por trs
partes:
DIVIDIR: dividir a lista em duas partes;

CONQUISTAR: ordenar cada parte com o algoritmo;

COMBINAR: juntar as parte em uma lista ordenada.

A complexidade do algoritmo O(nlog2n).


Ordenao por Mistura
Merge Sort
Exemplo:
12 33 11 2 25 54 10 4

12 33 11 2 25 54 10 4 DIVIDIR

12 33 11 2 25 54 10 4

12 33 2 11 25 54 4 10 ORDENAR
Continua...
Ordenao por Mistura
Merge Sort
Exemplo:
12 33 2 11 25 54 4 10

2 11 12 33 4 10 25 54 COMBINAR

2 4 10 11 12 25 33 54
Vetor
Ordenado
Ordenao por Mistura
Merge Sort
Cdigo em C:
void mergeSort(int vetor[], int tamanho) {
int meio;

if (tamanho > 1) {
meio = tamanho / 2;
mergeSort(vetor, meio);
mergeSort(vetor + meio, tamanho - meio);
merge(vetor, tamanho);
}
}

A dificuldade deste algoritmo est em desenvolver


uma funo para misturar os dados j ordenados.

Isso um dos exerccios para voc!!! J
Ordenao por rvore
Heap Sort
A ordenao por rvore utiliza uma rvore
binria com propriedades diferenciadas (heap)
para ordenar os dados.
Os elementos so ordenados na insero,
obedecendo uma das duas propriedades:
heap mximo: que leva a uma ordenao crescente;
heap mnimo: que leva a uma ordena decrescente.
Aps as inseres, eles podem ser removidos
da rvore na ordem desejada.
Ordenao por rvore
Heap Sort
A rvore que obedece o heap mximo tem o
maior elemento na raiz.
A rvore que obedece o heap mnimo tem o
menor elemento na raiz.
A complexidade do algoritmo de O(nlog2n).
O algoritmo pode utilizar um vetor para
representar a rvore.
Ordenao Rpida
Quick Sort
Algoritmo de ordenao descoberto por C. A.R.
Hoare em 1962.
Mais um exemplo da tcnica de programao
denominada dividir e conquistar.
O algoritmo divide-se em duas fases:
partio: divide o trabalho pela metade (nem
sempre);
ordenao: ordena as metades.
Ordenao Rpida
Quick Sort
A complexidade divide-se em:
particionamento: O(n)
dividir os dados no meio: O(log2n)
Total: O(n log n)
A mesma que a ordenao em rvore!
Ordenao Rpida
Quick Sort
A partio consiste em descobrir um piv de
forma que quando comparados com ele:
os elementos esqueda do piv sejam menores;
os elementos direita do piv sejam maiores.

elementos < piv piv elementos > piv


Ordenao Rpida
Quick Sort
A ordenao consiste em recursivamente aplicar
a partio e a ordenao em ambas as partes.

piv piv

piv
Ordenao Rpida
Quick Sort
O algoritmo recursivo, simples e intuitivo:

quicksort (void *a, int inicio, int fim)


{
int pivo; Dividir
/* Condio de trmino! */
if ( fim > inicio )
{
pivo = particiona (a, inicio, fim); Conquistar
quicksort (a, inicio, pivo - 1);
quicksort( a, pivo + 1, maior);
}
}
Ordenao Rpida
Quick Sort
int particiona( int *a, int inicio, int fim )
{
int esquerda, direita;
int pivo_item, pivo_indice;
pivo_item = a[inicio];
pivo_indice = esquerda = inicio;
direita = fim;
while ( esquerda < direita ) {
/* Vai para a esquerda enquanto item < pivo */
while( a[esquerda] <= pivo_item) esquerda ++;

/* Vai para a direita enquanto item > pivo */


while( a[direita] >= pivo_item) direita --;

if ( esquerda < direita ) Troca(a, esquerda, direita);


}
/* direita e a posicao final do pivo */
a[inicio] = a[direita];
a[direita] = pivo_item;
return direita;
}
Ordenao Rpida
Quick Sort
Qualquer item pode ser o piv.
Neste caso foi escolhido o mais esquerda.

Incio Fim
Ordenao Rpida
Quick Sort

Marcadores de direita e esquerda

Esquerda Direita

Incio Piv = 23 Fim


Ordenao Rpida
Quick Sort
Mover esquerda e direita
at que se cruzem.

Esquerda Direita

Incio Piv = 23 Fim


Ordenao Rpida
Quick Sort
Mover esquerda at encontrar
itens <= piv
Idem para a direita com
itens >= piv

Esquerda Direita

Incio Piv = 23 Fim


Ordenao Rpida
Quick Sort
Trocar os itens no
lado errado do piv

Esquerda Direita

Incio Fim
Piv = 23
Ordenao Rpida
Quick Sort
Esquerda passou da direita.
Fim do lao.

Direita Esquerda

Incio Piv = 23 Fim


Ordenao Rpida
Quick Sort
Troca o piv com
posio direita atual.

Direita Esquerda

Incio Piv = 23 Fim


Ordenao Rpida
Quick Sort
Retorna direita como
a nova posio do piv.

Direita

Incio Piv = 23 Fim


Ordenao Rpida
Quick Sort
Piv

Piv = 23
Direita

Ordena a esquerda Ordena a direita


recursivamente... recursivamente...

Вам также может понравиться