Buscar

Estrutura de Dados Aula 7

Prévia do material em texto

Estrutura de Dados – Aula 7 1 
 
Lista Encadeada 
 
Primeiramente, o que seria uma lista encadeada? Simples, supondo que você tenha que 
fazer um programa que cadastre um número indefinido de pessoas, você irá criar uma 
matriz/vetor?… Errado, pois mesmo que você crie 1000 posições, isso irá consumir 
muito memória, desde o início do processo, sem contar que posso ter 800 pessoas, ou 
até mesmo 1200 pessoas, ou seja, o valor é variável, para isso é criado uma lista 
encadeada, que é manipulada de forma dinâmica. 
 
Exemplo de Lista Encadeada Dinâmica 
Basicamente, funciona da seguinte forma, você insere um valor, em uma estrutura, que 
pode ser chamada de Unidade, Posição ou Nó, a partir deste, você cria a próxima 
posição, ou seja, você aponta para uma nova posição, por isso em cada estrutura, além 
dos elementos comuns (como int, char, float), existe um elemento ponteiro, que irá 
apontar para o próximo elemento. 
Sendo que para criar as posições, deve-se usar alocação de memória, com a função 
MALLOC, e para excluir, é só usar o FREE, porém, a exclusão, não é tão simples, pois 
se você exclui a posição 3, a posição 2 agora, tem que apontar para a posição 4, que será 
a nova posição 3, então tem que se fazer um jogo com as variáveis. Abaixo um código 
fonte, adpato por mim, para ser usado tanto em Linux quanto Windows: 
//Bibliotecas utilizadas 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
 
//Se o sistema for Windows 
 //Adiciona determinada biblioteca, e 
 //definindo comandos de limpar e esperar 
#ifdef WIN32 
 #include <windows.h> 
 #define LIMPA_TELA system("cls") 
//Senão for Windows (ex.: Linux) 
#else 
 #include <unistd.h> 
 #define LIMPA_TELA system("/usr/bin/clear") 
 Estrutura de Dados – Aula 7 2 
 
#endif 
 
//Máximo de bytes para uma String 
#define BUFFER 64 
 
//Espera 3 segundos 
#define ESPERA sleep(3) 
 
//Estrutura da lista que será criada 
typedef struct lista { 
 char *nome; 
 int idade; 
 struct lista *proximo; 
} Dados; 
 
//Funções para manusear os dados (irão retornar dados) 
Dados *inicia_dados (char *nome, int idade); 
Dados *insere_dados (Dados *dados, char *nome, int idade); 
Dados *delbusca_dados(Dados *dados, char *chave); 
Dados *deleta_dados (Dados *dados, int nTipo); 
int checa_vazio (Dados *dados); 
 
//Funções para mostrar dados 
void exibe_dados (Dados *dados); 
void exibe_tamanho (Dados *nova); 
void busca_dados (Dados *dados, char *chave); 
 
//Funções do Menu 
void criavazia(void); //1 
void insereinicio(void); //2 
void inserefim(void); //3 
void listavazia(void); //4 
void prielemento(void); //5 
void ultelemento(void); //6 
void exibe(void); //7 
void exibetam(void); //8 
void deletapri(void); //9 
void deleta(void); //a 
void delbusca(void); //b 
void busca(void); //c 
 
//Inicializando os dados da lista 
Dados *principal = NULL; 
 
//--------------------------------- 
// Opção '1' 
//--------------------------------- 
 
//Criando uma lista vazia 
void criavazia(void){ 
 char *nome; 
 int idade; 
 //Alocando dados para uma String 
 nome = (char *)malloc(BUFFER); 
 //Lendo String Nome 
 fprintf(stdout, "\n\nDigite o Nome: \n----> "); 
 scanf("%s", nome); 
 fprintf(stdout, "\n"); 
 //Lendo int Idade 
 fprintf(stdout, "Digite a Idade: \n----> "); 
 scanf("%d", &idade); 
 Estrutura de Dados – Aula 7 3 
 
 fprintf(stdout, "\n"); 
 //Lançando os dados lidos na lista Principal 
 free(principal); 
 principal = inicia_dados(nome, idade); 
} 
 
