Aula T10 – BCC202 Listas – Parte 2 Túlio Toffolo www. decom. ufop

Slides:



Advertisements
Apresentações semelhantes
IFTO ESTRUTURA DE DADOS AULA 05 Prof. Manoel Campos da Silva Filho
Advertisements

LISTAS Dilvan Moreira, parcialmente baseado em material do prof. Ricardo Campello.
Aula T-09 – BCC202 Listas (Parte 1) Túlio Toffolo www. decom. ufop
Programação em Java Prof. Maurício Braga
Listas Encadeadas CONTEÚDO (1) Motivação (2) Definição (3) Operações
Estruturas de Dados Árvores Binárias
Listas encadeadas Prof. Rosana Palazon.
Listas duplamente encadeadas
Programação II Estruturas de Dados
TADS – Tipos Abstratos de Dados
TADS – Tipos Abstratos de Dados
Árvores.
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
David Menotti Estruturas de Dados I DECOM – UFOP
Filas David Menotti Estruturas de Dados I DECOM – UFOP.
Pesquisa em Memória Primária - Hashing
Pesquisa em Memória Primária – Árvores de Busca
Aula T11 – BCC202 Pilhas Túlio Toffolo
David Menotti Estruturas de Dados I DECOM – UFOP
Pilha David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP.
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
Pesquisa em Memória Primária – Árvores de Busca
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
Aula T12 – BCC202 Listas Túlio Toffolo
AED – Algoritmos e Estruturas de Dados
Estruturas de Dados I Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
Estruturas de Dados II Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
Estruturas de Dados II Prof.: Sergio Pacheco Prof.: Sergio Pacheco 1 1.
Listas com Ponteiros Listas encadeadas Listas circulares.
Slides: Prof. SIMÃO Revisão: Prof. João Fabro
Slides: Prof. João Fabro UTFPR - Curitiba
Lista Encadeada Circular Lista Duplamente Encadeada
Listas Encadeadas.
ALGORITMOS E ESTRUTURAS DE DADOS
exercícios listas encadeadas
Prof. Hilton Cardoso Marins Junior LISTA LINEAR
Pesquisa em memória primária: hashing
Listas Encadeadas Raquel O. Prates, Luiz Chaimowicz, Jussara Almeida
Algoritmos e Estruturas de Dados
LISTAS DUPLAMENTE ENCADEADAS
Pesquisa em Memória Primária
Árvores binárias de pesquisa com balanceamento
Estruturas de Dados com Jogos
Estruturas de Dados com Jogos
INTELIGÊNCIA ARTIFICIAL
Tipos Abstratos de Dados
Principais operações em Listas TPA Listas Simples Inserção no Final 1.void insereNofinalDaLista(Lista *l, Elemento e){ 2.Lista paux,p; 3. p.
Árvores Binárias de Pesquisa
TAD Pilha com Alocação Dinâmica de Memória
Implementação de FILAS com Alocação Dinâmica
Lista Encadeada Circular Lista Duplamente Encadeada
Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Denise Guliato Faculdade de Computação – UFU
Estruturas de Dados Aula 9: Listas (parte 1)
Lista encadeada Representar um grupo de dados.
Estruturas de Dados Aula 11: TAD Pilha
Árvore Binária de Busca
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática Disciplina: Estrutura de Dados Professor: Cheli dos S. Mendes da Costa Listas.
Tabelas Hash Prof. Túlio Toffolo
Módulo Compras Relatórios e Relações 1. Objetivo 2 Conhecer os relatórios e as relações do sistema disponibilizadas no módulo Compras.
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática
Prof. Alessandro Gonçalves
Estruturas de Dados Aula 10: Listas (parte 2) 07/05/2014.
Profa. Juliana Mafra ESTRUTURA DE DADOS 30 de Setembro de 2009 Faculdade de Informática e Tecnologia de Pernambuco.
Alocação Dinâmica Dilvan Moreira. Objetivos  Entender o que são e como usar:  Gerenciamento de Memória  Alocação Dinâmica em C.
Fundamentos de Programação 1 Slides 21 Prof.ª Fabiany e Prof. SIMÃO Linguagem C “Lista Encadeada”.
Fundamentos de Programação 1 Slides 22 Prof.ª Fabiany e Prof. SIMÃO Linguagem C “Lista Duplamente Encadeada - Projeto com vários Arquivos”.
UNIVERSIDADE FEDERAL DE MINAS GERAIS Listas Lineares Cristiano Arbex Valle Vinicius Fernandes dos Santos
Transcrição da apresentação:

Aula T10 – BCC202 Listas – Parte 2 Túlio Toffolo www. decom. ufop Aula T10 – BCC202 Listas – Parte 2 Túlio Toffolo www.decom.ufop.br/toffolo

Listas Encadeadas Características: Tamanho da lista não é pré-definido Cada elemento guarda quem é o próximo Elementos não estão contíguos na memória info NULL Vetor x Listas: Vetor: tamanho pré-definido, sabe qual o próximo, contíguo na memória Lista: não tem tamanho pré-definido, cada um guarda quem é o próximo, espalhados pela memória Figura Cada elemento armazenado numa lista guarda um ponteiro para o próximo elemento. O último elemento da lista possui um ponteiro inválido, indicando o término da estrutura. Com isto, a partir do primeiro elemento e percorrendo-se os ponteiros, pode-se acessar todos os elementos da lista. Portanto, numa lista encadeada, as informações não estão armazenadas de forma contínua na memória. Cada informação tem seu espaço de memória e é ligada à outra através de um enlace (ponteiro). Cada elemento é uma estrutura: informações + próximo da fila. Filas e pilhas dividem características comuns: Primeiro, ambas têm regras específicas para referenciar elementos às estruturas de dados. Segundo, operações de restauração são por natureza destrutivas, isto é, acessar um elemento em uma pilha ou fila requer sua retirada. info NULL prox info prox info info NULL prox

Sobre os Elementos da Lista Elemento: guarda as informações sobre cada elemento. Para isso define-se cada elemento como uma estrutura que possui: campos de informações ponteiro para o próximo elemento info prox

Sobre a Lista Uma lista pode ter uma célula cabeça info prox NULL Último Uma lista pode ter um apontador para o último elemento

Cria Lista Vazia NULL Cabeça Último

Inserção de Elementos na Lista info prox NULL Último 3 opções de posição onde pode inserir: 1ª. posição última posição Após um elemento qualquer E

Inserção na Primeira Posição info NULL prox prox info prox info prox info NULL Último

Inserção na Última Posição prox info prox info prox info NULL info NULL prox Último

Inserção Após o Elemento E info NULL prox prox info prox info prox info NULL Último Elem E

Retirada de Elementos na Lista info prox NULL Último 3 opções de posição de onde pode retirar: 1ª. posição última posição Um elemento qualquer E

Retirada do Elemento na Primeira Posição da Lista prox info prox info prox info NULL Último

Retirada do Elemento E da Lista prox info prox info prox info NULL Elem E Anterior Último

Retirada do Último Elemento da Lista prox info prox info prox info NULL NULL Anterior Último

Estrutura da Lista Usando Apontadores typedef int TipoChave; typedef struct { TipoChave Chave; /* outros componentes */ } TItem; typedef struct Celula* Apontador; typedef struct Celula { TItem Item; struct Celula* pProx; /* Apontador pProx; */ } TCelula; Apontador pPrimeiro; Apontador pUltimo; } TLista;

