• Nenhum resultado encontrado

Algoritmos Eficientes de Ordenação

N/A
N/A
Protected

Academic year: 2021

Share "Algoritmos Eficientes de Ordenação"

Copied!
22
0
0

Texto

(1)

Algoritmos Eficientes de Ordenação

Quick Sort

Merge Sort

Heap Sort

Utilizar informação das chaves:

Counting Sort

(2)

Quick Sort

int partition(Item a[], int l, int r) { int i = l-1, j = r; Item v = a[r];

for (;;) {

while (less(a[++i], v)) ;

while (less(v, a[--j])) if (j == l) break; if (i >= j) break; exch(a[i], a[j]); } exch(a[i], a[r]); return i; }

void quicksort(Item a[], int l, int r) { int i; if (r <= l) return; i = partition(a, l, r); quicksort(a, l, i-1); quicksort(a, i+1, r); } AED 2002/2003 – p.2/22

(3)

Quick Sort – Complexidade

Complexidade depende das chaves

Para array já ordenado, tempo de execução é







Normalmente, para qualquer partição razoável do

vector a cada passo do algoritmo, complexidade é

    

Não é estável

(4)

Merge Sort

Item aux[maxN];

merge(Item a[], int l, int m, int r) { int i, j, k;

for (i = m+1; i > l; i--) aux[i-1] = a[i-1]; for (j = m; j < r; j++) aux[r+m-j] = a[j+1]; for (k = l; k <= r; k++)

if (less(aux[i], aux[j]))

a[k] = aux[i++]; else a[k] = aux[j--]; }

void mergesort(Item a[], int l, int r) { int m = (r+l)/2; if (r <= l) return; mergesort(a, l, m); mergesort(a, m+1, r); merge(a, l, m, r); } AED 2002/2003 – p.4/22

(5)

Merge Sort – Complexidade

Tempo de execução:

                  

Fácil de verificar quando



é potência de 2, e no caso

geral recorrendo a indução

Complexidade pior caso é



    

É estável

(6)

Merge Sort – Bottom-Up

#define min(A, B) (A < B) ? A : B

void mergesortBU(Item a[], int l, int r) { int i, m;

for (m = 1; m < r-l; m = m+m)

for (i = l; i <= r-m; i += m+m)

merge(a, i, i+m-1, min(i+m+m-1, r)); }

(7)

Merge Sort com Listas

link merge(link a, link b)

{ struct node head; link c = &head; while ((a != NULL) && (b != NULL))

if (less(a->item, b->item)) { c->next = a; c = a; a = a->next; } else { c->next = b; c = b; b = b->next; } c->next = (a == NULL) ? b : a; return head.next; } link mergesort(link c) { link a, b;

if (c->next == NULL) return c; a = c; b = c->next;

while ((b != NULL) && (b->next != NULL)) { c = c->next; b = b->next->next; } b = c->next; c->next = NULL;

return merge(mergesort(a), mergesort(b)); }

(8)

Heap Sort

#define pq(A) a[l-1+A]

void heapsort(Item a[], int l, int r) { int k, N = r-l+1; for (k = N/2; k >= 1; k--) fixDown(&pq(0), k, N); while (N > 1) { exch(pq(1), pq(N)); fixDown(&pq(0), 1, --N); } } AED 2002/2003 – p.8/22

(9)

Heap Sort – Complexidade

Construção do amontoado (ciclo

for):

    

no pior caso

É possível assegurar

  

Colocação das chaves (ciclo

while):

    

no pior caso

Complexidade pior caso é



    

Não é estável

(10)

Avaliação Experimental

N Quick Merge Heap

12500

2

5

3

25000

7

11

8

50000

13

24

18

100000

27

52

42

200000

58

111

100

400000

122

238

232

800000

261

520

542

AED 2002/2003 – p.10/22

(11)

Ordenação por Comparação

Algoritmos de ordenação baseados em comparações

são

    

Para



chaves existem

 

ordenações possíveis das

chaves

Algoritmo de ordenação por comparação utiliza

comparações de pares de chaves para seleccionar

uma das





ordenações

Escolher uma folha em árvore com





folhas

Altura da árvore é não inferior



         

É possível obter algoritmos mais eficientes desde que

não sejam baseados em comparações:

Utilizar informação quanto às chaves utilizadas

Counting Sort

(12)

Counting Sort – Motivação

Ordenar

    

Chaves podem tomar valor entre 0 e





Se existem



chaves com valor 0, então ocupam as

primeiras

 

posições do array final, 0 a









Se existem

 !

chaves com valor 1, então ocupam as

posições

 

a

    !  

posições do array final

...

Necessário vectores auxiliares para guardar contagens

e para construir array ordenado

(13)

Counting Sort I

