43
Ordenação (computação) Origem: Wikipédia, a enciclopédia livre. Ordenação é o ato de se colocar os elementos de uma sequência de informações, ou dados , em uma ordem predefinida. O termo técnico em inglês para ordenação é sorting, cuja tradução literal é "classificação". Dado uma seqüencia de n dados: O problema de ordenação é uma permutação dessa seqüencia tal que para alguma relação de ordem . Algumas ordens são facilmente definidas. Por exemplo, a ordem numérica, ou a ordem alfabética -- crescentes ou decrescentes. Contudo, existem ordens, especialmente de dados compostos, que podem ser não triviais de se estabelecer. Um Algoritmo que ordena uma conjunto, geralmente representada num vetor, é chamadado um algoritmos de ordenação . Entre os mais importantes, podemos citar bubble sort (ou ordenação por flutuação), heap sort (ou ordenação por heap), insertion sort (ou ordenação por inserção), merge sort (ou ordenação por mistura) e o quicksort . Ordenação estável Origem: Wikipédia, a enciclopédia livre. Um algoritmo de ordenação diz-se estável se preserva a ordem de registros de chaves iguais. Isto é, se tais registros aparecem na sequência ordenada na mesma ordem em que estão na sequência inicial. [1] Esta propriedade é útil apenas quando há dados associados às chaves de ordenação. Exemplo Por exemplo, um algoritmo estável ordenando a sequência de números (chaves) com letras associadas (registros): 3[a], 2[b], 2[c], 1[d] obrigatoriamente retornará: 1[d], 2[b], 2[c], 3[a] enquanto algoritmos instáveis sujeitam os elementos associados aos objetos a serem ordenados a mudanças: 1[d], 2[c], 2[b], 3[a]

Metodos de Ordenacao de Vetores

Embed Size (px)

Citation preview

Page 1: Metodos de Ordenacao de Vetores

Ordenação (computação)

Origem: Wikipédia, a enciclopédia livre.

Ordenação é o ato de se colocar os elementos de uma sequência de informações, ou dados, em uma ordem predefinida. O

termo técnico em inglês para ordenação é sorting, cuja tradução literal é "classificação".

Dado uma seqüencia de n dados:

O problema de ordenação é uma permutação dessa seqüencia

tal que

para alguma relação de ordem.

Algumas ordens são facilmente definidas. Por exemplo, a ordem numérica, ou a ordem alfabética -- crescentes

ou decrescentes. Contudo, existem ordens, especialmente de dados compostos, que podem ser não triviais de se

estabelecer.

Um Algoritmo que ordena uma conjunto, geralmente representada num vetor, é chamadado um algoritmos de

ordenação. Entre os mais importantes, podemos citar bubble sort (ou ordenação por flutuação), heap sort (ou

ordenação por heap), insertion sort (ou ordenação por inserção), merge sort (ou ordenação por mistura) e

o quicksort.

Ordenação estável Origem: Wikipédia, a enciclopédia livre.

Um algoritmo de ordenação diz-se estável se preserva a ordem de registros de chaves iguais. Isto é, se tais registros

aparecem na sequência ordenada na mesma ordem em que estão na sequência inicial. [1]

Esta propriedade é útil apenas quando há dados associados às chaves de ordenação.

Exemplo

Por exemplo, um algoritmo estável ordenando a sequência de números (chaves) com letras associadas (registros):

3[a], 2[b], 2[c], 1[d]

obrigatoriamente retornará:

1[d], 2[b], 2[c], 3[a]

enquanto algoritmos instáveis sujeitam os elementos associados aos objetos a serem ordenados a mudanças:

1[d], 2[c], 2[b], 3[a]

Page 2: Metodos de Ordenacao de Vetores

Implementação

Certos algoritmos são estáveis a partir de sua concepção original, como o Counting sort ou o Merge sort. Porém. é possível

implementar estabilidade artificialmente em certos algoritmos. Por exemplo, numa comparação de dois objetos de mesmo valor

pode aplicar-se uma comparação adicional para verificar se a ordem original dos registros associados foi mantida. Neste caso,

a implementação de estabilidade requer um custo adicional de eficiência.

Algoritmos estáveis

Alguns algoritmos de ordenação estáveis:

Bubble sort

Cocktail sort

Insertion sort

Merge sort

Bucket sort

Algoritmos instáveis

Alguns algoritmos de ordenação instáveis:

Selection Sort

Quick Sort

Heap Sort

Shell Sort

Counting Sort

Algoritmo de ordenação

Origem: Wikipédia, a enciclopédia livre.

Algoritmo de ordenação em ciência da computação é um algoritmo que coloca os elementos de uma dada sequência em

uma certaordem -- em outras palavras, efetua sua ordenação completa ou parcial. As ordens mais usadas são a numérica e

a lexicográfica.

Existem várias razões para se ordenar uma sequência. Uma delas é a possibilidade se acessar seus dados de modo mais

eficiente.

Métodos de ordenação de vetores

Métodos simples

Insertion sort

Selection sort

Bubble sort

Comb sort

Métodos sofisticados

Quick sort

Page 3: Metodos de Ordenacao de Vetores

Merge sort

Heapsort

Shell sort

Radix sort

Gnome sort

Count sort

Bucket sort

Cocktail sort

Timsort

Métodos de pesquisa

Pesquisa binária

Busca linear

BogoBusca

Bogosort Origem: Wikipédia, a enciclopédia livre.

Bogosort (também denominado bozo sort, blort sort e vai-na sort ou Estou com sort) é um algoritmo de

ordenação extremamente ineficiente, baseado na reordenação aleatória dos elementos. Não é utilizado na prática, mas pode

ser usado no ensino de algorítmos mais eficientes. Seu nome veio do engraçado termo quantum bogodynamics e,

ultimamente, a palavra bogus.

Esse algoritmo é probabilístico por natureza. Se todos os elementos a serem ordenados são distintos, a complexidade

esperada é . O tempo exato de execução esperado depende do quantos diferentes valores de elementos

ocorrem, e quantas vezes cada um deles ocorre, mas para casos não-triviais o tempo esperado de execução é exponencial ou

super-exponencial a . Ele termina pela mesma razão do teorema do macaco infinito; existe alguma probabilidade de que

aconteça a permutação correta, dado que em um infinito número de tentativas fatalmente a encontrará.

Deve-se notar que com os algoritmos geradores de números pseudo-aleatórios, que têm um número finito de estados e não

são realmente aleatórios, o algoritmo pode nunca terminar para certos conjuntos de valores a serem ordenados.

Bogosort não é um algoritmo de ordenação estável.

Exemplo

Para se ordenar um baralho usando-se este algorítmo, seria necessário jogar as cartas ao ar, juntá-las aleatoriamente, e então

verificar se as mesmas estão ordenadas.

[editar]Algorítmo

função bogosort(array)

Page 4: Metodos de Ordenacao de Vetores

enquanto não está_ordenado(array)

array := permutação_aleatória(array)

[editar]Implementações

[editar]C

void bogosort(int size, int *array)

{

int i, j;

for (i = 1; i <= size; i++)

if (i == size)

return;

else if (array[i-1] > array[i])

break;

for (i = 0; i < size; i++) {

j = rand() % size;

if (array[i] != array[j])

array[i] ^= array[j] ^= array[i] ^= array[j];

}

bogosort(size, array);

}

[editar]C++

#include <algorithm>

#include <vector>

template<class T>

void bogosort(std::vector<T>& array)

{

while (! is_sorted(array))

std::random_shuffle(array.begin(), array.end());

}

template<class T>

bool is_sorted(const std::vector<T>& array)

{

for (typename std::vector<T>::size_type i = 1; i < array.size(); ++i)

if (array[i] < array[i-1]) return false;

return true;

}

[editar]Java

public static void bogoSort(int length, int range) {

int []array = randomIntArray(length,range);

while (! isSorted(array))

array = randomArray(array);

for (int i = 0; i < array.length; i++) {

System.out.print(array[i] + " ");

}

Page 5: Metodos de Ordenacao de Vetores

}

private static boolean isSorted(int [] array)

{

for (int i = 0; i < (array.length - 1); ++i) {

if (array[i] > array[i+1])

return false;

}

return true;

}

