Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Quicksort
Proposto por Hoare em 1960 e publicado em 1962. o algoritmo de ordenao interna mais rpido que se conhece para uma ampla variedade de situaes. Provavelmente o mais utilizado. A idia bsica dividir o problema de ordenar um conjunto com n itens em dois problemas menores. Os problemas menores so ordenados independentemente. Os resultados so combinados para produzir a soluo final.
Algoritmos e Estrutura de Dados I
David Menotti
Quicksort
A parte mais delicada do mtodo o processo de partio. O vetor A [Esq..Dir] rearranjado por meio da escolha arbitrria de um piv x. O vetor A particionado em duas partes:
David Menotti
Quicksort - Partio
David Menotti
Ao final, do algoritmo de partio: o vetor A[Esq..Dir] est particionado de tal forma que:
Os itens em A[Esq], A[Esq + 1], ..., A[j] so menores ou iguais a x; Os itens em A[i], A[i + 1], ..., A[Dir] so maiores ou iguais a x.
David Menotti
Quicksort - Exemplo
Exemplo:
3 6 4 5 1 7 2
David Menotti
Quicksort - Exemplo
3
Primeira partio Segunda partio
6 2 2
4 4 4
5 1 3
1 5 5
7 7 7
2 6 6
3 1
. . .
3 4 5 7 6
Continua...
terceira partio
David Menotti
Quicksort - Exemplo
1
quarta partio quinta partio
2 2 2
3 4 4
4 1 3
5 5 5
7 6 6
6 7 7
3 1
Final
David Menotti
Quicksort - Partio
void Particao(int Esq, int Dir, int *i, int *j, Item *A) { Item x, aux; *i = Esq; *j = Dir; x = A[(*i + *j)/2]; /* obtem o pivo x */ do { while (x.Chave > A[*i].Chave) (*i)++; while (x.Chave < A[*j].Chave) (*j)--; if (*i <= *j) { aux = A[*i]; A[*i] = A[*j]; A[*j] = aux; (*i)++; (*j)--; } } while (*i <= *j); }
David Menotti Algoritmos e Estrutura de Dados I
Quicksort
O anel interno da funo Particao extremamente simples. Razo pela qual o algoritmo Quicksort to rpido.
David Menotti
Quicksort - Funo
/* Entra aqui o procedimento Particao */ void Ordena(int Esq, int Dir, Item *A) { int i,j; Particao(Esq, Dir, &i, &j, A); if (Esq < j) Ordena(Esq, j, A); if (i < Dir) Ordena(i, Dir, A); } void QuickSort(Item *A, int n) { Ordena(0, n-1, A); //Ordena(1, *n, A); }
David Menotti Algoritmos e Estrutura de Dados I
Quicksort
Caractersticas
David Menotti
Quicksort
Anlise
Seja C(n) a funo que conta o nmero de comparaes. Pior caso: C(n) = O(n2)
O pior caso ocorre quando, sistematicamente, o piv escolhido como sendo um dos extremos de um arquivo j ordenado. Isto faz com que o procedimento Ordena seja chamado recursivamente n vezes, eliminando apenas um item em cada chamada. O pior caso pode ser evitado empregando pequenas modificaes no algoritmo. Para isso basta escolher trs itens quaisquer do vetor e usar a mediana dos trs como piv.
David Menotti
Quicksort
Anlise
Melhor caso:
Esta situao ocorre quando cada partio divide o arquivo em duas partes iguais.
Isso significa que em mdia o tempo de execuo do Quicksort O(n log n).
David Menotti
Quicksort
Vantagens:
extremamente eficiente para ordenar arquivos de dados. Necessita de apenas uma pequena pilha como memria auxiliar. Requer cerca de n log n comparaes em mdia para ordenar n itens. Tem um pior caso O(n2) comparaes. Sua implementao muito delicada e difcil:
Desvantagens:
Um pequeno engano pode levar a efeitos inesperados para algumas entradas de dados.
Algoritmos e Estrutura de Dados I
O mtodo no estvel.
David Menotti
Quicksort No Recursivo
void QuickSortNaoRec (Vetor A, Indice n) { TipoPilha pilha; TipoItem item; int esq, dir, i, j; FPVazia(&pilha); esq = 0; dir = n-1; item.dir = dir; item.esq = esq; Empilha(item,&pilha); do if (dir > esq) { Particao(A,esq,dir,&i, &j); item.dir = j; item.esq = esq; Empilha(item,&pilha); esq = i; } else { Desempilha(&pilha,&item); dir = item.dir; esq = item.esq; } while (!Vazia(pilha)); }
David Menotti Algoritmos e Estrutura de Dados I
Quicksort No Recursivo
void QuickSortNaoRec (Vetor A, Indice n) { TipoPilha pilha; TipoItem item; int esq, dir, i, j; FPVazia(&pilha); esq = 0; dir = n-1; item.dir = dir; item.esq = esq; Empilha(item, &pilha); do if (dir > esq) { Particao(A,esq,dir,&i, &j); if ((j-esq)>(dir-i)) { item.dir = j; item.esq = esq; Empilha(item, &pilha); esq = i; } else { item.esq = i; item.dir = dir; Empilha(item, &pilha); dir = j; } } else { Desempilha(&pilha,&item); dir = item.dir; esq = item.esq; } while (!Vazia(pilha)); }
David Menotti
David Menotti
Melhorias no Quicksort
Piv Mediana de trs No empilhar quando tem um s Melhor ainda: usar algoritmo de insero para vetores pequenos (menos de 10 ou 20 elementos) Escolha do lado a ser empilhado Melhoria no tempo de execuo de 25% a 30%
David Menotti