Você está na página 1de 23

ECOP01 - TÉCNICAS DE PROGRAMAÇÃO


Prof. Bruno Tardiole Kuehne

brunokuehne@unifei.edu.br
Aula 06:

Ordenação de Vetores

Créditos:
Prof. João Paulo R. R. Leite
joaopaulo@unifei.edu.br
Universidade Federal de Itajubá
Ordenação
• A ordenação de objetos é uma tarefa bastante intuitiva
e fácil de ser assimilada.
– Quando um grupo de pessoas é instruído para se por em fila
por ordem de tamanho, é dispensada qualquer outra
informação para que se forme imediatamente a fila
ordenada.
– Basta que se defina um critério claro para a ordenação.
• Manter as coisas em ordem é uma tarefa fundamental
em vários contextos, como a manipulação de listas,
itens de estoque, controle de dados, etc.
– Mas pra quê os dados precisam estar em ordem?
Ordenação
• Maior eficiência:
A eficiência no manuseio de dados pode ser aumentada
se eles forem dispostos em uma estrutura utilizando
algum critério de ordem, ou classificação.
• “Ordem” segundo o dicionário é
– “Uma disposição metódica, um arranjo de coisas segundo
certas relações, uma disposição conveniente dos meios para se
obterem os fins.”
• O problema da ordenação, portanto, pode ser encarado tão-
somente como uma etapa (importante) na solução de um
problema maior, de caráter mais prático.
• Dificilmente a ordenação será um fim em si mesma.
Ordenação
• Seria praticamente impossível, por exemplo, encontrar um
nome em uma lista telefônica desordenada:
– Dicionários, índices de livros, folhas de pagamento, contas bancárias,
listas de estudantes...
• O uso de dados ordenados é inquestionável e precisa ser
aplicado também à computação.
– Banco de dados: Acelerando o processo de localização dos dados;
– Agrupamento em categorias: Mantendo dados relacionados próximos,
facilitando, por exemplo, o processamento de dados em blocos;
– Algoritmos: Alguns algoritmos precisam que os dados estejam em
ordem para que funcionem corretamente. (Por exemplo, a busca
binária, Caminho mínimo em grafo com Dijkstra, Árvore geradora
mínima com Kruskal, e muitos outros)
Ordenação
• De acordo com o conceito, uma ordenação é feita segundo certas
relações: é preciso ser estabelecido um critério, que defina quem
precede quem na ordem.
• O critério da ordenação varia de acordo com a aplicação e o tipo
de dados, e é definido pelo usuário:
– um conjunto de números pode ser organizado de acordo com sua ordem
de grandeza em ordem crescente ou decrescente;
– os nomes no caderno de telefone podem estar ordenados
alfabeticamente pelo primeiro ou último nome.
• Normalmente, o estabelecimento do critério é trivial, como no
caso dos números e caracteres. No entanto, para tipos de dados
mais complexos, o critério pode ser mas complicado de ser obtido.
– Como organizar, por exemplo, uma coleção de fotos de rostos de pessoas?
Ordenação
• Uma vez escolhido o critério, o segundo passo é a criação
de um algoritmo que traduza o critério para uma
linguagem de programação.
– Nos algoritmos que estudaremos, o resultado da ordenação será
sempre a reorganização de um dado vetor unidimensional.
• Para ordenar um vetor, seus dados precisam ser
comparados entre si e movidos conforme necessário, até
que se chegue ao estado final ordenado.
– A eficiência do algoritmo é dada pela quantidade de vezes que
essas operações são repetidas, em função do tamanho da
entrada.
Ordenação
• Como todos os dados precisam ser comparados, a
grande maioria dos algoritmos de ordenação trabalha
de forma iterativa, utilizando laços de repetição,
onde cada volta do laço aproxima o vetor de seu
estado final (ordenado).
– Ao conjunto de operações realizados a cada iteração
(comparação + movimentação) damos o nome de passo.
• Ao calcular aproximadamente a quantidade de passos
necessários para a ordenação, definimos também sua
complexidade e quantificamos seu desempenho.
Ordenação
• Os dois métodos que iremos estudar estão entre os mais
simples que existem, mas não estão entre os mais eficientes.
• Os dois realizam aproximadamente N2 comparações e
movimentações de dados, onde N é o tamanho do vetor a ser
ordenado.
– São usados em programas com quantidade moderada ou pequena
de dados;
– Fáceis de entender e codificar: Normalmente irão utilizar dois laços
aninhados, o que gera a complexidade O(N2).
– Demonstram os princípios de ordenação por comparação.
• São eles:
Bubble Sort e Selection Sort.
Bubble Sort
• Efetua a ordenação por comparação entre pares
de elementos, trocando-os de posição caso
estejam foram de ordem no par.
– Simples implementação.
– É o mais antigo método de ordenação e um dos mais
ineficientes, pois exige mais comparações e trocas.
– Faz com que os maiores valores sejam empurrados
para o final do vetor em trocas sucessivas.
• Como uma bolha (bubble), percorrendo o vetor.
Bubble Sort
• Realiza varreduras no vetor, trocando pares
adjacentes de elementos sempre que o próximo
elemento for menor que o anterior;
• Após uma varredura, o maior elemento está
corretamente posicionado no vetor;
• Após a i-ésima varredura, os i maiores elementos
estão ordenados;
• A cada varredura, o maior elemento é inserido na
posição ordenada e removido da posição
desordenada.
As funções rand() e srand() são da
biblioteca stdlib.h. Vantagem: Simples de Implementar
A função time é da biblioteca time.h. Desvantagem: Desempenho fraco.
Bubble Sort
• As etapas do algoritmo são:
– Quando i = 0, os elementos vizinhos são comparados:
• (vetor[0], vetor[1]), (vetor[1], vetor[2]), (vetor[2], vetor[3])...
• São realizadas (TAM - 1) comparações;
• Para cada par (v[i] , v[i+1]) são trocados os valores se (v[i+1] < v[i]);
• No final da passada, o maior elemento da lista está na posição
v[TAM -1];
– Quando i = 1, são realizadas as mesmas comparações e
trocas, terminando com o elemento de segundo maior valor
na posição v[TAM -2];
– O processo termina com i = TAM - 1, em que o menor
elemento será armazenado na posição v[0].
Bubble Sort
• Considere o seguinte vetor de cinco posições:
– V = {7, 2, 8, 5, 4}
Bubble Sort
• Geração de números aleatórios:
– void srand(unsigned int seed)
• Inicializa o pseudo-gerador de números aleatórios com seed. Utiliza a
função time(NULL) para que, a cada execução, a semente seja diferente.
– time_t time(time_t* timer)
• Quando chamada com time(NULL) retorna a data e horário atuais em
forma de um inteiro não sinalizado (número de segundos desde uma
data convencionada, das 0 horas de 1 de janeiro de 1970)
– int rand()
• Retorna um número inteiro pseudoaleatório entre 1 e, pelo menos,
32767.
• Utilizar rand()%N irá gerar um número aleatório entre 0 e N-1.
Bubble Sort
• Complexidade
• Considerando uma entrada de tamanho n:
– O laço externo fará:
• n repetições, pois é um for de 0 até n – 1.
– O laço interno fará:
• n – i – 1 repetições, pois é um for de 0 até j – i – 2.
• Portanto, o número total de repetições da comparação + troca será um
somatório do tipo:
Soma de P.A.