private static int [] randomArray(int [] array) {

int size = array.length;

int[] indices = new int[size];

for (int i=0; i<size; i++) {

indices[i] = i;

}

Random random = new Random();

for (int i = 0; i < size; i++) {

boolean unique = false;

int nRandom = 0;

while (!unique) {

unique = true;

nRandom = random.nextInt(size);

for (int j = 0; j < i; j++) {

if (indices[j] == nRandom) {

unique = false;

break;

}

}

}

indices[i] = nRandom;

}

int [] result = new int[size];

for (int k = 0; k < size; k++) {

result[indices[k]] = array[k];

}

return result;

}

private static int[] randomIntArray(int length, int n)

{

int[] a = new int[length];

Random generator = new Random();

for (int i = 0; i < a.length; i++)

{

a[i] = generator.nextInt(n);

Page 6: Metodos de Ordenacao de Vetores

}

return a;

}

Fluxograma

Introdução

O bubble sort, ou ordenação por flutuação (literalmente "por bolha"), é um algoritmo de ordenação dos mais simples. A ideia é

percorrer o vector diversas vezes, a cada passagem fazendo flutuar para o topo o maior elemento da sequência. Essa movimentação

lembra a forma como as bolhas em um tanque de água procuram seu próprio nível, e disso vem o nome do algoritmo.

No melhor caso, o algoritmo executa operações relevantes, onde n representa o número de elementos do vector. No pior caso, são

feitas operações. A complexidade desse algoritmo é de Ordem quadrática. Por isso, ele não é recomendado para programas que

precisem de velocidade e operem com quantidade elevada de dados.

[editar]Algoritmo

[editar]Pseudo-código

O algoritmo abaixo, decrito em pseudo-código, promete ordenar um vetor V[1..n] em ordem crescente.

Algoritmo Bubble(V, n)

1. k = n-1

2. para i = 1 até n faça

3. j = 1

4. enquanto j <= k faça

5. se V[j] > V[j+1] então

6. aux = V[j]

7. V[j] = V[j+1]

8. V[j+1] = aux

9. j = j+1

10. k = k-1

Page 7: Metodos de Ordenacao de Vetores

[editar]Demonstração de corretude

A demonstração do algoritmo se apóia nos seguintes invariantes, provados por indução matemática:

(i0): na linha 2, V[n-i+2 .. n] é crescente.

Prova: no momento da entrada do laço externo, quando i=1, o invariante vale, já que V[n+1 .. n] é vazio e, portanto, crescente.

Suponha agora que o invariante vale se trocarmos i por i-1. Queremos mostrar que ele também vale para i. Por hipótese de indução,

V[n-i+3 .. n] é crescente. Pelo invariante (i1), ao terminar o laço das linhas 4-9, teremos que V[1 .. n-i] <= V[n-i+1]. V[n-i+2] <= V[n-i+3

.. n]. Assim, V[n-i+2 .. n] é crescente.

Observe que a validade de (i0) em conjunto com a condição de parada do algoritmo (i = n+1) implicam na corretude do mesmo: V[n-

(n+1)+2 .. n] = V[1 .. n] é crescente.

(i1): na linha 4, vale que V[ j ] >= V[1 .. j-1]

Prova: o invariante vale na entrada do laço das linhas 4-9, quando j=1, pois V[1] >= V[1..0] (vazio). Suponha agora que o invariante

vale se trocarmos j por j-1. Então, V[ j-1 ] >= V[1 .. j-2] na linha 4. Ora, mas podemos ver que, ao final do laço interno, V[ j ] >= V[ j-1 ].

De fato, na linha 5, se V[ j-1 ] > V[ (j-1)+1 ] = V[ j ], trocaremos V[ j-1 ] e V[ j ] de posição, o que garante que V[ j ] >= V[ j-1 ] sob

qualquer circunstância.

Observe que, ao final do laço interno, V[n-i+1] >= V[1 .. n-i]: aplique (i1) com j = k+1, notando que k = n-i.

[editar]Análise do consumo de tempo

TODO. Alguém saberia formatar melhor esta tabela?

-------------+-------------------------------------

linha | número de execuções da linha

-------------+-------------------------------------

1 1

2 n+1

3 n

4 n

5 sum_{i=1}^{n} n-i+1 = (n^2 + n)/2 + 1

6 <= sum_{i=1}^{n} n-i = (n^2 + n)/2

7 <= sum_{i=1}^{n} n-i = (n^2 + n)/2

8 <= sum_{i=1}^{n} n-i = (n^2 + n)/2

9 sum_{i=1}^{n} n-i = (n^2 + n)/2

10 n

-------------+-------------------------------------

total <= (5/2)n^2 + (13/2)n + 3

-------------+-------------------------------------

O consumo de tempo de Bubble é \theta(n^2).

TODO: provar.

[editar]Versão alternativa

Abaixo há um algoritmo Bubble Sort onde a implementação é a mais simples possível, ou seja, é a versão original do Bubble

Sortsem o aprimoramento da variável "houve troca".

BUBBLESORT (V[], n)

houveTroca <- verdade # uma variável de controle

enquanto houveTroca for verdade faça:

houveTroca <- falso

para i de 1 até n-1 faça:

se V[i] vem depois de V[i + 1]

Page 8: Metodos de Ordenacao de Vetores

então troque V[i] e V[i + 1] de lugar e

houveTroca <- verdade

Para j de 1 até (i - 1) Passo 1

Se a[j - 1] > a[j] Então

aux <- a[j]

a[j] <- a[j - 1]

a[j - 1] <- aux

FimSe

Observação: Neste algoritmo tanto o melhor caso, como o pior caso tem ordem "n²", porque em ambos os casos os ciclos são

sempre realizados até ao fim, mesmo quando os elementos já estão ordenados.

[editar]Implementação

[editar]C

1. include<stdio.h>

2. include<stdlib.h>

3. include<conio.h>

4. include<stdbool.h>

int main() {

int vetor[5], i, aux;

bool parar = false;

for(i=0;i<5;++i)

{

printf("Digite o valor: ");

scanf("%d",&vetor[i]);

}

while(parar == false)

{

parar = true;

for(i=0;i<4;++i)

{

if(vetor[i]>vetor[i+1])

{

parar = false;

aux = vetor[i];

vetor[i] = vetor[i+1];

vetor[i+1] = aux;

}

}

}

Page 9: Metodos de Ordenacao de Vetores

for(i=0;i<5;++i)

{

printf("%d",vetor[i]);

}

getch();

return 0;

}

[editar]Java

public static void bubbleSort (int [] vetor){

boolean houveTroca = true;

while (houveTroca) {

houveTroca = false;

for (int i = 0; i < (vetor.length)-1; i++){

if (vetor[i] > vetor[i+1]){

int variavelAuxiliar = vetor[i+1];

vetor[i+1] = vetor[i];

vetor[i] = variavelAuxiliar;

houveTroca = true;

}

}

}

}

[editar]C

Usando "do while".

void swapbubble( int v[], int i)

{

int aux=0;

aux=v[i];

v[i] = v[i+1];

v[i+1] = aux;

}

void bubble(int v[], int qtd)

{

int i;

int trocou;

qtd--;

do

{

trocou = 0;

for(i = 0; i < qtd; i++)

{

if(v[i] > v[i + 1])

Page 10: Metodos de Ordenacao de Vetores

{

swapbubble(v, i);

trocou = 1;

}

}

}while(trocou);

}

Método de ordenação Bolha com ordenação de strings.

void bubble(int v[], int qtd)

//UTILIZA BIBLIOTECA string.h

{

int i;

int trocou;

char aux;

do

{

qtd--;

trocou = 0;

for(i = 0; i < qtd; i++)

if(strcasecmp(v[i],v[i + 1])>0)

{

/*o ideal seria fazer uma função troca aqui*/

strcpy(aux, v[i]);

strcpy(v[i], v[i + 1]);

strcpy(v[i + 1], aux);

trocou = 1;

}

}while(trocou==1);

}

[editar]C++

#include <algorithm>

using namespace std;

void bubblesort(int a[], int n)

{

for(int j=0; j<n; j++){

for(int i=0; i<n-1; i++){

if(a[i+1] < a[i])

swap(a[i+1], a[i]);

}

}

}

Page 12: Metodos de Ordenacao de Vetores

Bucket sort, ou bin sort, é um algoritmo de ordenação que funciona dividindo um vetor em um número finito de recipientes.

