Programação II. Ordenação (sort) Bruno Feijó Dept. de Informática, PUC-Rio

Documentos relacionados
Programação II. Ordenação (sort) Bruno Feijó Dept. de Informática, PUC-Rio

Programação II. Tópicos Extras Ordenação (sort) Bruno Feijó Dept. de Informática, PUC-Rio

INF 1007 Programação II

Programação II. Ordenação (sort) Bruno Feijó Dept. de Informática, PUC-Rio

Módulo 16 - Ordenação

Programação II. Busca em Vetor (search) Bruno Feijó Dept. de Informática, PUC-Rio

Programação de Computadores II. Cap. 16 Ordenação

Linguagem C: Ordenação

Programação II. Ordenação (sort) Bruno Feijó Dept. de Informática, PUC-Rio

Módulo 16 - Ordenação. Referências

Estruturas de Dados. Módulo 17 - Busca. 2/6/2005 (c) Dept. Informática - PUC-Rio 1

ALGORITMOS DE ORDENAÇÃO RECURSIVOS

INF1007: Programação 2 6 Ordenação de Vetores. 01/10/2015 (c) Dept. Informática - PUC-Rio 1

Projeto e Análise de Algoritmos

Algoritmos e Estruturas de dados

Recuperação P1 de Estrutura de Dados

Programação II. Vetores Bidimensionais e Vetores de Ponteiros. Bruno Feijó Dept. de Informática, PUC-Rio

Programação II. Vetor de Tipo Estruturado e Vetor de Ponteiros. Bruno Feijó Dept. de Informática, PUC-Rio

Programação II. Árvores Binárias (Binary Trees) Bruno Feijó Dept. de Informática, PUC-Rio

Universidade Federal de Santa Maria Colégio Agrícola de Frederico Westphalen Curso Superior de Tecnologia em Sistemas para Internet

Universidade Federal do ABC Avaliação Disciplina Turma Professor Data Instruções para a prova (leia antes de começar): SelectionSort selectonsortrec

Programação II. Tipos Estruturados

Classificação de Dados

Carlos Eduardo Batista. Centro de Informática - UFPB

Programação II. Tipos Estruturados. Bruno Feijó Dept. de Informática, PUC-Rio

Programação II. Vetores e Alocação Dinâmica. Bruno Feijó Dept. de Informática, PUC-Rio

P2 Programação II Departamento de Informática/PUC-Rio

Ordenação: QuickSort. Prof. Túlio Toffolo BCC202 Aula 15 Algoritmos e Estruturas de Dados I

AED - Algoritmos e Estruturas de Dados Licenciatura em Engenharia Electrónica

Questão 1.a) (2.5 pontos ) tipodabolsa matricula EhBolsista

INF 1007 Programação II

Algoritmos de ordenação Ordenação rápida ( Quicksort )

Programação II. Listas Encadeadas (Linked Lists) Bruno Feijó Dept. de Informática, PUC-Rio

INF 1620 P2-23/10/04 Questão 1 Nome:

ALGORITMOS E ESTRUTURAS DE DADOS CES-11 Prof. Paulo André Castro Sala 110 Prédio da Computação IECE - ITA

Quicksort. David Menotti Algoritmos e Estruturas de Dados II DInf UFPR

Programação II. Vetores e Alocação Dinâmica. Bruno Feijó Dept. de Informática, PUC-Rio

Estruturas de Dados. Introdução Definição de Ponteiros Declaração de Ponteiros em C Manipulação de Ponteiros em C

Aluno: Valor Nota Q1 3.0 Q2 2.5 Q3 2.5 Q4 2.0 Total 10.0

INF 1620 P3-02/07/02 Questão 1 Nome:

Algoritmos e Estruturas de Dados

Estrutura de Dados. Algoritmos de Ordenação. Prof. Othon M. N. Batista Mestre em Informática

REVISÃO DE C. Vanessa Braganholo Estruturas de Dados e Seus Algoritmos

ponteiros INF Programação I Prof. Roberto Azevedo