//Iniciando os dados da lista vazia 
Dados *inicia_dados(char *nome, int idade) { 
 Dados *novo; 
 //Alocando memória para a posição atual da lista 
 novo = (Dados *)malloc(sizeof(Dados)); 
 //Lançando os dados lidos 
 novo->nome = (char *)malloc(strlen(nome)+1); 
 strncpy(novo->nome, nome, strlen(nome)+1); 
 novo->idade = idade; 
 //Apontando para a próxima posição da lista 
 novo->proximo = NULL; 
 return novo; 
} 
 
//--------------------------------- 
// Opção '2' 
//--------------------------------- 
 
//Inserindo no início da lista 
void insereinicio(void){ 
 char *nome; 
 int idade; 
 //Reservando espaço para String 
 nome = (char *)malloc(BUFFER); 
 //Armazenando String Nome 
 fprintf(stdout, "\n\nDigite o Nome: \n----> "); 
 scanf("%s", nome); 
 fprintf(stdout, "\n"); 
 //Armazenando int Idade 
 fprintf(stdout, "Digite a Idade: \n----> "); 
 scanf("%d", &idade); 
 fprintf(stdout, "\n"); 
 //Lançando dados no ínicio da lista 
 principal = insere_dados(principal, nome, idade); 
} 
 
//Inserindo dados recebidos 
Dados *insere_dados(Dados *dados, char *nome, int idade) { 
 Dados *inicio; 
 //Alocando memória para a posição atual 
 inicio = (Dados *)malloc(sizeof(Dados)); 
 //Lançando os dados lidos 
 inicio->nome = (char *)malloc(strlen(nome)+1); 
 strncpy(inicio->nome, nome, strlen(nome)+1); 
 inicio->idade = idade; 
 //O próximo valor aponta para a lista já existente 
 inicio->proximo = dados; 
 return inicio; 
} 
 
//--------------------------------- 
// Opção '3' 
//--------------------------------- 
 
//Inserção de dados no final de uma lista 
 Estrutura de Dados – Aula 7 4 
 
void inserefim(void) { 
 char *nome; 
 int idade; 
 //Alocação de espaço para String Nome 
 nome = (char *)malloc(BUFFER); 
 //Armazenando String Nome 
 fprintf(stdout, "\n\nDigite o Nome: \n----> "); 
 scanf("%s", nome); 
 fprintf(stdout, "\n"); 
 //Armazenando Int Idade 
 fprintf(stdout, "Digite a Idade: \n----> "); 
 scanf("%d", &idade); 
 fprintf(stdout, "\n"); 
 //Criando listas auxiliares 
 Dados *final,*aux; 
 //Alocando dados para a posição final da lista 
 final = (Dados *)malloc(sizeof(Dados)); 
 //Setando os valores Nome e Idade 
 final->nome = (char *)malloc(strlen(nome)+1); 
 strncpy(final->nome, nome, strlen(nome)+1); 
 final->idade = idade; 
 //A pŕoxima posição será Nulo 
 final->proximo=NULL; 
 //A lista auxiliar será igual a Principal 
 aux=principal; 
 //Enquanto o próximo de auxiliar não for Nulo 
 while(aux->proximo!=NULL){ 
 aux=aux->proximo; 
 } 
 //O último valor, será Nulo, e depois apontando para 
 //o Final 
 aux->proximo=NULL; 
 aux->proximo=final; 
} 
 
//--------------------------------- 
// Opção '4' 
//--------------------------------- 
 
//Função que testa se a lista está vazia 
void listavazia(void){ 
 if (principal == NULL) 
 fprintf(stdout, "\n\nLista esta Vazia!\n\n "); 
 else 
 fprintf(stdout, "\n\nLista nao esta Vazia!\n\n "); 
 getchar(); 
} 
 
//--------------------------------- 
// Opção '5' 
//--------------------------------- 
 
//Mostrar o primeiro elemento da lista 
void prielemento(void){ 
 fprintf(stdout, "------------------------\n"); 
 fprintf(stdout, "Nome: %s\n", principal->nome); 
 fprintf(stdout, "Idade: %d\n", principal->idade); 
 fprintf(stdout, "------------------------\n"); 
 getchar(); 
} 
 
 Estrutura de Dados – Aula7 5 
 
//--------------------------------- 
// Opção '6' 
//--------------------------------- 
 
