Ir ao conteúdo

Lista Encadeada & Duplamente Encadeada


edersonsergiocoelho

Posts recomendados

Postado

Gente to precisando de uma ajuda desesperada de um código fonte funcionando de lista encadeada e duplamente encadeada na linguagem c mais que seja bem simples, mais simples que tiver... Tenho prova amanha e nao to conseguindo aprender o assunto passei todo fim de semana agora e não consigo aprender nada do assunto, é muito difícil, e o pior está sendo porque não tenho nenhum exemplo que preste professor fez uns la na classe mais quem disse que roda...

Precisava de um código fonte das duas listas com pelo menos mostrando nome, sexo e idade... Como inserir, remover, e inserir no final da lista...

Por favor se alguém puder me ajudar!

Postado

Bom, como você aparentemente não teve acesso a boas referências, te indico um excelente livro, mas não vou te dar essa "cola" que você quer levar pra prova. Dê uma olhada no livro Introdução a Estruturas de Dados, Celes, Cerqueira e Rangel, um livro excelente e claro que eu usei.

Colando assim você está "cavando a própria cova', pois não vai aprender nada e nem adianta tentar decorar os códigos pois não vai conseguir mesmo.

Postado

Cara, entenda minha parte: eu nao quero para colar nao, e para poder entender entende que eu nao tenho muito tempo minha prova e amanha eu ja tenho varias noções sobre a lista encadeada, que custa da uma ajuda... Eu fazendo uma depuracao manualmente posso entender... Que eu acho o melhor metodo para aprender é depurando o programa manualmente e entendendo tudo que ele está fazendo...

Os exemplos que o professor passa está um lixo variaveis erradas, monte de coisa, que eu não consegui ajeitar se quiser posso colocar aqui pra você da uma olhada e me ajuda com pelo menos esse então...

  • Membro VIP
Postado

Não sei se ainda dá tempo para a prova, mas de qualquer forma é necessário que você aprenda esta estrutura de dados, então dê uma olhada na Wikipédia, lá há umas explicações simplificadas e objetivas da lógica dessa estrutura e também tem um código como exemplo.

Postado

Entenda que não basta ter o código em mãos. Tem que entender como a coisa funciona, senão vai ficar todo perdido quando olhar os ponteiros da estrutura. Pra isso é necessário ter uma boa referência bibliográfica e não apenas o código.

Postado

Concordo com você. O Problema é essa referência. Os livros são muito complicados e Difíceis de entender, eu já vi esse livro que você falou, já até peguei ele pra estudar, mas não me ajudou em nada. Bom, mas agora to entedendo um pouco mais das listas, to com dificuldade de fazer a função para remover, já estou sabendo fazer direito a lista com as funções de inserir, listar... Agora essa de remover complicado...

Postado

Discordo. Esse livro "Introdução à Estruturas de Dados" é super simples e objetivo nas explicações. Se você acha esse difícil de entender, imagina muitos outros então....

Bom, mas quanto à função de remover, realmente ela é uma das mais difíceis nas listas encadeadas. Mas existem 2 casos:

1º - Como a lista encadeada é na verdade um ponteiro para o primeiro elemento, e se o elemento a ser removido for o primeiro, tudo o que você tem que fazer é fazer o ponteiro para a lista apontar para o segundo elemento e logo em seguida usar a função free() para liberar o primeiro elemento. Assim, a lista agora será o ponteiro para o segundo elemento e aquele que era o primeiro foi liberado. É importante salientar que você deve seguir essa ordem, senão irá perder toda a lista, ou seja, primeiro deves fazer o ponteiro apontar para o segundo elemento e só depois liberar o que era o primeiro.

2º - Se o elemento a ser removido for algum que estiver "no meio" da lista (na verdade qualquer um que não seja o primeiro), você deve pegar o ponteiro do elemento anterior e fazê-lo apontar para o posterior ao elemento a ser retirado. Após feito isso você deve usar a função free() para liberar o elemento que se quer remover. Se a lista for uma duplamente encadeada, o acerto do encadeamento deve ser feito para os dois ponteiros (o que aponta para o próximo e o que aponta para o posterior).

Já que você está com o livro em mãos, nem preciso colocar os códigos aqui, mas se houver alguma dúvida poste.

Abraços.

  • Membro VIP
Postado

Sem fazer tempestade ai com ao user.É bom que você estude um pouco sobre as ED's(estruturas de dados) e depois aprofunde bem nas TAD's(tipos abstratos de dados).Aprender isso de um dia pro outro sem saber ponteiro fico um pouco complicado.Boa sorte.

Postado