ÁRVORES ABB (ÁRVORES BINÁRIAS DE BUSCAS) Sérgio Carlos Portari Júnior

INF 1620 P3-27/11/04 Questão 1 Nome:

PROVA P2 INF /10/2014 Programação II

1. Faça um programa que leia uma string digitada pelo usuário e salve em um arquivo em branco.

PROGRAMAÇÃO DE COMPUTADORES V - TCC Modulo 6 : Funções Escopo de Variáveis: Globais x Locais Aura - Erick

Algoritmos de ordenação

P2 Programação II Departamento de Informática/PUC-Rio

Algoritmos e Estruturas de Dados. Décima sexta aula: Quicksort

Exemplo. Lista Inicial (Desordenada) a. Iteração: Pivô: 25. Elemento da Esquerda: 48 Elemento da Direita: 12

Classificação por Particionamento

INF 1620 P3-29/06/04 Questão 1 Nome:

INF 1007 Simulado P2 Nome: Instruções

Capacitação em Linguagem C Parte 2

Aluno: Para todas as questões desta prova considere os tipos estruturados abaixo:

Linguagens de Programação I

ÁRVORES BINÁRIAS DE BUSCA. Vanessa Braganholo Estruturas de Dados e Seus Algoritmos

Reinaldo Gomes Alocação Dinâmica

INF 1620 P3-21/06/08 Questão 1 Nome:

INTRODUÇÃO À LINGUAGEM C

DAINF - Departamento de Informática

Sumário. Introdução à Ciência da Computação. Ponteiros em C. Introdução. Definição. Por quê ponteiros são importantes?

Funções em Linguagem C Parte II

Programação II. Ponteiros. Bruno Feijó Dept. de Informática, PUC-Rio

Departamento de Informática PUC-Rio INF Estruturas de Dados Lista 2 Completa (Gerada em 8 de maio de 2006)

BCC202 - Estrutura de Dados I

Métodos de Ordenação Parte 3

INF 1620 P4 11/12/06 Questão 1 Nome:

Programação de Computadores I Introdução ao C PROFESSORA CINTIA CAETANO

Algoritmos e Programação de Computadores Profs: Ronaldo Castro de Oliveira Anilton Joaquim da Silva

INF 1620 P3-25/11/05 Questão 1 Nome:

Programação II. Introdução a Funções. Bruno Feijó Dept. de Informática, PUC-Rio

Classificação por Seleção - selection sort

INTRODUÇÃO À LINGUAGEM C

Permite modularidade (dividir programa em partes): Facilita a depuração (debug) e portabilidade.

ALGORITMOS DE ORDENAÇÃO

Carlos Eduardo Batista. Centro de Informática - UFPB

CIC 110 Análise e Projeto de Algoritmos I

INTRODUÇÃO À LINGUAGEM C

Introdução à Programação / Programação I

AED2 - Aula 11 Problema da separação e quicksort

Algoritmos de Ordenação: QuickSort

Conteúdo. Busca Seqüencial. Busca Binária. Algoritmos de Ordenação e Busca e sua Análise de Complexidade. Alneu de Andrade Lopes Rosane Minghim

INF 1620 P2-14/10/05 Questão 1 Nome:

ALGORITMOS E ESTRUTURAS DE DADOS CES-11

CURSO DE ESTRUTURA DE DADOS MÓDULO: ALGORITMOS DE ORDENAÇÃO E PESQUISA PROFESSORA: DANIELA ELOISE FLÔR COLABORADORA: MARIA CAROLINA SILA VANUCHI

Módulo 5 Vetores e Alocação Dinâmica

SCC Algoritmos e Estruturas de Dados I

Linguagem C: Ponteiros - Alocação Dinâmica

Exame de Programação Estruturada (A)

INF 1010 Estruturas de Dados Avançadas

Filas de Prioridade. Uma fila de prioridade pode ser vista como uma generalização das filas com as seguintes duas operações:

UNIVERSIDADE DA BEIRA INTERIOR