• E sua complexidade é O(n2).


• Importante observar que a quantidade de operações efetuadas
também é constante para um dado n, e não depende da ordem prévia
dos elementos.
Selection Sort
• Procura, a cada iteração, o elemento de menor (ou
maior) valor e o colocam na sua posição definitiva
correta.
• O algoritmo de seleção se apóia em sucessivas
passadas – ou iterações – que trocam o elemento
de menor valor com o primeiro elemento do vetor.
1. Pesquisa seqüencial seleciona a posição do menor
elemento do vetor;
2. Coloca-o na posição que lhe corresponde.
Selection Sort
1. Identifica o menor elemento do vetor
através de uma pesquisa seqüencial;
2. Compara e troca com o elemento da
primeira posição do vetor;
3. Reexamina os elementos restantes no vetor
para achar o segundo menor elemento;
4. O processo se repete até que todos os
elementos do vetor sejam ordenados.
Vantagem: Método simples de Implementar
Desvantagem: Baixo desempenho, também com complexidade O(n2)
Selection Sort
• Os elementos do
vetor são
adicionados ao vetor
ordenado na ordem
correta.
• Repare no exemplo,
com o vetor
inicialmente com
{7, 2, 8, 5, 4}
Selection Sort
• Complexidade
• Considerando uma entrada de tamanho n:
– A primeira iteração compara o 1º elemento com os n - 1 demais: n - 1
comparações
– A segunda iteração compara o 2º elemento com os n – 2 demais: n – 2
comparações
– ...
– A (n-1)º iteração compara o (n-1)º elemento com o último: 1 comparação
– Total de comparações: (n-1) + (n-2) + (n-3) + ... + 1
– Calculando a soma da PA: (n-1)*(n-1 + 1) / 2 = (n2 – n)/2
• E sua complexidade, portanto, é O(n2).
• Importante observar que a quantidade de operações efetuadas também
é constante para um dado n, e não depende da ordem prévia dos
elementos.
Dúvidas??
Bibliografia Recomendada

• Deitel, Harvey M., and Paul J. Deitel. "Como


programar em C."

• H Schildt, RC Maye. “C completo e total”

Você também pode gostar