Cada recipiente é então ordenado individualmente, seja usando um algoritmo de ordenação diferente, ou usando o algoritmo

bucket sort recursivamente. O bucket sort tem complexidade linear (Θ(n)) quando o vetor a ser ordenado contém valores que

são uniformemente distribuídos.

[editar]Funcionamento

Bucket sort funciona do seguinte modo:

1. Inicialize um vetor de "baldes", inicialmente vazios.

2. Vá para o vetor original, incluindo cada elemento em um balde.

3. Ordene todos os baldes não vazios.

4. Coloque os elementos dos baldes que não estão vazios no vetor original.

[editar]Exemplo em C

//Compilado em Linux.Sujeito a mudanças caso outro sistema seja utilizado.

#include <stdio.h>

#define tam_bucket 100

#define num_bucket 10

#define max 10

typedef struct {

int topo;

int balde[tam_bucket];

}bucket;

void bucket_sort(int v[],int tam); //cabeçalho das funções

void bubble(int v[],int tam);

//int main(){}

void bucket_sort(int v[],int tam){

bucket b[num_bucket];

int i,j,k;

/* 1 */ for(i=0;i<num_bucket;i++) //inicializa todos os "topo"

b[i].topo=0;

/* 2 */ for(i=0;i<tam;i++){ //verifica em que balde o elemento deve

ficar

j=(num_bucket)-1;

while(1){

if(j<0)

break;

if(v[i]>=j*10){

b[j].balde[b[j].topo]=v[i];

(b[j].topo)++;

break;

}

j--;

}

Page 13: Metodos de Ordenacao de Vetores

}

/* 3 */ for(i=0;i<num_bucket;i++) //ordena os baldes

if(b[i].topo)

bubble(b[i].balde,b[i].topo);

i=0;

/* 4 */ for(j=0;j<num_bucket;j++){ //põe os elementos dos baldes de volta

no vetor

for(k=0;k<b[j].topo;k++){

v[i]=b[j].balde[k];

i++;

}

}

}

void bubble(int v[],int tam){

int i,j,temp,flag;

if(tam)

for(j=0;j<tam-1;j++){

flag=0;

for(i=0;i<tam-1;i++){

if(v[i+1]<v[i]){

temp=v[i];

v[i]=v[i+1];

v[i+1]=temp;

flag=1;

}

}

if(!flag)

break;

}

}

[editar]Explicação do código

Bucket sort - fase 1.

Bucket sort - fase 2.

Page 14: Metodos de Ordenacao de Vetores

Antes de mais nada, é preciso saber o que cada "#define" significa.

1. tam_bucket é o tamanho de cada balde da estrutura bucket.

2. num_bucket é o número de baldes, isto é, o tamanho do vetor de bucket

3. max é o tamanho do vetor a ser ordenado.

A estrutura bucket consiste de um vetor de inteiros (int balde[tam_bucket]) e de uma variável que serve para dizer

quantos números estão armazenados no balde.

O parâmetro "tam", tanto na função "bucket_sort" como na "bubble", é o tamanho do vetor a ser ordenado.

A explicação dos "for" agora:

1. Inicializa o "topo" de cada bucket que o vetor de bucket "b[num_bucket]" contém.

Isso é importante, pois, a princípio, os baldes estão vazios.

2. Verifica em que balde o elemento deve ficar.

Cada elemento do vetor a ser ordenado é colocado em seu lugar no vetor de bucket.Por exemplo, suponha o número

26.A variável "j" receberia (num_bucket-1), isto é,9 no exemplo acima.O "while" verifica se 26 é maior do que j*10

(90).Como isto não é válido, "j" é decrementado em 1, e o processo se repete até que j=2, já que 26>=20.Então, o

balde de posição 2 recebe 26.Caso não haja nenhum outro elemento no balde 2, isso significa que "topo" daquele

balde vale 0, portanto balde[0] recebe o 26.Caso haja, por exemplo, 3 elementos no balde, isso quer dizer que topo=2,

portanto balde[2] recebe 26.Depois disso, "topo" daquele balde é incrementado em 1 e o processo se repete para os

outros elementos do vetor que queremos ordenar.

3. Ordena cada balde.

Ordena os baldes cujos "topo" são diferentes de 0, ou seja, não estão vazios.No algoritmo acima, o bubble sort foi

utilizado, mas métodos mais eficientes podem ser utilizados.

4. Por fim, os baldes são percorridos e seus elementos são devolvidos para o vetor original.

Atente para o fato de que nosso exemplo não ordena elementos negativos.Um tratamento especial para eles

seria necessário.Além do mais, o método de separar cada elemento pode ser diferente.O utilizado foi

verificar se o elemento está entre 0 e 10, 11 e 20, e assim por diante.

_______________________________________________________________________________________

____

Aqui uma matriz linear de inteiros com n elementos,é usado para ordenar os elementos do vetor.

[editar]Exemplo em C++ com matriz

/*************************INICIO*****************************************/

//==================================================================

//

// Projeto: Bucket Sort

// Data de Criacao: 27/02/09

// Autor: Albany Timbo Mesquita

// Colaboracao:Pedro Henrique Fernandes Marques Leitao

//

//==================================================================

#include <iostream>

#define TAM 20 /*Tamanho do vetor*/

Page 15: Metodos de Ordenacao de Vetores

#define NUM 10000 /*base para gerador de numeros aleatorios*/

using std::cout;

using std::cin;

using std::endl;

void gerarVet(int*);

void bucketSort(int*);

void imprimaVet(int*);

int main(){

int vet[TAM],tinicio,tfim,tempo;

tinicio=time(NULL);

gerarVet(vet);

imprimaVet(vet);

bucketSort(vet);

imprimaVet(vet);

tfim=time(NULL);

tempo=difftime(tfim,tinicio);

cout<<"Tempo de execucao "<<tempo/60<<" Minutos e "<<tempo%60<<" segundos.\n";

system("pause");

return 0;

}

/***********************************************************************/

/*******************************FUNCOES*********************************/

/***********************************************************************/

void bucketSort(int *vet){

int mat[10][TAM],aux[TAM],cont=1,num,w=0,i,j;

do{

for(i=0;i<TAM;i++){aux[i] = 0;}//Zerando o vetor auxiliar.

for(i=0;i<10;i++) {//Setando a Matriz com valores -1

for(j=0;j<TAM;j++){

mat[i][j] = -1;

}

}

for (i=0;i<TAM;i++) {

num = (vet[i]/cont)%10;//verificando o valor da esquerda para direita

mat[num][aux[num]] = vet[i];//colocando o valor na sua posicao na

matriz

aux[num]++; //contador de colunas da matriz

}

for(i=0;i<10;i++) {//volta com os valores da Matriz para o vetor

for(j=0;j<TAM;j++){

if(mat[i][j] != -1){

vet[w] = mat[i][j];

w++;

}

Page 16: Metodos de Ordenacao de Vetores

}

}

w = 0;

cont=cont*10;

}while(aux[0] < TAM);//condicao :Enquanto vetor auxiliar < tamanho vetor

} //

/******************GERADOR DE NUMEROS ALEATORIOS**************************/

void gerarVet(int *vet){

srand(time(NULL));

for (int i=0;i<TAM;i++){

vet[i]=rand()%NUM;

}

}

/*******************FUNCAO PARA IMPRIMIR VETOR************************/

void imprimaVet(int *vet){

for (int i=0;i<TAM;i++){

cout<<vet[i]<<"|";

}

cout<<"**************************************************************\n";

}

/********************************FIM*************************************/

_______________________________________________________________________________________

______________________

[editar]Exemplo em Java com LinkedList

/*

* Autor: wilhs

* Data: 28/04/2011

* Crédito: Implementação com base neste Artigo.

*/

public static void BucketSort(int[] vetor, int maiorValor)

{

int numBaldes = maiorValor/5;

LinkedList[] B = new LinkedList[numBaldes];

for (int i = 0; i < numBaldes; i++){

B[i] = new LinkedList<Integer>();

}

//Coloca os valores no balde respectivo:

for (int i = 0; i < vetor.length; i++) {

int j = numBaldes-1;

while (true){

if(j<0){

break;

}

if(vetor[i] >= (j*5)){

B[j].add(vetor[i]);

break;

Page 17: Metodos de Ordenacao de Vetores

}

j--;

}

}

//Ordena e atualiza o vetor:

int indice = 0;

for (int i = 0; i < numBaldes; i++){

int[] aux = new int[B[i].size()];

//Coloca cada balde num vetor:

for (int j = 0; j < aux.length; j++){

aux[j] = (Integer)B[i].get(j);

}

insertionSort(aux); //algoritmo escolhido para ordenação.

// Devolve os valores ao vetor de entrada:

for (int j = 0; j < aux.length; j++, indice++){

vetor[indice] = aux[j];

}

}

}