//Mostrando o último elemento da lista 
void ultelemento(void){ 
 Dados *aux=principal; 
 //Enquanto o próximo elemento não for NULL 
 //Avance uma posição 
 while(aux->proximo!=NULL){ 
 aux=aux->proximo; 
 } 
 fprintf(stdout, "------------------------\n"); 
 fprintf(stdout, "Nome: %s\n", aux->nome); 
 fprintf(stdout, "Idade: %d\n", aux->idade); 
 fprintf(stdout, "------------------------\n"); 
 getchar(); 
} 
 
//--------------------------------- 
// Opção '7' 
//--------------------------------- 
 
//Exibindo dados da lista 
void exibe(void) { 
 //Se não estiver vazio, exibe os dados 
 if (!checa_vazio(principal)) 
 exibe_dados(principal); 
} 
 
//Exibindo todos os dados do menu 
void exibe_dados(Dados *dados) { 
 fprintf(stdout, "Cadastro:\n\n"); 
 fprintf(stdout, "------------------------\n"); 
 //Exibindo todos os valores da lista 
 for (; dados != NULL; dados = dados->proximo) { 
 fprintf(stdout, "Nome: %s\n", dados->nome); 
 fprintf(stdout, "Idade: %d\n", dados->idade); 
 fprintf(stdout, "------------------------\n"); 
 } 
 getchar(); 
} 
 
//--------------------------------- 
// Opção '8' 
//--------------------------------- 
 
//Exibindo o tamanho da lista 
void exibetam(void){ 
 //Se não estiver vazio, exibe os dados 
 if (!checa_vazio(principal)) 
 exibe_tamanho(principal); 
} 
 
