Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Ordenação, Notas de estudo de Engenharia Informática

Algoritmos de Ordenação

Tipologia: Notas de estudo

2012

Compartilhado em 25/11/2012

wellington-cassio-faria-8
wellington-cassio-faria-8 🇧🇷

4.5

(37)

129 documentos

1 / 25

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19

Pré-visualização parcial do texto

Baixe Ordenação e outras Notas de estudo em PDF para Engenharia Informática, somente na Docsity!

19 MAKROS Books Ordenação e Pesquisa No mundo da computação, talvez as tarefas mais fundamentais e extensivamente analisadas sejam ordenação e pesquisa. Essas rotinas são utilizadas em pratica- mente todos os programas de banco de dados, bem como em compiladores, in- terpretadores e sistemas operacionais. Este capítulo introduz os conceitos básicos de ordenação e pesquisa. Como você verá, ordenar e pesquisar ilustram diversas técnicas de programação em €. Como o objetivo de ordenar os dados geralmente é facilitar e acelerar o processo de pesquisa nesses dados, discutimos primeiro a ordenação. [6 Ordenação Ordenação é o processo de arranjar um conjunto de informações semelhantes numa ordem crescente ou decrescente. Especificamente, dada uma lista ordenada i de n elementos, então N< <=. <= in Muito embora a maioria dos compiladores forneça a função qsort) como parte da biblioteca padrão, você deve entender a ordenação por três razões. Pri- meiro, você não pode aplicar uma função generalizada como qgsort() a todas as situações. Segundo, pelo fato de qsortQ) ser parametrizada para operar em uma variedade de dados, ela roda mais lentamente que uma ordenação semelhante que opera sobre apenas um tipo de dado. (Generalização aumenta inerentemente o tempo de execução devido ao tempo de processamento extra necessário para 501 502 C — Completo e Total“ S Cla a Cap19 manipular os diversos tipos de dados.) Finalmente, como você verá, embora o algoritmo quicksort (usado por gsort() seja muito eficiente no caso geral, ele pode não ser a melhor ordenação para situações especiais. Existem duas categorias gerais de algoritmos de ordenação: algoritmos que ordenam matrizes (tanto na memória como em arquivos de acesso aleatório em disco) e algoritmos que ordenam arquivos sequenciais em disco ou fita. Este capítulo enfoca apenas a primeira categoria, por ser mais relevante à maioria dos programadores. Geralmente, quando a informação é ordenada, apenas uma porção dessa informação é usada como chave da ordenação. Essa chave é utilizada nas com- parações, mas, quando uma troca se torna necessária, toda a estrutura de dados é transferida. Por exemplo, em uma lista postal, o campo de código de área (CEP) poderia ser usado como chave, mas O nome e o endereço acompanham o CEP quando uma troca é feita. Com o objetivo de simplificar, os exemplos ordenarão matrizes de caracteres enquanto você aprende os diversos métodos de ordenação. Mais tarde você aprenderá a adaptar esses métodos a qualquer tipo de estrutura de dados. Tipos de Algoritmos de Ordenação Existem três métodos gerais para ordenar matrizes: HM portroca m por seleção EH por inserção Para entender esses três métodos, imagine as cartas de um baralho. Para ordenar as cartas, utilizando troca, espalhe-as, voltadas para cima, numa mesa, então troque as cartas fora de ordem até que todo o baralho esteja ordenado. Utilizando seleção, espalhe as cartas na mesa, selecione a carta de menor valor, retire-a do baralho e segure-a em sua mão. Esse processo continua até que todas as cartas estejam em sua mão. As cartas em sua mão estarão ordenadas quando o processo tiver terminado. Para ordenar as cartas por inserção, segure todas as cartas em sua mão. Ponha uma carta por vez na mesa, sempre inserindo-a na posição correta. O maço estará ordenado quando não restarem mais cartas em sua mão. Uma Avaliação dos Algoritmos de Ordenação Existem muitos algoritmos diferentes para cada método de ordenação. Cada um deles tem scus méritos, mas os critérios gerais para avaliação de um algoritmo são: Soa so É Completo eTotak E & aii dr do aaa fila fede A ordenação bolha é uma ordenação por trocas. Ela envolve repetidas comparações e, se necessário, a troca de dois elementos adjacentes. Os elementos são como bolhas em um tanque de água — cada uma procura o seu próprio nível. A forma mais simples da ordenação bolha é mostrada aqui: !* A ordenação bolha. */ void bubble(char *item, int count) í register int a, b; register char t; for (a=l; a=a; --b) if(item[b-1] > item[b]) ( !* troca os elementos */ t = item[b-1]; item[b-1] item[b); item[b] = t; No código anterior, item é um ponteiro para uma matriz de caracteres a ser ordenada e count é o número de elementos da matriz. A ordenação bolha é dirigida por dois laços. Dado que existem count elementos na matriz, o laço mais externo faz a matriz ser varrida count-l vezes. Isso garante que, na pior hipótese, todo elemento estará na posição correta quando a função terminar. O laço mais interno faz as comparações c as trocas. (Uma versão ligeiramente melhorada da ordenação bolha termina se não ocorre nenhuma troca, mas isso acrescenta uma outra comparação a cada passagem pelo laço interno.) Essa versão da ordenação bolha pode ser utilizada para ordenar uma matriz de caracteres em ordem ascendente. Por exemplo, o programa seguinte ordena uma string digitada no teclado. !*Sort Driver*/ tinclude finclude tinclude void bubble(char *item, int count); “a 44 EN “ ,6 Cap. 19 DS Brdeliaçõõo Postal SO void main(void) f char s[80]; printf ("Digite uma string:"); gets(s); bubble(s, strlents)); printf("A string ordenada é: &s.in”, s); Para ver como funciona a ordenação bolha, assuma que a matriz a ser ordenada contenha dcab. Cada passo é mostrado aqui: inicial decab passo 1 ad ecb passo 2 abadc passo 3 abcad Ao analisar qualquer ordenação, você deve determinar quantas com- parações e trocas serão realizadas para o menor, médio e pior casos. Com a ordenação bolha, o número de comparações é sempre o mesmo, porque os dois laços for repetem o número especificado de vezes, estando a lista inicialmente ordenada ou não. Isso significa que a ordenação bolha sempre executa 1% Lu —n) comparações, onde n é o número de elementos a ser ordenado. Essa fórmula deriva do fato de que o laço mais externo executa n —1 vezes e o laço mais interno n/2 vezes. Multiplicando-se um pelo outro obtemos a fórmula anterior. O número de trocas é zero, para o melhor caso, em uma lista já ordenada. O número de trocas para 0 caso médio e o pior caso são médio qn? -n) pior Yom? — 1) Está fora do escopo deste livro explicar a origem das fórmulas anteriores, mas você pode observar que, à medida que a lista se torna menos ordenada, o número de elementos fora de ordem se aproxima do número de comparações. (Lembre-se de que, na ordenação bolha, existem três trocas para cada elemento fora de ordem.) Essa é uma ordenação n-guadrado, pois seu tempo de execução é um múltiplo do quadrado do número de elementos. Esse tipo de algoritmo é muito ineficiente quando aplicado a um grande número de elementos, porque o tempo de execução está diretamente relacionado com o número de comparações e trocas. Por exemplo, ignorando o tempo que leva para trocar qualquer elemento fora Cap. 19 | * Ordctaçãoo pesquisa 2 DEDO CUL 507 register int a; int exchange; char t; do ( exchange = 0; for (a=count-1; a>0; --a) ( if(item[a-l]>item[a]) ( t = item[a-l); item[a-1] — item[al; item[a] = t; exchange - 1; 3 for(a=l; aitem[a]) ( t = item[a-1); item[a-1] = item[a); item[a] = t; exchange = ; ) ) while(exchange); /*ordena até que não existam mais trocas*/ ; Embora a ordenação oscilante seja uma melhoria da ordenação bolha, ela ainda é exccutada na ordem de um algoritmo »-guadrado, porque o número de com- parações não foi alterado e o número de trocas foi reduzido de uma constante relativamente pequena. A ordenação oscilante é melhor que a ordenação bolha, mas existem ordenações ainda melhores. Ordenação por Seleção A ordenação por seleção seleciona o elemento de menor valor e troca-o pelo primeiro elemento. Então, para os 1-1 elementos restantes, é encontrado o ele- mento de menor chave, trocado pelo segundo elemento e assim por diante. As trocas continuam até os dois últimos elementos. Por exemplo, se o método de seleção fosse utilizado na matriz bdac, cada passo se apresentaria como: inicial bad ac passo 1 ad be passo 2 a bad c passo 3 abcd 508 á LA C 4 Esmpleto É Tó Fo é 58022. 85% Cópia O código a seguir mostra uma ordenação por seleção simples. /* A ordenação por seleção. */ void select(char *item, int count) f register int a, b, c; int exchange; char t; for(a=0; a a 4 Quicksort A quicksort, inventada e denominada por C.A.R. Hoare, é superior a todas as outras ordenações deste livro, e geralmente é considerada o melhor algoritmo de ordenação de propósito geral atualmente disponível, É bascada no método de ordenação por trocas. Isso é surpreendente, quando se considera o terrível desempenho da ordenação bolha! A quicksort é bascada na idéia de partições. O procedimento geral é selecionar um valor, chamado de comparando, e, então, fazer a partição da matriz em duas seções, com todos os elementos maiores ou iguais ao valor da partição de um lado e os menores do outro. Esse processo é repetido para cada seção restante até que a matriz esteja ordenada. Por exemplo, dada a matriz fedacb e usando o valor d para a partição, o primeiro passo da quicksort rearranja a matriz como seguc: início fedacb passol bcadef Esse processo é, então, repetido para cada seção — isto é, bca c def. Como você pode ver, o processo é essencialmente recursivo por natureza e, certamente, as implementações mais claras da quicksort são algoritmos recursivos. 514 : C = Completo e Total PR Éap.19 Você pode selecionar o valor do comparando intermediário de duas for- mas. Você pode escolhê-lo aleatoriamente ou selecioná-lo fazendo a média de um pequeno conjunto de valores retirado da matriz. Para uma ordenação ótima, você deveria selecionar um valor que estivesse precisamente no centro da faixa de valores. Porém, isso não é fácil para a maioria dos conjuntos de dados. No pior caso, o valor escolhido está em uma extremidade e, mesmo nesse caso, quick- sort ainda tem um bom rendimento. A versão seguinte da quicksort seleciona o elemento intermediário da matriz. Embora isso nem sempre resulte em uma boa escolha, a ordenação ainda é efetuada corretamente. !* Função de inicialização da Quicksort. */ void quick(char *item, int count) f gs(item, O, count-1) /* A Quicksort. */ void qgs(char *item, int left, int right) register int i, j; char x, y; i = left; j = right; x = item[(left+right)/2]; do while(item[illeft) j--; if(i<=5) « y = item[i]; item[i] = item[5]; item[j] = y; i++; j--; ) ) whileti<=5); if(left0 && j>left) j--; if(i<=5) € strcpyttemp, item[i]); strcpy (item[il], itemíjl]); strcpy(fitem[5], temp); i++; j--; ) while(i<=5): if(left + wnile(i<=j); if(left mo sq % 2% 4*cfcimiottadE SO Css tinclude tinclude gdefine NUM ELEMENTS 4 /* Esse é um número arbitrário que deve ser determinado dinamicamente para cada lista. */ struct address ( char name [30]; char street [40]; char city [20]; char state[3]; char zip[11]; jainfo; struct address addrs [NUM ELEMENTS] = ( "A, Alexander", "101 lst St”, “Olney”, “Ga", "55555", "B. Bertrand”, "22 2nd Ave", "Oakland", "Pa", "34232", "C. Carlisle”, “33 3rd Elvd”, "ava", "Or", "92000", "D. Dodger", "4 Fourth Dr", "Fresno", "Mi", "45678" J: void quick disk(FILE *fp, int count); void qs disk(FILE *fp, int left, int right); void swap all fields(FILE *fp, long à, long 5); char *get zip(FILE *fp, long rec); void maintvoid) f FILE *fp; /* primeiro, crie um arquivo para ser ordenado */ if((fp-=fopen ("mlist”, “wb"))==NULL) ( printf ("O arquivo não pode ser aberto para escrita.in'"); exit (1); : printf ("Gravando dados não ordenados para disco. in"); fwrite (addrs, sizeof (addrs), 1, fp); fclose (fp); !'* agora, ordene o arquivo */ if((fp=fopen("mlist", "rb+"))==NULL) ( printf("O arquivo não pode ser aberto para leitura/escrita. An"); exit(l); , fprintf ("Ordenando arquivo de disco. An");