Cocktail sort Origem: Wikipédia, a enciclopédia livre.

Cocktail sort, também conhecido como Shaker Sort, bubble sort bidirecional (que também pode se referir a uma variante

do selection sort), ripple sort, shuttle sort ouhappy hour sort, é uma variação do bubble sort que é tanto um algoritmo de

ordenaçãoestável quanto uma ordenação por comparação. O algoritmo difere do bubble sort pelo fato de ordenar em ambas as

direções em cada passagem através da lista. Este algoritmo de ordenação é apenas ligeiramente mais difícil de implementar

do que o bubble sort, e resolve o problema com os chamados coelhos e tartarugas no bubble sort.

[editar]Complexidade

O(n²)

[editar]Implementações

[editar]Código em C

void cocktail_sort(int list[10]) {

int length,bottom,top, swapped,i,aux;

Page 18: Metodos de Ordenacao de Vetores

length=10;

bottom = 0;

top = length - 1;

swapped = 0;

while(swapped == 0 && bottom < top)//Se não houver troca de posições ou o ponteiro que

{ //sobe ultrapassar o que desce, o vetor esta ordenado

swapped = 1;

//Este for é a “ida” para a direita

for(i = bottom; i < top; i = i + 1)

{

if(list[i] > list[i + 1]) //indo pra direita:testa se o próximo é maior

{ //indo pra direita:se o proximo é maior que o atual,

//troca as posições

aux=list[i];

list[i]=list[i+1];

list[i+1]=aux;

swapped = 0;

}

}//fecha for

// diminui o `top` porque o elemento com o maior valor

// já está na direita (atual posição top)

top = top - 1;

//Este for é a “ida” para a esquerda

for(i = top; i > bottom; i = i - 1)

{ if(list[i] < list[i - 1])

{

aux=list[i];

list[i]=list[i-1];

list[i-1]=aux;

swapped = 0;

}

}

//aumenta o `bottom` porque o menor valor já está

//na posição inicial (bottom)

bottom = bottom + 1;

}//fecha while

}// fim da funçao

[editar]Código em C# e Java (sintaxe idêntica)

private static void cocktail(int[] vetor)

{

int tamanho, inicio, fim, swap, aux;

tamanho = 20; // para um vetor de 20 elementos

inicio = 0;

fim = tamanho - 1;

swap = 0;

while (swap == 0 && inicio < fim)

{

swap = 1;

for (int i = inicio; i < fim; i = i + 1)

{

if (vetor[i] > vetor[i + 1])

{

aux = vetor[i];

vetor[i] = vetor[i + 1];

Page 19: Metodos de Ordenacao de Vetores

vetor[i + 1] = aux;

swap = 0;

}

}

fim = fim - 1;

for (int i = fim; i > inicio; i = i - 1)

{

if (vetor[i] < vetor[i - 1])

{

aux = vetor[i];

vetor[i] = vetor[i - 1];

vetor[i - 1] = aux;

swap = 0;

}

}

inicio = inicio + 1;

}

}

Comb sort Origem: Wikipédia, a enciclopédia livre.

O algoritmo Comb sort (ou Combo sort ou ainda algoritmo do pente[1]

) é umalgoritmo de ordenação relativamente simples, e

faz parte da família de algoritmos deordenação por troca. Foi desenvolvido em 1980 por Wlodzimierz Dobosiewicz. Mais tarde,

foi redescoberto e popularizado por Stephen Lacey e Richard Box em um artigo publicado na revista Byte em Abril de 1991.

O Comb sort melhora o Bubble sort, e rivaliza com algoritmos como o Quicksort. A idéia básica é eliminar as tartarugas ou

pequenos valores próximos do final da lista, já que em um bubble sort estes retardam a classificação tremendamente.

(Coelhos, grandes valores em torno do início da lista, não representam um problema no bubble sort).

O Algoritmo repetidamente reordena diferentes pares de itens, separados por um salto, que é calculado a cada passagem.

Método semelhante ao Bubble Sort, porém mais eficiente.

Na Bubble sort, quando quaisquer dois elementos são comparados, eles sempre têm um gap (distância um do outro) de 1. A

idéia básica do Comb sort é que a diferença pode ser muito mais do que um. (O Shell sort também é baseado nesta idéia, mas

é uma modificação do insertion sort em vez do bubble sort).

O gap (intervalo) começa como o comprimento da lista a ser ordenada dividida pelo fator de encolhimento (em geral 1,3; veja

abaixo), e a lista é ordenada com este valor (arredondado para um inteiro se for necessário) para o gap. Então, a diferença é

dividida pelo fator de encolhimento novamente, a lista é ordenada com este novo gap, e o processo se repete até que a

diferença seja de 1. Neste ponto, o Comb sort continua usando um espaço de 1 até que a lista esteja totalmente ordenada. A

fase final da classificação é, portanto, equivalente a um bubble sort, mas desta vez a maioria dos elementos "tartarugas" já

foram tratados, assim o bubble sort será eficiente.

[editar]Fator de encolhimento

O fator de encolhimento tem um grande efeito sobre a eficiência do Comb sort. No artigo original, os autores sugeriram 1,3

depois de tentar algumas listas aleatórias e encontrando-se, geralmente as mais eficazes. Um valor muito pequeno retarda o

algoritmo porque mais comparações devem ser feitas, ao passo que um valor muito grande não pode tratar um número

suficiente de "tartarugas" para ser prático.

Page 20: Metodos de Ordenacao de Vetores

O texto descreve uma melhoria no comb sort usando o valor base como

fator de encolhimento. Ele também contém uma implementação em pseudocódigo com uma tabela de gaps pré-definidos.

[editar]Variações

[editar]Combsort11

Com um fator de encolhimento de cerca de 1,3, só existem três caminhos possíveis para a lista de gaps terminar: (9, 6, 4, 3, 2,

1), (10, 7, 5, 3, 2, 1), ou (11, 8, 6, 4, 3, 2, 1). Experimentos mostram que melhorias significativas de velocidade podem ser feitas

se o gap for definido como 11, sempre que, caso contrário, tornar-se 9 ou 10. Esta variação é chamada Combsort11.

Se uma das sequências que começam com 9 ou 10, forem utilizadas, o passo final, com um intervalo de 1 tem menor

probabilidade de ordenar os dados sendo necessário então outro passo com gap de 1. Os dados são ordenados quando não

ocorrem mais trocas durante uma passagem com gap= 1.

Também é possível usar uma tabela pré-definida, para escolher quais gaps a utilizar em cada passo.

[editar]Combsort com diferentes finais

Como muitos outros algoritmos eficientes de ordenação (como o quick sort ou merge sort), o comb sort é mais eficaz em suas

passagens anteriores do que durante o passo final, quando ele se assemelha a um bubble sort. O Comb sort pode ser mais

eficaz se o método de classificação é mudado uma vez que os gaps cheguem a um número pequeno o suficiente. Por

exemplo, uma vez que a diferença chegue a um tamanho de cerca de 10 ou menor, parando o comb sort e fazendo um

simples gnome sort ou cocktail sort, ou, melhor ainda, um insertion sort, se aumentará a eficiência global da ordenação.

Outra vantagem deste método é que não há necessidade de manter o controle das operações de troca durante os passos da

classificação para saber se a ordenação deve parar ou não.

[editar]Implementações

[editar]C++

Esta é uma implementação no estilo STL. Ele irá classificar qualquer intervalo entre a primeira e a última. Isso funciona com

quaisqueriteradores posteriores, mas é mais eficaz com iteradores de acesso aleatório ou ponteiros.

template<class ForwardIterator>

void combsort ( ForwardIterator first, ForwardIterator last )

