(VWUXWXUDVGH'DGRV 1. Introdução • Disciplina que estuda as técnicas computacionais para a organização e manipulação eficiente de quaisquer quantidades de informação. • Em um projeto de software, 2 aspectos devem ser considerados para sua implementação: o De que forma estão organizados os dados ? Qual a sua estrutura ? o Quais procedimentos atuam sobre estes dados ? Que operações podem ser realizadas sobre eles ? • Ao estudar estruturas de dados teremos sempre este par: o Um conjunto estruturado de informações Uma classe de objetos ou um tipo de dados. o Um conjunto definido de operações sobre estes dados: Um conjunto de métodos ou funções. 1.1 Tipos de Estruturas 3ULPLWLYDV Implementadas diretamente pelo compilador Exemplos (simples): Booleano, Inteiros, ... Exemplos (compostas) : Strings, Registros, Vetores ... Operações: Inserção, Remoção, Ordenação, Máximo, Mínimo, Inversão, ... 1mR3ULPLWLYDV Implementadas pelo programador Exemplos: Listas, Árvores, Tabelas de Dispersão ... 1 /LVWDV/LQHDUHV Define-se uma lista como sendo o conjunto de N elementos [ [ [ organizados estruturalmente de forma a refletir as posições relativas dos mesmos: • SDUDN1RQy[ pSUHFHGLGRSHORQy[ HVHJXLGRSHORQy[ •TXDQGR1 1 HQWmRDOLVWDHVWiYD]LD ∀ i, j entre 1 e n se i < j → Ei antecede Ej E1 E2 EN nó 5HSUHVHQWDomR ItVLFD alocação seqüencial (por contigüidade) simplesmente encadeada alocação encadeada duplamente encadeada A escolha da forma de representação dependerá da freqüência com que determinadas operações serão executadas sobre a lista. O objetivo é reduzir o esforço computacional para sua execução. Operações mais freqüentes - Incluir um nó antes do k-ésimo nó da lista - Remover o k-ésimo nó da lista - Alterar o k-ésimo nó de uma lista - Acessar o k-ésimo nó de uma lista - Buscar um nó através de seu conteúdo Alocação seqüencial (Contígua) Usa estrutura estática (vetor) para representar a estrutura dinâmica (lista de elementos) 2 É a solução mais simples, pois usa um vetor para colocar os nós da lista em posições contíguas. EN = vetor[N] tempo fixo de acesso a qualquer nó da lista 3UREOHPDV • Operações de inserção e remoção de elementos da lista provocam movimentação de dados • Quantidade de armazenamento limitada pelo tamanho físico do vetor Esse tipo de representação só é adequada qdo o n° de consultas for > n° de inserções e remoções da lista Alocação encadeada Início Leite Tomates Pão Cada elemento, ou nó da lista, possui uma referência indicando a localização do próximo elemento. 9DQWDJHQVFRPUHODomRjDORFDomRVHTHQFLDO • Operações de inserção e remoção não exigem movimentação de dados; 'HVYDQWDJHQVFRPUHODomRjDORFDomRVHTHQFLDO • Algoritmos mais complexos • Tempo de acesso aos elementos da lista não é mais constante – devemos percorrer a lista 3 // Inserir um nó antes do k-ésimo nó de uma lista int inserir (OLVWD x, LQW k, LQW fim, WLSRGDGR val) ^ LQW i; se k < 0 RX k > fim RX fim = MAX -1 HQWmR retorne –1; // situação de erro VHQmR ^ i = fim; HTWR i >= k IDoD { x[i+1] = x[i]; i = i – 1; } fim = fim + 1; x[k] = val; ` ` // Remover o k-ésimo nó de uma lista remover (OLVWD x; LQW k, LQW fim) { VH k < 0 RX k > fim HQWmR erro; VHQmR { HTWR k < fim IDoD ^ x[k] = x[k+1]; k = k + 1; ` fim = fim - 1; } } 4 5HSUHVHQWDomRHQFDGHDGDEDVHDGDHPYHWRU ([HPSOR/HLWRVGHKRVSLWDO ,QtFLR 3 4 João 223344 1 Maria 66677 -1 Lúcia 88899 Inserção no início da lista Início Leite Tomates Pão Leite Tomates Pão Batata Início Batata Estrutura que representa a lista constante MAX 100 tipo no = registro { WLSRGDGR dados; LQW prox; } tipo WOLVWD = registro { no elem[MAX]; int inicio; } WOLVWD lista; 5 Inserção no início da lista pos := aloca_nó(); // pos é o índice no vetor // onde o novo item foi colocado lista.elem[pos].prox := lista.inicio; lista.elem[pos].dados := Novo_Elemento; lista.inicio := pos; Inserção no fim da lista Início Leite Tomates Pão Leite Tomates Pão Batata Início Batata LQW next; pos := aloca_nó(); // pos é o índice no vetor // onde o novo item será colocado lista.elem[pos].prox := -1; lista.elem[pos].dados := Novo_Elemento; VH lista.inicio = -1 HQWmR { lista.inicio := pos; } senão { next := lista.inicio; HTWR lista.elem[next].prox <> -1 IDoD next := lista.elem[next].prox; lista.elem[next].prox := pos; } 6 Inserção no meio da lista Início Leite Tomates Pão X Leite Tomates Pão X Batata Início Batata LQW next, ant; pos := aloca_nó(); // pos é o índice no vetor // onde o novo item foi colocado lista.elem[pos].prox := -1; lista.elem[pos].dados := Novo_Elemento; VH lista.inicio = -1 { lista.inicio := pos; HQWmR } senão { // percorre a lista procurando a posição onde inserir next := lista.inicio; HTWR next <> -1 H Novo_Elemento > lista.elem[next].dados { ant := next; next := lista.elem[next].prox; } lista.elem[pos].prox := lista.elem[ant].prox; lista.elem[ant].prox := pos; } 7 Remoção no início da lista Início Leite Tomates Pão Leite Tomates Pão Início // Remove o primeiro elemento da lista VH lista.inicio = -1 HQWmR erro(); // não pode remover nó de lista vazia !!! VHQmR { LQW tmp; tmp := lista.inicio; lista.inicio := lista.elem[inicio].prox; desaloca(tmp); } 8 Remoção no meio da lista Início Leite Tomates Pão Leite Tomates Pão Início VH lista.inicio = -1 HQWmR erro(); // não pode remover nó de lista vazia ! VHQmR { LQW next, ant; // percorre a lista procurando a posição onde remover next := lista.inicio; HTWR next <> -1 H não for a posicao onde remover IDoD { ant := next; next := lista.elem[next].prox; } VH next = -1 HQWmR erro(); // chegou no fim da lista! VHQmR { lista.elem[ant].prox := lista.elem[next].prox; desaloca(next); } } 9 Remoção no fim da lista Início Leite Tomates Pão Leite Tomates Pão Início LQW VH next, ant, tmp; lista.inicio = -1 HQWmR erro(); // não pode remover nó de lista vazia ! VHQmR VH lista.elem[lista.inicio].prox = -1 HQWmR { tmp := lista.inicio; lista.inicio := -1; desaloca(tmp); } VHQmR { // percorre a lista até chegar no último elemento next := lista.inicio; HTWR lista.elem[next].prox <> -1 IDoD{ ant := next; next := lista.elem[next].prox; } lista.elem[ant].prox := -1; desaloca(next); } 10