Gente To Precisando Ajuda Ainda Nas Lista Exatamente Numa Lista Duplamente Encadeada To Tentando Rodar Aqui Mais Nao To Conseguindo A Função Imprimir Nao Imprime Nao Sei Que Esta Dando Errado, Fiz Conforme Os Exemplos Do Professor Do Jeito Que Ele Ensinou...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
struct Pessoa {
char nome[50];
char sexo;
int idade;
Pessoa *prox;
Pessoa * ant;
};
Pessoa *criar(Pessoa *L) {
Pessoa *novo;
char nome[50];
char sexo;
int idade;
novo = (Pessoa *)malloc(sizeof(Pessoa));
printf("Informe O Nome: ");
fflush(stdin);
gets(nome);
printf("Informe O Sexo: ");
fflush(stdin);
scanf("%c", &sexo);
printf("Informe A Idade: ");
scanf("%d", &idade);
strcpy(novo->nome, nome);
novo->sexo = sexo;
novo->idade = idade;
novo->prox = NULL;
novo->ant = NULL;
return(novo);
}
Pessoa *insere(Pessoa *L) {

char nome[50];
char sexo;
int idade;
Pessoa *novo = (Pessoa *)malloc(sizeof(Pessoa));
printf("Informe O Nome: ");
fflush(stdin);
gets(nome);
printf("Informe O Sexo: ");
fflush(stdin);
scanf("%c", &sexo);
printf("Informe A Idade: ");
scanf("%d", &idade);
strcpy(novo->nome, nome);
novo->sexo = sexo;
novo->idade = idade;
novo->prox = L;
novo->ant = NULL;
if(L!=NULL){
L->ant=novo;
}
return novo;
}
void imprimir(Pessoa *L) {
for( ; L->prox != NULL; L = L->prox) {
printf("Nome: %s, Sexo: %c, Idade: %d \n",L->nome, L->sexo, L->idade);
}
}

main() {
Pessoa *L = NULL;
int op;
do {
printf("1-Para Criar\n");
printf("2-Para Inserir\n");
printf("3-Para Imprimir\n");
printf("4- Para Remover\n");
printf("5-Para Sair\n");
scanf("%d", &op);
switch(op) {
case 1:
L = criar(L);
break;
case 2:
L = insere(L);
break;
case 3:
imprimir(L);
break;
case 4:
//L = remove(L);
break;
case 5:
getch();
exit(1);
}
}while(op != 5);
}

Postado

Caro colega edinhocoelho, se seu professor te ensinou fazer desse jeito, lamento em dizer, procure outro professor ou troque de faculdade......:wacko:

As funções Pessoa *criar(Pessoa *L) e Pessoa *insere(Pessoa *L) pedem os mesmos dados do usuário, 2 vezes. Isso é totalmente desnecessário.

As variáveis nome[50], sexo e idade também são desnecessárias e consomem memória a toa. Durante a leitura dos dados pelo teclado, basta fazer a função scanf atribuir diretamente à estrutura struct Pessoa, assim:


gets(novo->nome);
.
.
.
scanf("%c", &novo->sexo);
.
.
.
scanf ("%d", &novo->idade);

O encadeamento no final da função Pessoa *insere(Pessoa *L) também está totalmente errado.

Postado

valeu Pelas Dica Ja Implementei No Meu Codigo então Amigo Gostaria Que você Me Ensinasse Agora Arrumar A Funcao Insere Deixar Em Uma So Agora Ja Que voce Falou Que Ter Criar E Inserir E Totalmente Desnecessario, Realmente Ta Muito difícil Aprender Com Esse Professor De Estrutura De Dados Acabei De Crer Agora Que Nem Ele Sabe O Que Faz...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
struct Pessoa {
char nome[50];
char sexo;
int idade;
Pessoa *prox;
Pessoa * ant;
};
Pessoa *inserir(Pessoa *L) {
Pessoa *novo;
novo = (Pessoa *)malloc(sizeof(Pessoa));
printf("Informe O Nome: ");
fflush(stdin);
gets(novo->nome);
printf("Informe O Sexo: ");
fflush(stdin);
scanf("%c", &novo->sexo);
printf("Informe A Idade: ");
scanf("%d", &novo->idade);
novo->prox = NULL;
novo->ant = NULL;
return(novo);
}
void imprimir(Pessoa *L) {
for( ; L->prox != NULL; L = L->prox) {
printf("Nome: %s, Sexo: %c, Idade: %d \n",L->nome, L->sexo, L->idade);
}
}
main() {
Pessoa *L = NULL;
int op;
do {
printf("1 - Para Inserir\n");
printf("2 - Para Imprimir\n");
printf("3 - Para Remover\n");
printf("4 - Para Sair\n");
scanf("%d", &op);
switch(op) {
case 1:
L = inserir(L);
break;
case 2:
imprimir(L);
break;
case 3:
//L = remove(L);
break;
case 4:
getch();
exit(1);
}
}while(op != 4);
}

Postado

Quanto à leitura de dados está correto, mas ainda precisa acertar o encadeamento. Segue um código de inserção de novos elementos numa lista duplamente encadeada.