INF 1620 P2-01/11/03 Questão 1 Nome:

Arquivos Sequenciais. Estruturas de Dados II Vanessa Braganholo

MAC121 ALGORITMOS E ESTRUTURAS DE DADOS I 2O. SEMESTRE DE 2017

SSC300- Linguagens de Programação e Aplicações Profa Vânia de Oliveira Neves. ICMC/USP São Carlos

Transcrição:

Programação II Ordenação (sort) Bruno Feijó Dept. de Informática, PUC-Rio

Quick Sort (Ordenação Rápida)

Algoritmo Quick Sort (recursivo) O algoritmo de Quick Sort foi desenvolvido por Sir Charles Hoare (Tony Hoare), em 1960, aos 26 anos. Suponha que você sabe colocar um dos elementos x do vetor (por exemplo, o primeiro) numa posição tal que todos os elementos antes são menores ou iguais a x e todos os elementos depois dele são maiores (note que, nesta tarefa, não importa se alguns elementos trocam de posição): x x x x 5 5 n elementos 5 4 3 7 1 2 6 9 1 4 3 2 5 7 6 9 n = 8 Vamos denominar o elemento x escolhido de pivô e chamar esta etapa da ordenação de PARTIÇÃO. Neste caso, se você souber ordenar o subvetor esquerdo e o subvetor direito, você terá o vetor inicial completamente ordenado! Isto nos leva a definir uma função recursiva quicksort na qual o caso-base é um vetor com 1 ou nenhum elemento (e, neste caso, nada é preciso fazer) e o caso geral é fazer a partição seguida da chamada da função para o subvetor esquerdo e da chamada da função para o subvetor direito: quicksort do vetor se n 1 então retorna faz PARTIÇÃO com pivô x (i.e. coloca x no lugar certo) quicksort do subvetor à esquerda de x quicksort do subvetor à direita de x No próximo slide estão sugeridos um processo simples e direto para a PARTIÇÃO e uma maneira de se referenciar aos subvetores à esquerda e à direita de x.

PARTIÇÃO x a a v a x a para Algoritmo Quick Sort (recursivo) - CRESCENTE Para a PARTIÇÃO, podemos ir caminhando com os índices do vetor: a b... a b v b x b para se a b, troca e incrementa região dos x se b a, troca pivô x com v b Subvetor à esq v b x v a 0 a b posição correta de x b região dos x b Subvetor à dir n - a repete processo para cada subvetor caminham enquanto fica repetindo até que 25 48 37 12 57 86 33 92 a b a b b b b 25 12 37 48 57 86 33 92 a b b a 12 25 37 48 57 86 33 92 12 incr a se v a x decr b se v b x troca e incr/decr não troca nem in/decr troca pivô quicksort(n,v) se n <= 1 então retorna x = v 0 a = 1 b = n-1 faça enquanto a < n e v a x a = a + 1 enquanto v b > x b = b - 1 se a < b então troca v a com v b e a= a+1 e b= b-1 enquanto a b troca pivô x com v b quicksort(b, subvetor esquerdo) quicksort(n-a, subvetor direito)

Partição Código Quick Sort CRESCENTE quicksort(n,v) se n <= 1 então retorna x = v 0 a = 1 b = n-1 faça enquanto a < n e v a x a = a + 1 enquanto v b > x b = b - 1 se a < b então troca v a com v b e a= a+1 e b= b-1 enquanto a b troca pivô x com v b quicksort(b, subvetor esquerdo) quicksort(n-a, subvetor direito) void quicksort(int n, int * v) int x = v[0]; int temp; int a = 1; int b = n-1; if (n<=1) return; do while (a < n && v[a] <= x ) while ( v[b] > x ) if (a < b) temp = v[a]; v[a] = v[b]; v[b] = temp; while (a <= b); v[0] = v[b]; v[b] = x; quicksort(b,v); quicksort(n-a,&v[a]);