{

static const double shrink_factor = 1.247330950103979;

typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_type;

difference_type gap = std::distance(first, last);

bool swaps = true;

while ( (gap > 1) || (swaps == true) ){

if (gap > 1)

gap = static_cast<difference_type>(gap/shrink_factor);

swaps = false;

ForwardIterator itLeft(first);

ForwardIterator itRight(first); std::advance(itRight, gap);

for ( ; itRight!=last; ++itLeft, ++itRight ){

if ( (*itRight) < (*itLeft) ){

std::iter_swap(itLeft, itRight);

Page 21: Metodos de Ordenacao de Vetores

swaps = true;

}

}

}

}

[editar]Java

public static <E extends Comparable<? super E>> void sort(E[] input) {

int gap = input.length;

boolean swapped = true;

while (gap > 1 || swapped) {

if (gap > 1)

gap = (int) (gap / 1.247330950103979);

int i = 0;

swapped = false;

while (i + gap < input.length) {

if (input[i].compareTo(input[i + gap]) > 0) {

E t = input[i];

input[i] = input[i + gap];

input[i + gap] = t;

swapped = true;

}

i++;

}

}

}

[editar]C

void combsort(int *arr, int size) {

float shrink_factor = 1.247330950103979;

int gap = size, swapped = 1, swap, i;

while ((gap > 1) || swapped) {

if (gap > 1)

gap = gap / shrink_factor;

swapped = 0;

i = 0;

while ((gap + i) < size) {

if (arr[i] - arr[i + gap] > 0) {

swap = arr[i];

arr[i] = arr[i + gap];

arr[i + gap] = swap;

swapped = 1;

}

++i;

}

}

}

Page 22: Metodos de Ordenacao de Vetores

Counting sort

Origem: Wikipédia, a enciclopédia livre.

Counting sort é um algoritmo de ordenação estável cuja complexidade é O(n). As chaves podem tomar valores entre 0 e M-1.

Se existirem k0 chaves com valor 0, então ocupam as primeiras k0 posições do vetor final: de 0 a k0-1.

[editar]Implementações

1. Cria cnt[M+1] e b[max N]

2. Inicializa todas as posições de cnt a 0.

3. Percorre o vector a e, para cada posição i de a faz cnt[a[i]-1]++ o que faz com que, no final, cada posição i de cnt

contem o nº de vezes que a chave i-1 aparece em a.

4. Acumula em cada elemento de cnt o elemento somado ao elemento anterior: cnt[i] indica a posição ordenada do

primeiro elemento de chave i.