void distcount(int a[], int l, int r) { int i, j, cnt[M+1];

int b[maxN];

for (j = 0; j <= M; j++) cnt[j] = 0; for (i = l; i <= r; i++) cnt[a[i]+1]++;

for (j = 1; j < M; j++) cnt[j] += cnt[j-1];

for (i = l; i <= r; i++) b[cnt[a[i]]++] = a[i]; for (i = l; i <= r; i++) a[i] = b[i];

(14)

Counting Sort – Complexidade

Dois ciclos relativos à dimensão das chaves

Três ciclos relativos às



chaves

Complexidade:

    AED 2002/2003 – p.14/22

(15)

Counting Sort II

void distcount(int a[], int l, int r) { int i, j, cnt[M];

int b[maxN];

for (j = 0; j < M; j++) cnt[j] = 0; for (i = l; i <= r; i++) cnt[a[i]]++;

for (j = 1; j < M; j++) cnt[j] += cnt[j-1]; for (i = r; i >= l; i--) b[--cnt[a[i]]] = a[i]; for (i = l; i <= r; i++) a[i] = b[i];

}

Diferenças??

Definição do valor

cnt[j]

Estabilidade do algoritmo ??

(16)

Radix Sort – Definições

#define bitsword 32 #define bitsbyte 8 #define bytesword 4

#define R (1 << bitsbyte)

#define digit(A, B) (((A) >> (bitsword-((B)+1)*bitsbyte)) & (R-1))

(17)

Radix Sort I

#define bin(A) l+count[A]

void radixMSD(Item a[], int l, int r, int w) { int i, j, count[R+1]; if (w > bytesword) return; if (r-l <= M) { insertion(a, l, r); return; } for (j = 0; j < R; j++) count[j] = 0; for (i = l; i <= r; i++) count[digit(a[i], w) + 1]++; for (j = 1; j < R; j++) count[j] += count[j-1]; for (i = l; i <= r; i++) aux[l+count[digit(a[i], w)]++] = a[i]; for (i = l; i <= r; i++) a[i] = aux[i]; radixMSD(a, l, bin(0)-1, w+1);

for (j = 0; j < R-1; j++)

radixMSD(a, bin(j), bin(j+1)-1, w+1); }

(18)

Radix Sort I – Operação

Utilizar dígitos, do maior peso para o menor peso:

Colocar chaves em

caixas

Ordenar elementos de cada caixa utilizando dígitos

subsequentes

Se número de elementos não superior a

, utilizar

insertion sort

(19)

Radix Sort II

void radixLSD(Item a[], int l, int r) { int i, j, w, count[R+1]; for (w = bytesword-1; w >= 0; w--) { for (j = 0; j < R; j++) count[j] = 0; for (i = l; i <= r; i++) count[digit(a[i], w) + 1]++; for (j = 1; j < R; j++) count[j] += count[j-1]; for (i = l; i <= r; i++) aux[count[digit(a[i], w)]++] = a[i]; for (i = l; i <= r; i++) a[i] = aux[i]; }

(20)

Radix Sort II – Operação

Utilizar dígitos, do menor peso para o maior peso:

Ordenar todo o vector utilizando counting sort

utilizando cada dígito

(21)

Eficiência dos Radix Sorts

Radix Sort I

Tempo de execução cresce com número de bytes

dos elementos a ordenar

Radix Sort II

 #" $ %  & 

, para chaves com

$

bits

Espaço adicional:

&

(22)

Avaliação Experimental

N Quick MSD LSD

12500

2

28

4

25000

5

29

8

50000

10

35

18

100000

21

47

39

200000

49

72

81

400000

102

581

169

800000

223 6064

328

AED 2002/2003 – p.22/22

Referências

Documentos relacionados

Para atrair os clientes e gerar lealdade, as empresas precisam não só repensar seus documentos existentes, mas também aproveitar formatos e canais eletrônicos e utilizar o amplo

Fine (About Uncirculated/ Extremely Fine) - BELA (Bela) - Moeda quase não circulada, que apresenta ainda algum brilho original, ou patine, podendo evidenciar ligeiras marcas

Constância do output de raios X versus taxa de dose ±2% em relação aos valores de referência Constância do output de raios X versus ângulo do gantry ±1% em relação aos valores

O problema é que essa divulgação, via de regra, ocorre de forma descontextualizada, fragmentada, como foi detectado mais uma vez pela pesquisa Fundep/UFMG/Andi (2009),

Marinha Grande Terça a domingo 10h00 às 13h00 e 14h00 às 18h00 +351 244 573 377 museu.vidro@cm-mgrande.pt Entradas | 1,50 euros Visitas guiadas por marcação prévia. OFICINAS

Em Entre Douro e Minho e no Algarve a superfície total das explorações agrícolas ocupa cerca de 1/3 da área geográfica das regiões, sendo que a Beira Litoral é a

Interface de dados Object recognition Object height measurement Object height measurement Measurement of external dimension Measurement of inside dimension Measurement of

A célula cancerosa é originada de uma célula normal que foi induzida a mudar suas características naturais relacionadas à sua vida celular. Entre essas