Generalizando o Algoritmo Quick Sort - Crescente O desenvolvimento apresentado nos slides anteriores refere-se à ordenação em ordem CRESCENTE de um vetor de INTEIROS. Uma primeira generalização é perceber que a partição divide o vetor em elementos que atendem o critério de ordenação à direita do pivô e elementos que NÃO atendem à esquerda. Por exemplo, a ilustração da partição para uma ordem CRESCENTE seria: 5 5 5 4 3 7 1 2 6 9 1 4 3 2 5 7 6 9 O critério de ordenação pode ser definido numa função auxiliar de comparação que é usada em dois momentos no algoritmo de quick sort, sendo um momento a negação do outro (operador!): static int cmpint(int x, int y) return x > y ; void quicksort(int n, int * v) int x = v[0]; int temp; int a = 1; int b = n-1; if (n<=1) return; do while (a < n &&!cmpint(v[a],x)) while (cmpint(v[b],x)) if (a < b) temp = v[a]; v[a] = v[b]; v[b] = temp; while (a <= b); v[0] = v[b]; v[b] = x; quicksort(b,v); quicksort(n-a,&v[a]); Elementos à esquerda NÃO atendem ao critério Elementos à direita atendem ao critério Geralmente definimos a função auxiliar como sendo static. Função static é invisível fora do arquivo no qual é declarada. O que é útil em módulos.

Generalizando o Algoritmo Quick Sort - Decrescente O desenvolvimento apresentado nos slides anteriores refere-se à ordenação em ordem CRESCENTE de um vetor de INTEIROS. Uma primeira generalização é perceber que a partição divide o vetor em elementos que atendem o critério de ordenação à direita do pivô e elementos que NÃO atendem à esquerda. Por exemplo, a ilustração da partição para uma ordem DECRESCENTE seria: 5 5 5 4 3 7 1 2 6 9 7 9 6 5 1 2 3 4 O critério de ordenação pode ser definido numa função auxiliar de comparação que é usada em dois momentos no algoritmo de quick sort, sendo um momento a negação do outro (operador!): static int cmpint(int x, int y) return x < y ; void quicksort(int n, int * v) int x = v[0]; int temp; int a = 1; int b = n-1; if (n<=1) return; do while (a < n &&!cmpint(v[a],x)) while (cmpint(v[b],x)) if (a < b) temp = v[a]; v[a] = v[b]; v[b] = temp; while (a <= b); v[0] = v[b]; v[b] = x; quicksort(b,v); quicksort(n-a,&v[a]); Elementos à esquerda NÃO atendem ao critério Elementos à direita atendem ao critério

Template void qsorttipo(int n, Tipo * v) // Ex: Tipo= int, Tipo= float, Tipo= Aluno * Tipo x = v[0]; Tipo temp; int a = 1, b = n-1; if (n<=1) return; do while (a < n &&!cmpfunction(v[a],x)) while (cmpfunction(v[b],x)) if (a < b) temp = v[a]; v[a] = v[b]; v[b] = temp; while (a <= b); v[0] = v[b]; v[b] = x; qsorttipo(b,v); qsorttipo(n-a,&v[a]); Função critério de ordenação static int cmpfunction(tipo x1, Tipo x2) // Criterio que retorna verdadeiro ou falso Pode ser um critério simples (p.ex., se for vetor de inteiros) ou um critério composto se for uma estrutura: p.ex., primeiro ordena crescente pelo peso e depois crescente pela idade. Neste caso, o critério é uma expressão booleana: pesox1 > pesox2 (pesox1 == pesox2 && idadex1 > idadex2)

Exercício 1 Ordenar vetor de floats Escreva um programa completo que ordena CRESCENTEMENTE um vetor de floats através do Quick Sort (e usando função de comparação). Depois indique a mudança para a ordenação DECRESCENTE.