5. Guarda em b os valores de a ordenados de acordo com b[cnt[a[i]++]=a[i]

6. Copia b para a.

7. Counting-Sort trabalha como uma contadora de ocorrências dentro de um programa, especificamente dentro de um

vetor. Quando determinado vetor tem números repetidos, números únicos e números que não existem um outro vetor

indica a quantidade de ocorrências.

Esta implementação tem a desvantagem de precisar de vectores auxiliares. O Counting Sort ordena exclusivamente números

inteiros pelo fato de seus valores servirem como índices no vetor de contagem.

[editar]Código em C++

template<class T>

std::vector<T> counting_sort( const std::vector<T> &op )

{

if( op.empty() )

return std::vector<T>();

T min = *std::min_element( op.begin(), op.end() );

T max = *std::max_element( op.begin(), op.end() );

std::vector<int> contagem( max - min + 1, 0 );

for( std::vector<T>::const_iterator it = op.begin(); it != op.end(); ++it );

++contagem[ *it - min ];

std::partial_sum( contagem.begin(), contagem.end(), contagem.begin() );

std::vector<T> ordenado( op.size() );

for( std::vector<T>::const_reverse_iterator it2 = op.rbegin(); it2 != op.rend(); ++it2 )

ordenado[ --contagem[ *it2 - min ] ] = *it2;

return ordenado;

}

[editar]Código em C

# include <stdio.h>

# include <string.h>

# include <stdlib.h>

Page 23: Metodos de Ordenacao de Vetores

# include <ctype.h>

# define MAX 100001

struct data

{

int number;

char key[100];

}DataBase[MAX], VectorSort[MAX];

int CounterNum[MAX];

int size = 0;

int main (void)

{

int i = 0;

while(scanf("%d%s",&DataBase[size].number,DataBase[size].key) >= 1)

size++;

int aux[2] = {0,0};

for(i = 0; i <= size;i++)

aux[DataBase[i].number]++;

aux[1] += aux[0];

for(i = size - 1;i >= 0;i--)

VectorSort[--aux[DataBase[i].number]] = DataBase[i];

for(i = 0; i < size;i++)

printf("Number: %d --- Key: %s\n",VectorSort[i].number,VectorSort[i].key);

return 0;

}

Gnome sort

Origem: Wikipédia, a enciclopédia livre.

Algoritmo similiar ao Insertion sort com a diferença que o Gnome sort leva um elemento para sua posição correta, com uma

seqüencia grande de trocas assim como o Bubble sort

O algoritmo percorre o vetor comparando seus elementos dois a dois, assim que ele encontra um elemento que está na

posição incorreta, ou seja, um número maior antes de um menor, ele troca a posição dos elementos, e volta com este elemento

até que encontre o seu respectivo lugar.

Características

Complexidade de tempo: Θ(n²)

Page 24: Metodos de Ordenacao de Vetores

[editar]Implementações

[editar]Código em C

# include <stdio.h>

# include <stdlib.h>

# include <ctype.h>

# include <string.h>

# include <stdbool.h>

# define MAX 100001

int VectorSort[MAX];

int size = 0;

void swap(int * ,int *);

void GnomeSort();

int main (void)

{

while(scanf("%d",&VectorSort[size]) >= 1)

size++;

GnomeSort();

return 0;

}

void swap(int *A, int *B)

{

int C = *A;

* A = *B;

* B = C;

}

void GnomeSort()

{

int next = 0, previous = 0;

int i = 0;

for(i = 0; i < size ; i++)

{

if(VectorSort[i] > VectorSort[i + 1])

{

previous = i;

next = i + 1;

while(VectorSort[previous] > VectorSort[next])

{

swap(&VectorSort[previous],&VectorSort[next]);

previous--;

next--;

}

}

}

for(i = 0; i < size; i++)

Page 25: Metodos de Ordenacao de Vetores

printf("%d\n",VectorSort[i]);

}

[editar]Código em C++ versão 1

template<class T>

void gnome_sort( std::vector<T> &lista )

{

std::vector<T>::size_type i = 1;

while( i < lista.size() )

{

if( i == 0 || lista.at( i-1 ) <= lista.at( i ) )

{

i++;

}

else

{

std::swap( lista[ i - 1 ], lista [ i ] );

--i;

}

}

}

[editar]Código em C++ versão 2

template<class T>

void gnome_sort( std::vector<T> &lista )

{

std::vector<T>::iterator elem = lista.begin()+1;

while( elem != lista.end() )

{

if( elem == lista.begin() || *(elem-1) <= *elem )

{

++elem;

}

else

{

std::iter_swap( elem-1, elem );

--elem;

}

}

}

[editar]Código em Java

import java.util.ArrayList;

import java.util.Collection;

import java.util.HashSet;

import java.util.List;

import java.util.Random;

import java.util.Set;

/**

* Implementa e executa o algoritmo Gnome Sort

*

* @author Dielson Sales, Marcos Paulo J. Melo Silva

* /

Page 26: Metodos de Ordenacao de Vetores

public class GnomeSort<E extends Comparable<? super E>> {

/**

* Ordena uma coleção de dados comparáveis usando o Gnome Sort.

* @param vector uma lista de dados comparáveis

* @return uma lista com os dados ordenados

* /

public Collection<E> sort(Collection<E> vector) {

int i = 1;

List<E> result = new ArrayList<E>(vector);

while (i < result.size()) {

if (i == 0 || result.get(i - 1).compareTo(result.get(i))<= 0) {

i++;

} else {

E temp = result.get(i - 1);

result.set(i - 1, result.get(i));

result.set(i, temp);

i--;

}

}

return result;

}

/**

* Execução do algoritmo de ordenação Gnome Sort.

* /

public static void main(String[] args) {

GnomeSort<Integer> gnomeSort = new GnomeSort<Integer>();

final int size = 50;

final Random random = new Random();

List<Integer> list = new ArrayList<Integer>(size);

for (int i = 0; i < size; i++) {

list.add(random.nextInt());

}

// Lista com os dados já ordenados.

Set<Integer> sortedList = new HashSet<Integer>(gnomeSort.sort(list));

}

}

/**

* Exemplo de código em Java

* Autores: Marcos Paulo J. de Melo Silva e Dielson Sales de Carvalho;

Page 27: Metodos de Ordenacao de Vetores

* Instituição: Universidade Federal de Alagoas (UFAL);

* /

[editar]Código em Java

/*

* Autor: Felipe da Silva Travassos

* Graduando em Ciência da Computação - UFCG

*/

public static Integer[] gnomeSort(Integer[] array){

int pivout = 0;

int aux;

while(pivout<(array.length-1)){

if(array[pivout]>array[pivout+1]){

aux = array[pivout];

array[pivout] = array[pivout+1];

array[pivout+1] = aux;

if(pivout>0){

pivout-=2;

}

}

pivout++;

}

return array;

}

Heapsort Origem: Wikipédia, a enciclopédia livre.

O algoritmo heapsort é um algoritmo de ordenação generalista, e faz parte da família de algoritmos de ordenação por seleção.

Foi desenvolvido em 1964 porRobert W. Floyd e J.W.J. Williams.

[editar]Definição

Tem um desempenho em tempo de execução muito bom em conjuntos ordenados aleatoriamente, tem um uso de memória

bem comportado e o seu desempenho em pior cenário é praticamente igual ao desempenho em cenário médio. Alguns

algoritmos de ordenação rápidos têm desempenhos espectacularmente ruins no pior cenário, quer em tempo de execução,

quer no uso da memória. O Heapsort trabalha no lugar e o tempo de execução em pior cenário para ordenar n elementos é

de O (n lg n). Lê-se logaritmo (ou log) de "n" na base 2. Para valores de n, razoavelmente grande, o termo lg n é quase

constante, de modo que o tempo de ordenação é quase linear com o número de itens a ordenar.

[editar]Características

Comparações no pior caso: 2n log2n + O(n) é o mesmo que 2n lgn + O(n)

Trocas no pior caso: n log2n + O(n) é o mesmo que n lgn + O(n)

Melhor e pior caso: O(n log2n) é o mesmo que O(n lgn)

Page 28: Metodos de Ordenacao de Vetores

[editar]Funcionamento

O heapsort utiliza uma estrutura de dados chamada heap, para ordenar os elementos a medida que os insere na estrutura.

Assim, ao final das inserções, os elementos podem ser sucessivamente removidos da raiz da heap, na ordem desejada,

lembrando-se sempre de manter a propriedade de max-heap.

A heap pode ser representada como uma árvore (uma árvore binária com propriedades especiais[2]

) ou como um vetor. Para

uma ordenação crescente, deve ser construído uma heap mínima (o menor elemento fica na raiz). Para uma ordenação

decrescente, deve ser construído uma heap máxima (o maior elemento fica na raiz).

[editar]Implementações

[editar]Código em C

void heapsort(tipo a[], int n)

{

int i = n/2, pai, filho;

tipo t;

for (;;)

{

if (i > 0)

{

i--;

t = a[i];

}

else

{

n--;

if (n == 0)

return;

t = a[n];

a[n] = a[0];

}

pai = i;

filho = i*2 + 1;

while (filho < n)

{

if ((filho + 1 < n) && (a[filho + 1] > a[filho]))

filho++;

if (a[filho] > t)

{

a[pai] = a[filho];

pai = filho;

filho = pai*2 + 1;

}

else

break;

}

a[pai] = t;

}

}

Page 29: Metodos de Ordenacao de Vetores

[editar]Código em C++

template<class T>

void heap_sort( std::vector<T> &lista )

{

int tam = static_cast<int>( lista.size() ), i;

for( i = tam/2 - 1; i >= 0; --i )

{

maxHeapify(lista, i , tam );

}

std::vector<T>::reverse_iterator elem;

for( elem = lista.rbegin(); elem != lista.rend(); elem++ )

{

std::iter_swap( elem, lista.begin() );

maxHeapify( lista, 0, --tam );

}

}

template<class T>

void maxHeapify( std::vector<T> &lista, const int pos, const int n )

{

int max = 2 * pos + 1;

if( max < n )

{

if( (max+1) < n && lista.at(max) < lista.at(max+1) )

{

++max;

}

if( lista.at(max) > lista.at(pos) )

{

std::swap( lista[max], lista[pos] );

maxHeapify( lista, max, n );

}

}

}

[editar]Código em Java

public static void heapSort(int[] v)

{

buildMaxHeap(v);

int n = v.length;

for (int i = v.length - 1; i > 0; i--)

{

swap(v, i , 0);

maxHeapify(v, 0, --n);

}

}

private static void buildMaxHeap(int[] v)

{

for (int i = v.length/2 - 1; i >= 0; i--)

Page 30: Metodos de Ordenacao de Vetores

maxHeapify(v, i , v. length );

}

private static void maxHeapify(int[] v, int pos, int n)

{

int maxi;

int l = 2 * pos + 1;

int right = 2 * pos + 2;

if ( (l < n) && (v[l] > v[pos]) )

{

maxi = l;

}

else

{

maxi = pos;

}

if (right < n && v[right] > v[maxi])

{

maxi = right;

}

if (maxi != pos)

{

swap(v, pos, maxi);

maxHeapify(v, maxi, n);

}

}

public static void swap ( int[ ] v, int j, int aposJ )

{

int aux = v [ j ];

v [ j ] = v [ aposJ ];

v [ aposJ ] = aux;

}

[editar]Código em Java (5.0)

public static <T extends Comparable<? super T>> void heapSort(T[] v) {

buildMaxHeap(v);

int n = v.length;

for (int i = v.length - 1; i > 0; i--) {

swap(v, i, 0);

maxHeapify(v, 0, --n);

}

}

private static <T extends Comparable<? super T>> void buildMaxHeap(T v[]) {

for (int i = v.length / 2 - 1; i >= 0; i--)

maxHeapify(v, i, v.length);

}

private static <T extends Comparable<? super T>> void maxHeapify(T[] v, int pos,

int n) {

int max = 2 * pos + 1, right = max + 1;

if (max < n) {

if (right < n && v[max].compareTo(v[right]) < 0)

max = right;

Page 31: Metodos de Ordenacao de Vetores

if (v[max].compareTo(v[pos]) > 0) {

swap(v, max, pos);

maxHeapify(v, max, n);

}

}

}

public static void swap(Object[] v, int j, int aposJ) {

Object aux = v[j];

v[j] = v[aposJ];

v[aposJ] = aux;

}

Insertion sort Origem: Wikipédia, a enciclopédia livre.

Insertion sort, ou ordenação por inserção, é um simples algoritmo de ordenação, eficiente quando aplicado a um pequeno

número de elementos. Em termos gerais, ele percorre um vetor de elementos da esquerda para a direita e à medida que

avança vai deixando os elementos mais à esquerda ordenados. O algoritmo de inserção funciona da mesma maneira com que

muitas pessoas ordenam cartas em um jogo de baralho como o pôquer.[1]

[editar]Características

Menor número de trocas e comparações entre os algoritmos de ordenação O(n) quando o vetor está ordenado.

Pior caso O(n²)

[editar]Implementações

[editar]Java

public static void insertionSort(int[] array)

{

for (int i = 1; i < array.length; i++)

{

int a = array[i];

for (int j = i - 1; j >= 0 && array[j] > a; j--)

{

array[j + 1] = array[j];

array[j] = a;

}

}

}

Page 32: Metodos de Ordenacao de Vetores

[editar]C

void insertionSort(int V[], int tam)

{

int i, j, aux;

for(i = 1; i < tam; i++){

j = i;

while((V[j] < V[j - 1])&&(j!=0)) {

aux = V[j];

V[j] = V[j - 1];

V[j - 1] = aux;

j--;

}

}

}

[editar]C++

void Inserction(int n, int vetor[]){

int j,i,key;

for(j = 1; j < n; j++){

key = vetor[j];

i = j - 1;

while(i >= 0 && vetor[i] > key){

vetor[i + 1] = vetor[i];

i = i - 1;

}

vetor[i + 1] = key;

}

}

Merge sort Origem: Wikipédia, a enciclopédia livre.

O merge sort, ou ordenação por mistura, é um exemplo de algoritmo de ordenação do tipo dividir-para-conquistar.

Sua ideia básica consiste em Dividir(o problema em vários sub-problemas e resolver esses sub-problemas através da

recursividade) e Conquistar(após todos os sub-problemas terem sido resolvidos ocorre a conquista que é a união das

resoluções dos sub-problemas).Como o algoritmo do Merge Sort usa a recursividade em alguns problemas esta técnica não é

muito eficiente devido ao alto consumo de memória e tempo de execução.

Os três passos úteis dos algoritmos dividir-para-conquistar, ou divide and conquer, que se aplicam ao merge sort são:

1. Dividir: Dividir os dados em subsequências pequenas;

2. Conquistar: Classificar as duas metades recursivamente aplicando omerge sort;

Page 33: Metodos de Ordenacao de Vetores

3. Combinar: Juntar as duas metades em um único conjunto já classificado.

[editar]Características

Complexidade de tempo: Θ(n log2 n)

Complexidade de espaço: Θ(n)

É possível implementar o merge sort utilizando somente um vetor auxiliar ao longo de toda a execução, tornando assim a

complexidade de espaço adicional igual a Θ(n log n).

É possível também implementar o algoritmo com espaço adicional Θ(1)

Algoritmo Criado por Von Neumann em 1945.

[editar]Desvantagens

Implementação complexa

Ideia complexa

Utiliza funções recursivas

[editar]Implementações

[editar]C

void merge(int vec[], int vecSize) {

int mid;

int i, j, k;

int* tmp;

tmp = (int*) malloc(vecSize * sizeof(int));

if (tmp == NULL) {

exit(1);

}

mid = vecSize / 2;

i = 0;

j = mid;

k = 0;

while (i < mid && j < vecSize) {

if (vec[i] < vec[j]) {

tmp[k] = vec[i];

++i;

}

else {

tmp[k] = vec[j];

++j;

}

++k;

}

if (i == mid) {

while (j < vecSize) {

tmp[k] = vec[j];

++j;

++k;

Page 34: Metodos de Ordenacao de Vetores

}

}

else {

while (i < mid) {

tmp[k] = vec[i];

++i;

++k;

}

}

for (i = 0; i < vecSize; ++i) {

vec[i] = tmp[i];

}

free(tmp);

}

void mergeSort(int vec[], int vecSize) {

int mid;

if (vecSize > 1) {

mid = vecSize / 2;

mergeSort(vec, mid);

mergeSort(vec + mid, vecSize - mid);

merge(vec, vecSize);

}

}

[editar]Código em C++

#include <algorithm>

#include <iostream>

#include <vector>

std::vector<int> merge_sort(const std::vector<int> &data)

{

if (data.size() <= 1) {

return data;

}

int middle = data.size() / 2;

std::vector<int> left(data.begin(), data.begin()+middle);

std::vector<int> right(data.begin()+middle, data.end());

left = merge_sort(left);

right = merge_sort(right);

std::vector<int> result(data.size());

std::merge(left.begin(), left.end(),

right.begin(), right.end(),

result.begin());

return result;

}

Page 35: Metodos de Ordenacao de Vetores

Quicksort

Origem: Wikipédia, a enciclopédia livre.

O algoritmo Quicksort é um método de ordenação muito rápido e eficiente, inventado por C.A.R. Hoare em 1960[1]

, quando

visitou a Universidade de Moscovocomo estudante. Naquela época, Hoare trabalhou em um projeto de tradução de

máquina para o National Physical Laboratory. Ele criou o 'Quicksort ao tentar traduzir um dicionário de inglês para russo,

ordenando as palavras, tendo como objetivo reduzir o problema original em subproblemas que possam ser resolvidos mais facil

e rapidamente. Foi publicado em 1962 após uma série de refinamentos.[2]

O Quicksort é um algoritmo de ordenação por comparação não-estável.

O Quicksort adota a estratégia de divisão e conquista. A estratégia consiste em rearranjar as chaves de modo que as chaves

"menores" precedam as chaves "maiores". Em seguida o Quicksort ordena as duas sublistas de chaves menores e maiores

recursivamente até que a lista completa se encontre ordenada. [3]

Os passos são:

1. Escolha um elemento da lista, denominado pivô;

2. Rearranje a lista de forma que todos os elementos anteriores ao pivô sejam menores que ele, e todos os elementos

posteriores ao pivô sejam maiores que ele. Ao fim do processo o pivô estará em sua posição final e haverá duas

sublistas não ordenadas. Essa operação é denominada partição;

3. Recursivamente ordene a sublista dos elementos menores e a sublista dos elementos maiores;

A base da recursão são as listas de tamanho zero ou um, que estão sempre ordenadas. O processo é finito, pois a cada

iteração pelo menos um elemento é posto em sua posição final e não será mais manipulado na iteração seguinte.

[editar]Complexidade

Complexidade de tempo: θ(n lg2 n) no melhor caso e caso médio e θ(n2) no pior caso;

Complexidade de espaço: θ(lg2 n) no melhor caso e no caso médio e θ(lg2 n) no pior caso. R. Sedgewick desenvolveu uma

versão do Quicksort com partição recursão de cauda que tem complexidade θ(n2) no pior caso.

[editar]Implementações

[editar]C++

#include <algorithm>

#include <iterator>

#include <functional>

using namespace std;

template <typename T>

void sort(T begin, T end) {

if (begin != end) {

T middle = partition (begin, end, bind2nd(less<iterator_traits<T>::value_type>(),

*begin));

sort (begin, middle);

sort (max(begin + 1, middle), end);

}

}

[editar]C

void swap(int* a, int* b) {

int tmp;

Page 36: Metodos de Ordenacao de Vetores

tmp = *a;

*a = *b;

*b = tmp;

}

int partition(int vec[], int left, int right) {

int i, j;

i = left;

for (j = left + 1; j <= right; ++j) {

if (vec[j] < vec[left]) {

++i;

swap(&vec[i], &vec[j]);

}

}

swap(&vec[left], &vec[i]);

return i;

}

void quickSort(int vec[], int left, int right) {

int r;

if (right > left) {

r = partition(vec, left, right);

quickSort(vec, left, r - 1);

quickSort(vec, r + 1, right);

}

}

Implementação quicksort testado com ate 1000000 de elementos para dados crescente, decrescente e aleatório

void swap(int *a, int i, int j) {

int t = a[i];

a[i] = a[j];

a[j] = t;

}

int partition(int *a, int left,int right,int pivot)

{

int pos, i;

swap(a, pivot, right);

pos = left;

for(i = left; i < right; i++)

{

if (a[i] < a[right])

{

swap(a, i, pos);

pos++;

}

}

swap(a, right, pos);

return pos;

}

Page 37: Metodos de Ordenacao de Vetores

void quick(int *a, int left, int right)

{

if (left < right)

{

int pivot = (left+right)/2;

int pos = partition(a,left,right,pivot);

quick(a,left,pos-1);

quick(a,pos+1,right);

}

}

Implementaçao usando 'fat pivot':

void sort(int array[], int begin, int end) {

int pivot = array[begin];

int i = begin + 1, j = end, k = end;

int t;

while (i < j) {

if (array[i] < pivot) i++;

else if (array[i] > pivot) {

j--; k--;

t = array[i];

array[i] = array[j];

array[j] = array[k];

array[k] = t; }

else {

j--;

swap(array[i], array[j]);

} }

i--;

swap(array[begin], array[i]);

if (i - begin > 1)

sort(array, begin, i);

if (end - k > 1)

sort(array, k, end);

}

Lembrando que quando você for chamar a função recursiva terá que chamar a mesma da seguinte forma

ordenar_quicksort_nome(0,n-1). O 0(zero) serve para o início receber a posição zero do vetor e o fim será o tamanho do vetor -

1.

void ordenar_quicksort_nome(int ini, int fim)

{

int i = ini, f = fim;

char pivo[50];

strcpy(pivo,vetor[(ini+fim)/2]);

if (i<=f)

{

while (strcmpi(vetor[i],pivo)<0) i++;

while (strcmpi(vetor[f],pivo)>0) f--;

if (i<=f)

{

strcpy (aux_char,vetor[i]);

strcpy (vetor[i],vetor[f]);

strcpy (vetor[f],aux_char);

Page 38: Metodos de Ordenacao de Vetores

i++; f--;

}

}

if (f>ini) ordenar_quicksort_nome(ini,f);

if (i<fim) ordenar_quicksort_nome(i,fim);

}

[editar]JAVA

public static void quick_sort(int []v,int ini, int fim) {

int meio;

if (ini < fim) {

meio = partition(v, ini, fim);

quick_sort(v, ini, meio);

quick_sort(v, meio + 1, fim);

}

}

public static int partition(int []v, int ini, int fim) {

int pivo, topo, i;

pivo = v[ini];

topo = ini;

for (i = ini + 1; i <= fim; i++) {

if (v[i] < pivo) {

v[topo] = v[i];

v[i] = v[topo + 1];

topo++;

}

}

v[topo] = pivo;

return topo;

}

[editar]JAVA

public static void quickSort(int[] v, int inicio, int fim){

if(inicio<fim){

int pivo=inicio, i=fim, vPivo=v[pivo];

while(pivo<i){

if(vPivo>v[i]){

v[pivo]=v[i];

pivo=i;

i=inicio+1;

while(pivo>i){

if(vPivo<v[i]){

v[pivo]=v[i];

pivo=i;

i=fim;

break;

}else

i++;

}

} else

i--;

}

Page 39: Metodos de Ordenacao de Vetores

v[pivo]=vPivo;

quicksort(v, inicio, pivo-1);

quicksort(v, pivo+1, fim);

}

}

Comparação com outros algoritmos de ordenação

Quicksort é uma versão optimizada de uma árvore binária ordenada. Em vez de introduzir itens sequencialmente numa árvore

explicita, o Quicksort organiza-os correntemente na árvore onde está implícito, fazendo-o com chamadas recursivas à mesma.

O algoritmo faz exactamente as mesmas comparações, mas com uma ordem diferente.

O algoritmo que mais se familiariza com o Quicksort é o Heapsort. Para o pior caso neste algoritmo temos .

Mas, o Heapsort em média trata-se de uma algoritmo mais lento que o Quicksort, embora tenha sido muito debatido essa

afirmação. No Quicksort permanece o caso do pior caso, à excepção quando se trata de usar a variante Intro sort, que muda

para Heapsort quando um pior caso é detectado. Caso se saiba à partida que será necessário o uso do heapsort é

aconselhável usá-lo directamente, do que usar o introsort e depois chamar o heapsort, torna mais rápido o algoritmo.

O Quicksort também compete com o Mergesort, outro algoritmo de ordenação recursiva, tendo este o benefício de ter como

pior caso . Mergesort, ao contrário do Quicksort e do Heapsort, é estável e pode facilmente ser adptado para

operar em listas encadeadas e em listas bastantes grandes alojadas num tipo de acesso lento a média como um Network-

Attached Storage ou num disco. Embora o Quicksort possa ser operado em listas encadeadas, por vezes escolhendo um mau

pivô sem acesso aleatório. A maior desvantagem do Mergesort é que quando opera em arrays, requer de espaço para

o melhor caso, considerando que o Quicksort com um particionamento espacial e com recursão utiliza apenas de

espaço.

Bucket sort com dois buckets é muito parecido ao Quicksort (quase idêntico), o pivô neste caso é garantidamente o valor do

meio do vector.

Selection sort

Origem: Wikipédia, a enciclopédia livre.

O selection sort (do inglês, ordenação por seleção) é um algoritmo de ordenação baseado em se passar sempre o menor

valor do vetor para a primeira posição (ou o maior dependendo da ordem requerida), depois o de segundo menor valor para a

segunda posição, e assim é feito sucessivamente com os (n-1) elementos restantes, até os últimos dois elementos.

== Complexidade == Muito Complexo

O algoritmo possui complexidade enquanto que, por exemplo, os algoritmos Heapsort e Mergesort possuem

complexidades .

[editar]Implementações

[editar]C

void selection_sort(int num[], int tam)

{

int i, j, min;

for (i = 0; i < (tam-1); i++)

Page 40: Metodos de Ordenacao de Vetores

{

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;

}

}

}