Operações sobre Lista Usando Apontadores (com Cabeça) void FLVazia(TLista* pLista) { pLista->pPrimeiro = (Apontador) malloc(sizeof(TCelula)); pLista->pUltimo = pLista->pPrimeiro; pLista->pPrimeiro->pProx = NULL; } int LEhVazia(TLista* pLista) return (pLista->pPrimeiro == pLista->pUltimo); void LInsere(TLista *pLista,TItem* pItem) pLista->pUltimo->pProx = (Apontador) malloc(sizeof(TCelula)); pLista->pUltimo = pLista->pUltimo->pProx; pLista->pUltimo->Item = *pItem; pLista->pUltimo->pProx = NULL;

Operações sobre Lista Usando Apontadores (sem Cabeça) void FLVazia(TLista *pLista) { pLista->pPrimeiro = NULL; pLista->pUltimo = NULL; } int LEhVazia(TLista* pLista) { return (pLista->pUltimo == NULL); } void LInsere(TLista* pLista,TItem* pItem) if (pLista->pUltimo == NULL) { pLista->pUltimo = (Apontador) malloc(sizeof(TCelula)); pLista->pPrimeiro = pLista->pUltimo; } else { pLista->pUltimo->pProx = (Apontador) malloc(sizeof(TCelula)); pLista->pUltimo = pLista->pUltimo->pProx; pLista->pUltimo->Item = *pItem; pLista->pUltimo->pProx = NULL;

Operações sobre Lista Usando Apontadores (com cabeça) int LRetira(TLista* pLista, TItem* pItem) { TCelula* pAux; if (LEhVazia(pLista)) return 0; *pItem = pLista->pPrimeiro->pProx->Item; pAux = pLista->pPrimeiro; pLista->pPrimeiro = pLista->pPrimeiro->pProx; free(pAux); return 1; }

Operações sobre Lista Usando Apontadores (sem cabeça) int LRetira(TLista* pLista, TItem* pItem) { TCelula* pAux; if (LEhVazia(pLista)) return 0; *pItem = pLista->pPrimeiro->Item; pAux = pLista->pPrimeiro; pLista->pPrimeiro = pLista->pPrimeiro->pProx; free(pAux); if (pLista->pPrimeiro == NULL) pLista->pUltimo = NULL; /* lista vazia */ return 1; }

Operações sobre Lista Usando Apontadores (com cabeça) void LImprime(TLista* pLista) { Apontador pAux; pAux = pLista->pPrimeiro->pProx; while (pAux != NULL) printf("%d\n", pAux->Item.Chave); pAux = pAux->pProx; /* próxima célula */ }

Operações sobre Lista Usando Apontadores (sem cabeça) void LImprime(TLista* pLista) { Apontador pAux; pAux = pLista->pPrimeiro; while (pAux != NULL) printf("%d\n", pAux->Item.Chave); pAux = pAux->pProx; /* próxima célula */ }

Operações sobre Lista Usando Apontadores Vantagens: Permite inserir ou retirar itens do meio da lista a um custo constante (importante quando a lista tem de ser mantida em ordem). Bom para aplicações em que não existe previsão sobre o crescimento da lista (o tamanho máximo da lista não precisa ser definido a priori). Desvantagem: Utilização de memória extra para armazenar os apontadores. Percorrer a lista, procurando pelo i-ésimo elemento.

Exemplo de Uso Listas - Vestibular Num vestibular, cada candidato tem direito a três opções para tentar uma vaga em um dos sete cursos oferecidos. Para cada candidato é lido um registro: Chave: número de inscrição do candidato. NotaFinal: média das notas do candidato. Opção: vetor contendo a primeira, a segunda e a terceira opções de curso do candidato.

Exemplo de Uso Listas - Vestibular Problema: distribuir os candidatos entre os cursos, segundo a nota final e as opções apresentadas por candidato. Em caso de empate, os candidatos serão atendidos na ordem de inscrição para os exames.

Vestibular - Possível Solução Ordenar registros pelo campo NotaFinal, respeitando a ordem de inscrição; Percorrer cada conjunto de registros com mesma NotaFinal, começando pelo conjunto de NotaFinal 10, seguido pelo de NotaFinal 9, e assim por diante. Para um conjunto de mesma NotaFinal tenta-se encaixar cada registro desse conjunto em um dos cursos, na primeira das três opções em que houver vaga (se houver).

Vestibular - Possível Solução Primeiro refinamento: main() { ordena os registros pelo campo NotaFinal ; for Nota = 10 até 0 do while houver registro com mesma nota do if existe vaga em um dos cursos de opcao do candidato then insere registro no conjunto de aprovados else insere registro no conjunto de reprovados; imprime aprovados por curso ; imprime reprovados; }

Vestibular - Classificação dos Alunos Uma boa maneira de representar um conjunto de registros é com o uso de listas. Ao serem lidos, os registros são armazenados em listas para cada nota. Após a leitura do último registro os candidatos estão automaticamente ordenados por NotaFinal. Dentro de cada lista, os registros estão ordenados por ordem de inscrição, desde que os registros sejam lidos na ordem de inscrição de cada candidato e inseridos nesta ordem.

Vestibular – Representação da Classificação dos Alunos

Vestibular - Classificação dos Alunos por Curso As listas de registros são percorridas, iniciando-se pela de NotaFinal 10, seguida pela de NotaFinal 9, e assim sucessivamente. Cada registro é retirado e colocado em uma das listas da abaixo, na primeira das três opções em que houver vaga. Se não houver vaga, o registro é colocado em uma lista de reprovados. Ao final a estrutura acima conterá a relação de candidatos aprovados em cada curso.

Vestibular - Classificação dos Alunos por Curso

Vestibular - Segundo Refinamento main() { lê número de vagas para cada curso; inicializa listas de classificação de aprovados e reprovados; lê registro; while Chave != 0 do //Ou while Chave do insere registro nas listas de classificação, conforme nota final; }

Vestibular - Segundo Refinamento for Nota = 10 até 0 do { while houver próximo registro com mesma NotaFinal do retira registro da lista; if existe vaga em um dos cursos de opção do candidato insere registro na lista de aprovados; decrementa o número de vagas para aquele curso; } else insere registro na lista de reprovados; obtém próximo registro; imprime aprovados por curso; imprime reprovados;

Vestibular - Estrutura Final da Lista #define NOpcoes 3 #define NCursos 7 #define FALSE 0 #define TRUE 1 typedef short TipoChave; typedef struct TipoItem { TipoChave Chave; char NotaFinal; char Opcao[NOpcoes]; } TipoItem; typedef struct Celula { TipoItem Item; struct Celula *pProx; } TipoCelula; typedef struct TipoLista { Celula *pPrimeiro, *pUltimo; } TipoLista;

Vestibular - Estrutura Final da Lista TipoItem Registro; TipoLista Classificacao[11]; TipoLista Aprovados[NCursos]; TipoLista Reprovados; long Vagas[NCursos]; short Passou; long i, Nota;

Vestibular - Refinamento Final Observe que o programa é completamente independente da implementação do tipo abstrato de dados Lista. void LeRegistro(TipoItem *Registro) { /* os valores lidos devem estar separados por brancos */ long i; int TEMP; scanf("%hd %d", &(Registro->Chave), &TEMP); Registro->NotaFinal = TEMP; for (i = 0; i < NOpcoes; i++) { scanf("%d", &TEMP); Registro->Opcao[i] = TEMP; } scanf(“%*[^\n]”); /* limpa buffer - fflush(stdin);*/ getchar();

Vestibular - Refinamento Final int main(int argc, char *argv[]) { /*---Programa principal---*/ for (i = 1; i <= NCursos; i++) scanf("%ld", &Vagas[i-1]); scanf("%*[^\n]"); /* limpa buffer – fflush(stdin); */ getchar(); for (i = 0; i <= 10; i++) FLVazia(&(Classificacao[i])); for (i = 0; i < NCursos; i++) FLVazia(&(Aprovados[i])); FLVazia(&Reprovados); LeRegistro(&Registro); while (Registro.Chave != 0) { LInsere(&Classificacao[Registro.NotaFinal],&Registro); } return 0;

Vestibular - Refinamento Final for (Nota = 10; Nota >= 0; Nota--) { while (!LEhVazia(&Classificacao[Nota])) { LRetira(Classificacao[Nota].Primeiro, &Classificacao[Nota], &Registro); i = 0; Passou = FALSE; while (i < NOpcoes && !Passou) { if (Vagas[Registro.Opcao[i]-1] > 0) { LInsere(&(Aprovados[Registro.Opcao[i]-1]), &Registro ); Vagas[Registro.Opcao[i]-1]--; Passou = TRUE; } i++; if (!Passou) LInsere(&Reprovados, &Registro); for (i = 0; i < NCursos; i++) { printf("Relacao dos aprovados no Curso%ld\n", i+1); Imprime(Aprovados[i]); printf("Relacao dos reprovados\n"); Imprime(Reprovados); return 0;

Vestibular - Refinamento Final O exemplo mostra a importância de utilizar tipos abstratos de dados para escrever programas, em vez de utilizar detalhes particulares de implementação. Altera-se a implementação rapidamente. Não é necessário procurar as referências diretas às estruturas de dados por todo o código. Este aspecto é particularmente importante em programas de grande porte.

Exercícios Qual seria a vantagem de uma lista duplamente encadeada? Escreva uma função que receba uma lista como parâmetro e retira o seu primeiro elemento, apagando-o. Escreva uma função que receba uma lista e um ponteiro para uma célula como parâmetros e insira a célula na primeira posição da lista.

Pilhas e Filas Pilha: Fila: Quem entra por último sai primeiro Quem entra primeiro sai primeiro

Pilha – Apontadores #define max 10 typedef int TipoChave; typedef struct { int Chave; /* --- outros componentes --- */ } TipoItem; typedef struct Celula*Apontador; typedef struct Celula { TipoItem Item; struct Celula* pProx; } Celula; Apontador pFundo, pTopo; int Tamanho; } TipoPilha;

Fila – Apontadores #include <stdlib.h> #include <sys/time.h> #include <stdio.h> #define max 10 typedef int TipoChave; typedef struct TipoItem { TipoChave Chave; /* outros componentes */ } TipoItem; typedef struct Celula *Apontador; typedef struct Celula { TipoItem Item; struct Celula *pProx; } Celula; typedef struct TipoFila { Apontador pFrente; Apontador pTras; } TipoFila;