OBS: É usual sempre inserir novos elementos no INÍCIO da lista encadeada, pois isso facilita a inserção e remoção de elementos.


/*Struct que define o tipo lista duplamente encadeada*/

struct lista2 {
int info;
struct lista2* ant;
struct lista2* prox;
};

typedef struct lista2 Lista2; // estou redefinindo o nome da struct para Lista2



Lista2* lst2insere (Lista2* l, int v)
{
Lista2* novo = (Lista2*) malloc(sizeof(Lista2));
novo->info = v;
novo->prox = l;
novo->ant = NULL;

/*agora a função verifica se a lista não está vazia*/

if (l != NULL)
{
l->ant = novo;
return novo;
}

}

Agora compare com a sua função de inserir e tente encontrar as diferenças. Qualquer dúvida só perguntar.

  • Membro VIP
Postado

Vamos colocar as tags de spoiler nesses códigos.Da próxima vez vou tomar outras medidas.Abraço a todos.

Postado

É Gente Ta difícil Viu Tentei De Tudo Aqui Ainda Nada, Nao Ta Imprimindo O Primeiro Registro Os Demais Imprime Mais Nao Consegui Fazer Como Ele Guardasse O Primeiro Olha O Codigo Alguem Da Uma Dica Pra Onde Vai Agora...

Pessoa *inserir(Pessoa *L) {
Pessoa *novo;
novo = (Pessoa *)malloc(sizeof(Pessoa));
printf("Informe O Nome: ");
fflush(stdin);
gets(novo->nome);
printf("Informe O Sexo: ");
fflush(stdin);
scanf("%c", &novo->sexo);
printf("Informe A Idade: ");
scanf("%d", &novo->idade);
novo->prox = L;
novo->ant = NULL;
if (L != NULL){
L->ant = novo;
}
return novo;
}

Postado

Na função void imprimir (Pessoa* L) você precisa usar uma variável auxiliar para percorrer a lista, assim:


void imprimir(Pessoa *L) {

Pessoa* aux;
for(aux=L; aux != NULL; aux= aux->prox) {
printf("Nome: %s, Sexo: %c, Idade: %d \n",aux->nome, aux->sexo, aux->idade);
}
}

Antes não estava imprimindo o 1º elemento da lista porque quando você faz:


for( ; L->prox != NULL; L = L->prox)

o L->prox != NULL já vai logo pro 2º elemento da lista (L->prox), pulando então o 1º elemento.

Postado

OK Consegui Fazer A Funçao Mais Agora Gostaria De Saber Como Fazer O Remove Pra Tirar O Elemento Que Eu Queira Nao Sempre O Ultimo Para A Lista Duplamente Encadeada...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
struct Pessoa {
char nome[50];
char sexo;
int idade;
Pessoa *prox;
Pessoa * ant;
};
Pessoa *inserir(Pessoa *L, int i) {
Pessoa *novo;
novo = (Pessoa *)malloc(sizeof(Pessoa));
printf("Cadastro [%d]\n\n", i);
printf("Informe O Nome: ");
fflush(stdin);
gets(novo->nome);
printf("Informe O Sexo: ");
fflush(stdin);
scanf("%c", &novo->sexo);
printf("Informe A Idade: ");
scanf("%d", &novo->idade);
novo->prox = L;
novo->ant = NULL;
if (L != NULL){
L->ant = novo;
}
printf("\nCadastro Concluido Com Sucesso");
getch();
return novo;
}
void imprimir(Pessoa *L) {
Pessoa *Lista;
for(Lista = L ; Lista != NULL; Lista = Lista->prox) {
printf("Nome: %s, Sexo: %c, Idade: %d \n", Lista->nome, Lista->sexo, Lista->idade);
}
getch();
}
Pessoa *remover(Pessoa *L) {
Pessoa *temp = L;
if (temp == NULL)
return (L);
if (L == temp)
L = temp->prox;
else
temp->ant->prox = temp->prox;
if (temp->prox != NULL)
temp->prox->ant = temp->ant;
free(temp);
printf("Ultimo Cadastro Removido Com Sucesso");
getch();
return (L);
}
main() {
Pessoa *L = NULL;
int op, i = 0;
do {
printf("1 - Para Inserir\n");
printf("2 - Para Imprimir\n");
printf("3 - Para Remover Ultimo Cadastro\n");
printf("4 - Para Sair\n");
printf("\n----------------------------------------------------------------------\n\n");
printf("Informe A Opcao: ");
scanf("%d", &op);
printf("\n----------------------------------------------------------------------\n\n");
switch(op) {
case 1:
i += 1;
L = inserir(L, i);
break;
case 2:
imprimir(L);
break;
case 3:
L = remover(L);
break;
case 4:
exit(1);
getch();
}
system("cls");
}while(op != 4);
}

:)

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!