//Exibindo o tamanho total (bytes) e quantidade 
void exibe_tamanho(Dados *nova){ 
 int aux=0, tamanho=0; 
 fprintf(stdout, "\n------------------------\n"); 
 //Correndo todos os valores da Lista 
 for (; nova != NULL; nova = nova->proximo) { 
 aux++; 
 Estrutura de Dados – Aula 7 6 
 
 tamanho+=sizeof(nova); 
 } 
 fprintf(stdout, "Total de Elementos: %d\nTamanho 
Total: %d bytes\n",aux,tamanho); 
 fprintf(stdout, "------------------------\n"); 
 getchar(); 
} 
 
//--------------------------------- 
// Opção '9' e 'a' 
//--------------------------------- 
 
//Deleta o Primeiro valor 
void deletapri(void) { 
 //Se não estiver vazio, deleta os dados 
 if (!checa_vazio(principal)) 
 principal = deleta_dados(principal,1); 
} 
 
//Deleta o Último valor 
void deleta(void) { 
 //Se não estiver vazio, deleta os dados 
 if (!checa_vazio(principal)) 
 principal = deleta_dados(principal,2); 
} 
 
//Deleta registros da lista 
 //Tipo 1 = Inicio 
 //Tipo 2 = Fim 
Dados *deleta_dados(Dados *dados, int nTipo) { 
 if(nTipo==1){ 
 //Apontando para a próxima posição 
 Dados *novo; 
 novo = dados->proximo; 
 //Limpando os dados 
 free(dados->nome); 
 free(dados); 
 fprintf(stdout, "O primeiro registro foi deletado 
 com sucesso.\n"); 
 getchar(); 
 return novo; 
 } 
 if(nTipo==2){ 
 Dados *novo=dados, *aux=dados; 
 //Se a lista estiver no fim, exclui o que restou 
 if(novo->proximo==NULL){ 
 free(novo); 
 aux=NULL; 
 } 
 else{ 
 //Laço de repetição para chegar no fim da lista 
 while(novo->proximo!=NULL){ 
 novo=novo->proximo; 
 } 
 //Preenchendo os dados da lista auxiliar 
 while(aux->proximo!=novo){ 
 aux=aux->proximo; 
 } 
 //Limpando os dados e apontando para nulo 
 free(novo); 
 aux->proximo=NULL; 
 Estrutura de Dados – Aula 7 7 
 
 } 
 fprintf(stdout, "O ultimo registro foi deletado 
 com sucesso.\n"); 
 getchar(); 
 return aux; 
 } 
} 
 
//--------------------------------- 
// Opção 'b' 
//--------------------------------- 
 
//Deletando valor buscado 
void delbusca(void) { 
 char *chave; 
 //Se não estiver vazio 
 if (!checa_vazio(principal)) { 
 chave = (char *)malloc(BUFFER); 
 //Armazenando o valor digitado 
 fprintf(stdout, "Digite o nome para buscar: \n 
--> "); 
 scanf("%s", chave); 
 //Deletando a chave buscada 
 principal = delbusca_dados(principal, chave); 
 } 
} 
 
//Deletando os valores buscados 
Dados *delbusca_dados(Dados *dados, char *chave) { 
 int achou=0,cont=0; 
 Dados *juntou, *aux, *nova=dados; 
 
 //Correndo a lista e verificando se encontrou 
 //a string buscada, se sim, aumenta o 
 //contador e seta a variável de busca 
 for (; nova != NULL; nova = nova->proximo) { 
 if (strcmp(chave, nova->nome) == 0) { 
 achou=1; 
 cont++; 
 } 
 } 
 
 //Se encontrou a busca 
 if(achou==1){ 
 int ind=0; 
 //Correndo a lista 
 for(ind=0;ind<cont;ind++){ 
 //Se encontrou na primeira casa 
 //apaga a primeira casa 
 if(strcmp(chave,dados->nome)==0){ 
 aux=dados; 
 dados=dados->proximo; 
 free(aux); 
 } 
 //Senão, procura até encontrar 
 else{ 
 aux=dados; 
 //Posiciona na frente do encontro 
 //para exclusão 
 while(strcmp(chave,aux->nome)!=0){ 
 aux=aux->proximo; 
 Estrutura de Dados – Aula 7 8 
 
 } 
 
 juntou=dados; 
 //Enquanto o auxiliar juntou for 
 //diferente do posicionado para 
 //exclusão 
 while(juntou->proximo!=aux){ 
 juntou=juntou->proximo; 
 } 
 //Aponta para o próximo valor válido 
 juntou->proximo=aux->proximo; 
 
 free(aux); 
 } 
 } 
 fprintf(stdout, "Excluido.\n"); 
 } 
 else 
 fprintf(stdout, "Nenhum resultado encontrado.\n"); 
 
 getchar(); 
 return dados; 
} 
 
//--------------------------------- 
// Opção 'c' 
//--------------------------------- 
 
//Função que busca os dados 
void busca(void) { 
 char *chave; 
 //Senão estiver vazio a lista 
 if (!checa_vazio(principal)) { 
 chave = (char *)malloc(BUFFER); 
 //Lendo o nome que será buscado 
 fprintf(stdout, "Digite o nome para buscar: \n 
--> "); 
 scanf("%s", chave); 
 //chamando a função que irá procurar o nome 
 busca_dados(principal, chave); 
 } 
} 
 
//Percorre cada ponta da lista verificando busca 
void busca_dados(Dados *dados, char *chave) { 
 int achou = 0; 
 fprintf(stdout, "Cadastro:\n\n"); 
 //Percorrendo todas as posições 
 for (; dados != NULL; dados = dados->proximo) { 
 //Se encontrou, mostra os dados 
 if (strcmp(chave, dados->nome) == 0) { 
 fprintf(stdout, "------------------------\n"); 
 fprintf(stdout, "Nome: %s\n", dados->nome); 
 fprintf(stdout, "Idade: %d\n", dados->idade); 
 fprintf(stdout, "------------------------\n"); 
 achou++; 
 } 
 } 
 
 //Mostrandoo resultado da busca 
 if (achou == 0) 
 Estrutura de Dados – Aula 7 9 
 
 fprintf(stdout, "Nenhum resultado encontrado.\n"); 
 else 
 fprintf(stdout, "Foram encontrado(s) %d registro(s) 
.\n", achou); 
 
 getchar(); 
} 
 
//--------------------------------- 
// Função Auxiliar 
//--------------------------------- 
 
//Função que testa se a lista esta vazia 
int checa_vazio(Dados *dados) { 
 //Se a lista estiver vazia 
 if (dados == NULL) { 
 fprintf(stdout, "Lista vazia!\n"); 
 getchar(); 
 return 1; 
 } else 
 return 0; 
} 
 
//--------------------------------- 
// Função Principal 
//--------------------------------- 
 
int main(void) { 
 char escolha; 
 int chave=0; 
 //Laço que irá mostrar o menu esperando uma opção 
 (char) 
 do { 
 //Limpando a tela, e mostrando o menu 
 //lembrando que primeiramente, os itens estão 
 //bloqueados até que seja criada uma lista vazia 
 LIMPA_TELA; 
 fprintf(stdout, "\n\t\tCadastro de Pessoas\n\n"); 
 fprintf(stdout, "Escolha uma opcao: \n"); 
 fprintf(stdout, "1 - Criar lista vazia\n"); 
 if(chave==1){ 
 fprintf(stdout, "2 - Inserir no Inicio de uma 
 lista\n"); 
 fprintf(stdout, "3 - Inserir no Fim de uma 
 lista\n"); 
 } 
 fprintf(stdout, "4 - Lista Vazia...\n"); 
 if(chave==1){ 
 fprintf(stdout, "5 - Exibir dados do primeiro 
 elemento\n"); 
 fprintf(stdout, "6 - Exibir dados do ultimo 
 elemento\n"); 
 fprintf(stdout, "7 - Exibir todos os valores 
 da Lista\n"); 
 fprintf(stdout, "8 - Exibir o tamanho da 
 Lista\n"); 
 fprintf(stdout, "9 - Eliminar primeiro 
 elemento\n"); 
 fprintf(stdout, "a - Eliminar último 
 elemento\n"); 
 fprintf(stdout, "b - Eliminar elemento 
 Estrutura de Dados – Aula 7 10 
 
 buscado\n"); 
 fprintf(stdout, "c - Busca Dados\n"); 
 } 
 fprintf(stdout, "d - Sair\n\n"); 
 fprintf(stdout, "Resposta: "); 
 scanf("%c", &escolha); 
 //Se a chave for diferente de zero, porém a 
 //escolha for diferente 
 //de 1, 4 e d, a escolha será z (opção inválida) 
 if((chave==0)&&((escolha!='1')&&(escolha!='d') 
&&(escolha!='4'))) 
 escolha='z'; 
 switch(escolha) { 
 //Criando lista vazia 
 case '1': 
 chave=1; 
 criavazia(); 
 break; 
 //Inserindo no início 
 case '2': 
 insereinicio(); 
 break; 
 //Inserindo no final 
 case '3': 
 //Se a lista não estiver vazia 
 if(principal!=NULL){ 
 inserefim(); 
 } 
 //senão inclui no inicio 
 else{ 
 insereinicio(); 
 } 
 break; 
 //Checando se a lista está vazia 
 case '4': 
 listavazia(); 
 break; 
 //Mostrando Primeiro elemento 
 case '5': 
 prielemento(); 
 break; 
 //Mostrando Último elemento 
 case '6': 
 ultelemento(); 
 break; 
 //Exibindo todos elementos 
 case '7': 
 exibe(); 
 break; 
 //Exibindo tamanho da lista 
 case '8': 
 exibetam(); 
 break; 
 //Deleta primeiro elementos 
 case '9': 
 deletapri(); 
 break; 
 //Deleta último elemento 
 case 'a': 
 deleta(); 
 break; 
 Estrutura de Dados – Aula 7 11 
 
 //Deleta elemento buscado 
 case 'b': 
 delbusca(); 
 break; 
 //Buscando elementos 
 case 'c': 
 busca(); 
 break; 
 //Saindo e finalizando o programa 
 case 'd': 
 fprintf(stderr,"Obrigado por utilizar 
 esse programa!\n"); 
 fprintf(stderr,"------>Terminal de 
 Informação<------\n\n"); 
 ESPERA; 
 exit(0); 
 break; 
 //Se foi algum valor inválido 
 default: 
 fprintf(stderr,"Digite uma opcao valida 
 (pressione -Enter- p/ continuar)!\n"); 
 getchar(); 
 break; 
 } 
 //Impedindo sujeira na gravação da escolha 
 getchar(); 
 } 
 while (escolha > 0); //Loop Infinito 
 return 0; 
} 
Um print, do programa em execução no OpenSUSE: 
 
 Estrutura de Dados – Aula 7 12 
 
Exemplo de Programa que usa Lista Encadeada 
 
Referência Bibliográfica 
Este material foi retirado de : 
http://terminaldeinformacao.com/2013/05/19/lista-encadeada-em-linguagem-c

Continue navegando

Outros materiais