Código da ordenação SelectionSort com strings

void ordenar_selecao_nome() {

int i,j,n;

for(i=0; i<n-1; i++) {

for(j=i+1; j<n; j++) {

if(strcmp(vetor[i], vetor[j])>0) {

strcpy(aux_char, vetor[i]);

strcpy(vetor[i], vetor[j]);

strcpy(vetor[j], aux_char);

}

}

}

[editar]Código em C++

template<class T>

void selection_sort( std::vector<T> &lista )

{

for( std::vector<T>::iterator it = lista.begin(); it != lista.end()-1; ++it )

{

std::iter_swap( it, std::min_element( it, lista.end() ) );

}

}

[editar]Código em Java

public static void SelectionSort(int[] v) {

int index_min;

int aux;

for (int i = 0; i < v.length; i++) {

index_min = i;

for (int j = i + 1; j < v.length; j++) {

if (v[j] < v[index_min]) {

index_min = j;

}

}

if (index_min != i) {

aux = v[index_min];

v[index_min] = v[i];

v[i] = aux;

}

}

Page 41: Metodos de Ordenacao de Vetores

}

Shell sort Origem: Wikipédia, a enciclopédia livre.

Criado por Donald Shell em 1959,[1]

publicado pela Universidade de Cincinnati, Shell sort é o mais

eficiente algoritmo de classificação dentre os de complexidade quadrática. É um refinamento do método de inserção direta.[2]

O

algoritmo difere do método de inserção direta pelo fato de no lugar de considerar o array a ser ordenado como um único

segmento, ele considera vários segmentos sendo aplicado o método de inserção direta em cada um deles.[3]

Basicamente o

algoritmo passa várias vezes pela lista dividindo o grupo maior em menores. Nos grupos menores é aplicado o método

[editar]Implementações do algoritmo

[editar]Código em Java

public static void shellSort(Integer[] nums) {

int n = nums.length;

int h = n / 2;

int c, j;

while (h > 0) {

for (int i = h; i < n; i++) {

c = nums[i];

j = i;

while (j >= h && nums[j - h] > c) {

nums[j] = nums[j - h];

j = j - h;

}

nums[j] = c;

}

h = h / 2;

}

}

[editar]Código em C++

void ShellSort( apvector <int> &num) {

int i, temp, flag = 1, numLength = num.length( );

int d = numLength;

while( flag || (d > 1)) { // boolean flag (true when not equal to 0)

flag = 0; // reset flag to 0 to check for future swaps

d = (d+1) / 2;

for (i = 0; i < (numLength - d); i++) {

if (num[i + d] > num[i]) {

temp = num[i + d]; // swap positions i+d and i

num[i + d] = num[i];

num[i] = temp;

flag = 1; // tells swap has occurred

}

}

}

return;

}

Page 42: Metodos de Ordenacao de Vetores

[editar]Código em C

void shellSort(int * vet, int size) {

int i , j , value;

int gap = 1;

do {

gap = 3*gap+1;

} while(gap < size);

do {

gap /= 3;

for(i = gap; i < size; i++) {

value =vet[i];

j = i - gap;

while (j >= 0 && value < vet[j]) {

vet [j + gap] =vet[j];

j -= gap;

}

vet [j + gap] = value;

}

} while ( gap > 1);

}

[editar]Exemplo de execução

Execução:

Dado o vetor de entrada: 12, 43, 1, 6, 56, 23, 52, 9

12, 43, 1, 6, 56, 23, 52, 9

12, 43, 1, 6, 56, 23, 52, 9

1, 43, 12, 6, 56, 23, 52, 9

1, 6, 12, 23, 56, 43, 52, 9

1, 6, 12, 23, 52, 43, 56, 9

1, 6, 12, 23, 52, 9, 56, 43

1, 6, 12, 9, 52, 23, 56, 43

1, 6, 9, 12, 52, 23, 56, 43

1, 6, 9, 12, 23, 52, 56, 43

1, 6, 9, 12, 23, 52, 43, 56

1, 6, 9, 12, 23, 43, 52, 56

Em negrito estão os números trocados na atual iteração.

Após as seguintes trocas acima, obtemos o vetor ordenado: 1, 6, 9, 12, 23, 43, 52, 56.

[editar]Conclusão

A ordenação Shell utiliza a quebra sucessiva da sequência a ser ordenada e implementa a ordenação por inserção na

sequência obtida. Por ser um método de complexidade O(n^2 ) não é aconselhável a sua implementação para sequências

grandes, mas possui uma boa eficiência para as pequenas e medianas.

Page 43: Metodos de Ordenacao de Vetores