Ir ao conteúdo
  • Cadastre-se

C Lista encadeada em C


XisDeeeeee

Posts recomendados

Estou tentando inserir um elemento no início de uma lista encadeada: 

 

#include <stdio.h>
#include <stdlib.h>

typedef struct Valor {
    int value;
    struct Valor* prox;
} Valor, *POINTER;

Valor* ptrEncadeada = NULL;

void imprimeEncadeada(Valor* ptrEncadeada) {
    POINTER ptr = ptrEncadeada;
    while (ptr != NULL) {
        printf("%d ", ptr->value);
        ptr = ptr->prox;
    }
    puts("");
}

void Inserir(Valor* ptrEncadeada, int value) {
    POINTER newValue = malloc(sizeof(Valor));
    newValue->value = value;
    newValue->prox = ptrEncadeada;

    ptrEncadeada = newValue;

    free(newValue);
}

int main(void) {
    Inserir(ptrEncadeada, 5);
    imprimeEncadeada(ptrEncadeada);
    return 0;
}

Minha dúvida é: por que mesmo depois da inserção a lista ainda continua vazia?

Link para o comentário
Compartilhar em outros sites

Mude a declaração de Inserir() para retornar o novo endereço do início da lista ou ele vai se perder...

 

Use 


Valor* Inserir(Valor*, int );

 

Declare a lista em main(), mais seguro. Declare apenas estruturas e protótipos fora de main().

 

Imprima a lista lista antes de inserir. É um bom começo saber que pode listar uma lista vazia

 

Com algo assim você progride mais depressa:

int main(void)
{
  Valor* aLista = NULL;  
  imprimeEncadeada(aLista);
  
  for(int i=0; i<5; i+=1)
  {
    aLista = Inserir(aLista, i);
    imprimeEncadeada(aLista);
  }
  return 0;
}

Escreva a função que apaga a lista toda, com o mesmo protótipo que inserir()

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Uma breve explicação sobre ponteiros.

#include <stdio.h>

int main(void)
{
  /* Declara uma variavel com o nome de valor
   e um ponteiro com o nome de ponteiro */
  int valor=32,*ponteiro;
  ponteiro=&valor;    /* Passa o endereço da variavel valor para a variavel ponteiro */
  /* Mostra o local da variavel ponteiro na memoria */
  printf("\n%p",&ponteiro);
  /* Mostra o local da variavel valor na memoria */
  printf("\n%p",&valor);
  /* Mostra o valor da variavel valor */
  printf("\n%i",*ponteiro);
  /* Mostra o endereço apontado por ponteiro, que é basicamente o endereço da variavel valor */
  printf("\n%p",ponteiro);
  getchar();
  return(0);
}

Se você reparou bem, isso significa que nós temos que passar o endereço do ponteiro e não o endereço que ele aponta.

 

Um exemplo de lista encadeada

#include <stdio.h>
#include <stdlib.h>

/* Tipos */
typedef struct Lista
{
  int valor;
  struct Lista *proximo;
}TLista;

int main(void)
{
  TLista *inicio=NULL,*ponteiro=NULL;
  int valor;
  do
  {
    printf("\nDigite um valor:\t");
    scanf("%i%*c",&valor);
    if(inicio==NULL)
    {
      /* Reserva memoria para o primeiro ponteiro */
      inicio=malloc(sizeof(TLista));
      if(inicio==NULL)
        return(1);    /* ERRO */
      inicio->valor=valor;
      inicio->proximo=NULL;
      ponteiro=inicio;
    }
    else
    {
      ponteiro=ponteiro->proximo=malloc(sizeof(TLista));
      if(ponteiro==NULL)
        return(1);
      ponteiro->valor=valor;
      ponteiro->proximo=NULL;
    }
    printf("\nDigite 1 para sair ou 2 para continuar:\t");
    scanf("%i%*c",&valor);
  }while(valor!=1);
  /* Mostra a lista */
  ponteiro=inicio;
  while(ponteiro!=NULL)
  {
    printf("\n%i",ponteiro->valor);
    ponteiro=ponteiro->proximo;
  }
  /* Apaga a lista */
  ponteiro=inicio;
  while(ponteiro!=NULL)
  {
    inicio=ponteiro->proximo;
    free(ponteiro);
    ponteiro=inicio;
  }
  getchar();    /* Pausa */
  return(0);
}

Então resumindo. se vocẽ quer modificar o endereço de um ponteiro você tem que passar para a função como ponteiro para ponteiro. Exemplo: void Insere(TLista **ponteiro)

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@XisDeeeeee Bom Dia !

Sugestão, deixe o primeiro nó da "lista" um nó vazio.

 

typedef struct Valor {
    int value;
    struct Valor* prox;
} Valor, *POINTER;

Valor encadeada = {0};

 

– O Início é o próximo desse nó especialmente designado !!!

/* 02/2020 Colaboração do Prof ... */
void Inserir(POINTER ptrEncadeada, int value) {
    POINTER newValue = malloc(sizeof (*POINTER));

    newValue->value = value;
    newValue->prox = ptrEncadeada->prox;

    ptrEncadeada->prox = newValue;
}

 

– Parece aceitável !? É muito simples.

A função determina que o primeiro ponteiro (esse por argumento) tem value imutável e faz inserção posterior com a troca de apontadores entre o novo elemento e o primeiro do conjunto hipotético, pois toda lista é um conjunto no caso o primeiro nó é o seu nome com os demais de elementos.

 

Bons Estudos!

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Esqueci de comentar isso, mas ao inserir em uma lista você parece ter optado pelo caminho curto, inserir no início.

Mas no propósito geral de usar uma lista encadeada muitas vezes se espera

  • manter a ordem de inserção --- a lista é dita estável --- de modo que ao percorrer a lista você vê os elementos na ordem em que foram inseridos. O primeiro listado será o primeiro inserido e assim por diante.
  • manter a lista ordenada --- e se usa claro algum campo e uma função de comparação --- de modo que ao percorrer a lista os elementos vem classificados, por ordem crescente, por CEP, por endereço de entrega, por algo útil na aplicação que usa sua lista.

E nesses casos você precisaria inserir de acordo...

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

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...