Estrutura de Dados Carlos Eduardo Batista Centro de Informática - UFPB bidu@ci.ufpb.br
Aritmética de ponteiros em C (continuação) O que acontece na memória? Ponteiro para ponteiro etc. Métodos de pesquisa e classificação de dados (resumo) Estruturas de Dados 2
Operador & Endereço de Operador unário que devolve o endereço na memória do seu operando Operador * Valor no endereço de Operador unário que devolve o valor da variável localizada no endereço do seu operando m = &count; q = *m; Aritmética de ponteiros em C 3
int *pivalor; /* ponteiro para inteiro */ int ivariavel = 1234234; pivalor = &ivariavel; /* endereço de memória */ printf ("Endereco: %d\n", pivalor); printf ("Valor : %d\n", *pivalor); *pivalor = 180118 ; printf ("Valor alterado: %d\n", ivariavel); printf ("Endereco : %d\n", pivalor); Aritmética de ponteiros em C 4
int* e; *e = (int*)malloc(sizeof(int)); if (e == NULL) { printf( Memória cheia ); exit(1); } *e = 10; printf( e = %p e contém %d,e,*e); free(e); PonteirosemC 5
Ponteiro para ponteiro Ponteiro que guarda o endereço de memória de outro ponteiro tipo **nome *nome = conteúdo do ponteiro intermediário (um endereço) **nome = conteúdo da região final apontada (um valor) Ponteiro para ponteiro para ponteiro PonteirosemC 6
int *pivariavel; *pivariavel = (int *) malloc(sizeof(int)); //ADDR 4 *pivariavel = 20; printf( %d\n,&pivariavel); //1 printf( %d\n,pivariavel); //4 printf( %d\n,*pivariavel); //20 Ponteiros em C 7
#include <stdio.h> #include <stdlib.h> int funcao(int **piparametro) { printf("%d\n",&piparametro); printf("%d\n",piparametro); printf("%d\n",*piparametro); printf("%d\n",**piparametro); return 0; } int main( void ) { int *pivariavel; *pivariavel = (int *) malloc(sizeof(int); *pivariavel = 20; printf("%d\n",&pivariavel); printf("%d\n",pivariavel); printf("%d\n",*pivariavel); funcao( &pivariavel ); return 0; } Ponteiros em C 8
Ponteiros em C 9
Ponteiros em C 10
main() { } float pi = 3.1415, *pf, **ppf; pf = π ppf= &pf; printf("%f\n", **ppf); printf("%f\n", *pf); PonteirosemC 11
Busca: Tarefa recorrente Diferentes métodos e estruturas (TADs) aplicáveis Quais e quando? Métodos específicos para situações específicas O problema: Dado um conjunto de elementos identificados (por uma chave, por exemplo), localizar o elemento que possui uma chave específica 12
Algoritmo de busca Recebe como argumento o índice para a busca e o conjunto no qual a busca será realizada Operações Inserção Inserção com busca Se elemento não existe, insira Recuperação Remoção 13
Conjunto de dados Um vetor de registros Uma lista encadeada Uma árvore Busca Sequencial Binária Busca por interpolação, em árvores e hashing Busca deve ser realizada com menor custo Utilizar menor quantidade de recursos possíveis 14
Busca sequencial Forma mais simples Aplica-se a vetores, listas encadeadas e estruturas que possuem sequência de ordenação São consultados todos os registros até que se encontre o que se busca Encontrar 988 em um vetor com 8 elementos inteiros 234 567 353 276 958 598 988 544 Iteração 1... 7ª. Iteração! 15
int A[] = { 234, 567, 353, 276, 958, 598, 988, 544 }; int x = 988; for (i=0; i<8; i++) { if (A[i] == x) return(i); /*chave encontrada*/ } return(-1); /* chave não encontrada */ A int A[] = { 234, 567, 353, 276, 958, 598, 988, 544 }; int x = 988; int i; int n = 8; A[n] = 988; for (i=0; x!=a[i]; i++) if (i < n) return(i); /*chave encontrada*/ else return(-1); /*chave não encontrada*/ B 16
Busca sequencial Tamanho fixo do vetor Desperdício de memória pode ocorrer Alternativa: usar lista encadeada Complexidade Pesquisa com sucesso melhor caso: C(n) = 1 pior caso: C(n) = n caso médio: C(n) = (n+1) / 2 Pesquisa sem sucesso C(n) = n + 1 17
Busca sequencial Em arranjo não ordenado Inserção no final do arranjo Remoção: realocação dos registros acima do removido Eficiência: reordenar continuamente Mover para frente pesquisa com êxito move item para frente (no início da lista) Transposição registro recuperado é trocado com o registro imediatamente anterior Recuperação recorrente de registros (frequência) 18
Busca sequencial Em estrutura ordenada (pelos valores das chaves a serem buscadas) Melhor eficiência Pior caso (não encontrada a chave): O(n) Caso médio: O(n/2) Tabela de índices 19
Chave Registro 100 110 234 234 345 697 987 697 1000 987 999 1000 20
Busca binária Se os dados estiverem ordenados em um arranjo... Arr[i] <= Arr[i+1] (ordem crescente) Arr[i] >= Arr[i+1] (ordem decrescente) Parte-se do elemento do meio do arranjo para realizar a busca Se igual, busca bem sucedida Se maior ou menor, realizar busca na metade correspondente (dependendo se ordenado crescente ou decrescentemente) 21
Buscando 133... 123 133 222 245 321 334 411 544 133 < 245 123 133 222 245 321 334 411 544 133 = 133 Elemento encontrado! 22
Busca binária Complexidade O(log n) cada comparação reduz o número de possíveis candidatos por um fator de 2 Eficiente e simples Porém... Nem todo arranjo está ordenado Faz uso do fato que os índices são inteiros consecutivos Não se aplica a todos os tipos de estruturas Pode-se combinar com busca sequencial (organização da tabela secundária) 23
struct registry { int id; /* chave do registro */... /* outros campos do registro */ } typedef struct registry Registry; 24
/* tamanho do vetor = n */ /* função retorna posição do registro no vetor v, ou -1 se não encontrou */ int binsearch(registry *v, int id) { if (n <= 0) return -1; int esq = 0; int dir = n - 1; int i; do { i = (esq + dir) / 2; if (id > v[i].id) esq = i + 1; else dir = i - 1; } while ((id!= v[i].id) && (esq <= dir)); if (id == v[i].id) return i; return -1; } 25
Primeiro trabalho: Agenda Definir estrutura para armazenar registro Pessoa: nome, endereço, telefone... Definir um vetor que armazene os registros Com no máximo 100 elementos Operações: Inserção, busca/recuperação e remoção 26
Métodos de pesquisa e classificação de dados (continuação) Pilhas e Filas Próximas aulas 27
Notas de Aula do Prof. Bruno B. Boniati Notas de Aula do Prof. João Luís Garcia Rosa Referências 28
Estrutura de Dados Carlos Eduardo Batista Centro de Informática - UFPB bidu@ci.ufpb.br