Solução Exercício 1 Vetor de floats #include <stdio.h> int cmpfunction(float x1, float x2) // funcao criterio de ordenacao return x1 < x2; void qsortfloat(int n, float * v) float x = v[0]; float temp; int a = 1, b = n - 1; if (n <= 1) return; do while (a < n &&!cmpfunction(v[a], x)) while (cmpfunction(v[b], x)) if (a < b) temp = v[a]; v[a] = v[b]; v[b] = temp; while (a <= b); v[0] = v[b]; v[b] = x; qsortfloat(b, v); qsortfloat(n - a, &v[a]); // Decrescente, e return x1 > x2; se Crescente printarray(float * v, int n) int i; for (i = 0; i < n; i++) printf("%.1f\n", v[i]); int main(void) float vtemp[] = 40.0, 15.0, 25.0, 30.0, 10.0 ; int n = 5; qsortfloat(n, vtemp); printarray(vtemp, n); return 0;

Exercício 2 Ordena vetor de ponteiros para Dados Escreva programa completo, em módulos, que ordena um vetor de ponteiros para estrutura Dados através do Quick Sort (e usando função de comparação), de acordo o seguinte critério: primeiro em ordem crescente da idade e depois em ordem crescente do peso. struct dados int idade; int peso; ; typedef struct dados Dados; Sugestão para teste: Dados tab[] = 20,50,10,30,25,40,18,65,10,40,18,60; Dados * v[] = tab,tab+1,tab+2,tab+3,tab+4,tab+5; Faça a implementação em módulos com: dados.h, dados.c e testedados.c.

qsort Quick Sort da Biblioteca C

Ponteiros para Funções Em C é possível definir ponteiros para funções que podem ser colocados em vetores, passados para funções e retornados por funções No exemplo a seguir, a função opera(m, x, y, func) recebe um ponteiro de função como um de seus argumentos (func) e retorna m func(x,y). Devemos notar que o nome da função mult é um ponteiro quando escrevemos opera(2,3,5,mult); #include <stdio.h> Se argumentos são ponteiros, usamos const quando queremos garantir que a função func não modificará os valores que são int mult(int x,int y); apontados: int(*func)(const int *, const int *)) int soma(int x, int y); int opera(int m, int x, int y, int(*func)(int, int)); int main(void) int a, b; a = opera(2,3,5,mult); b = opera(2,3,5,soma); printf("%d %d\n",a,b); return 0; Saída: 30 16 int mult(int x,int y) return x*y; int soma(int x, int y) return x+y; int opera(int m,int x,int y,int(*func)(int, int)) return m*func(x,y);

Quick Sort da stdlib do C void qsort(void * v, int n, int tam, int (*cmp)(const void *, const void *)); v: vetor de ponteiros genéricos n: número de elementos do vetor tam: tamanho em bytes de cada elemento (use sizeof para especificar) cmp: ponteiro para função que compara elementos genéricos int nome(const void * a, const void * b); deve retornar <0 se a<b, >0 se a>b e 0 se a == b const é para garantir que a função não modificará os valores dos elementos static int compfloat(const void * a, const void * b) /* converte os ponteiros genericos */ float * aa = (float *)a; float * bb = (float *)b; /* faz a comparacao com (*aa) e (*bb) retornando -1,0, ou 1 */ if (*aa > *bb) // atenção para o * return 1; else if (*aa < *bb) return -1; else return 0; chamada: qsort(v,n,sizeof(float),compfloat); // N é o tamanho de v

Exemplo Quick Sort da stdlib #include <stdlib.h> int main(void)... void QsortPessoa(int n, Pessoa ** v) qsort(v,n,sizeof(pessoa *),comppessoa); Pessoa tab[] = "Diana Maria",22,...; Pessoa * v[] = tab,tab+1,...;... QsortPessoa(n,tabPessoa); // ordenacao com Quick Sort... int comppessoa(const void * a, const void * b) Pessoa ** aa = (Pessoa **)a; Pessoa ** bb = (Pessoa **)b; int cmp = strcmp((*aa)->nome,(*bb)->nome); if (cmp>0 (cmp==0 && ((*aa)->idade>(*bb)->idade))) return 1; else if (cmp<0 (cmp==0 && ((*aa)->idade<(*bb)->idade))) return -1; else return 0;