Ir ao conteúdo
  • Cadastre-se
UmPrograma

C Lista Encadeada, retirar Ultimo elemento

Recommended Posts

Olá, boa tarde pessoal.

 

Estava tentando resolver um exercício em de lista encadeada aqui, mas estou com muita duvida ainda. Principalmente que parece para a resolução dão problema a gente deve ir criando varias outras struct's.

 

No exercício proposto pelo professor ele pede que seja retirado o ultimo elemento da lista. No entanto não estou conseguindo resolver o problema.

(Estou buscando ajuda em um livro que tenho aqui( de Waldemar Celes, introdução a estrutura de dados) e pela própria Internet. Mas confesso que esta muita difícil assimilar algo.)

 

Caso possam, olhem o o meu código.

 

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

/// o l é o nó, que liga as cadeias.


struct lista{
    int info;
    struct lista* prox;
};
typedef struct lista Lista;
void inserir(Lista *l){
    Lista* novo= (Lista*)malloc(sizeof(Lista));
    if(!novo){
        printf("SEM MEMORIA!\n");
        exit(1);
    }
    printf("\nInforme um valor: ");
    scanf("%d", &novo->info);
    if(l!=NULL){
        l->prox=novo;
    }
    else{
        Lista *aux = l-> prox;
        while(aux->prox!= NULL){
            aux=aux->prox;
        }
        aux->prox=novo;
    }
}

Lista *retira_ultimo(Lista *l){
    if(l!=NULL){
        printf("Lista vazia.\n");
        return NULL;
    }
    else{
        Lista *ultimo = l->prox, *penultimo = l->prox;
        while(ultimo->prox!=NULL){
            penultimo=ultimo;
            ultimo=ultimo->prox;
        }
        penultimo->prox=NULL;
        return ultimo;
    }
}
main(){
    int op=1;
    Lista *l= (Lista*)malloc(sizeof(Lista));
    l ->prox = NULL;
    Lista* novo= (Lista*)malloc(sizeof(Lista));

    inserir(l);
    while(op==1){
        printf("Inserir novo elemento: 1 <sim> outro valor <nao> : ");scanf("%d", &op);
        if (op==1)
            inserir(l);
    }

    retira_ultimo(l);

    printf("\n\nA lista depois de retirar o ultimo numero digitado e o seguinte.\n\n");
    if(l!=NULL){
        printf("Lista vazia.\n");
    }
    Lista *aux = l->prox;
    while(aux!=NULL){
        printf("%d\n", aux->info);
        aux=aux->prox;
    }

    return 0;
}

 

Tenho muita dificuldade na estrutura "cabeça" e na necessidade de se criar um monte de struct a partir dela. 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

 

 

Uai porque nao estou conseguindo fazer o programa rodar no code blocks, parece esta demorando mais do que o necessario (demorando como nas funcoes recursivas kkkk), mas no site Repl.it esta funcionando o código. Se alguem puder me dar uma luz.

(E uma leve explicacao. Esse conteudo confunde muito.)

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Josesousa Está com dúvida em qual função? Já com relação a executar em um local e outro não demostra que há erros lógicos no código. 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@AnsiC Você conseguiu rodar e deu tudo certo?

 

Na verdade peguei uns programas parecidos e tentei analisa-los e tentei fazer o meu, que nao funcionou direito, so que ainda nao entendo isso de uma estrutura cabeça e um monte de estruturas que fazem uso dela. (nao sei se da para entender, mas no codigo por exemplo a Lista l e a Lista novo vem da lista Lista, não consigo compreender muito bem isso.)

 

Aqui no meu compilador nao deu para rodar nao, so no site https://repl.it/repls/BlueSilverShell .

 

Ainda me perco com essas Listas, pois a Lista l parece ser mais importante por ser o nó, mas é na Lista novo que as informações estão e a nó parece que serve apenas para ligar. Nao sei.....

 

Aí funcionou???

adicionado 17 minutos depois

 

 

Tem uma funcao que um monte de codigo usa que e a seguinte.

int vazia(Lista *node){
    if(node->prox==NULL){
        return 1;
    }
    else
        return 0;
}

 

Tentei substituui-la pelo if (l!=NULL), nao sei se e a mesma coisa. Julguei ser esse o motivo do meu problema de o codigo nao rodar. To muito perdido.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara o que me ajudou a entender listas encadeadas foi desenhar ela . E entender do zero o que cada função/estrutura esta fazendo. Se tiver dúvidas eu tenho uma lista com algumas funções.

https://github.com/igorvargasp/C--codes

 

Sua função inserir pode ser algo mais simples. Pequena sugestão.

 

Lista* inserir(Lista *l, int valor){
    Lista* novo= (Lista*)malloc(sizeof(Lista));
    if(!novo){
        printf("SEM MEMORIA!\n");
        exit(1);
    }
   	novo->dado = valor;
   	 novo->prox = l;
	return novo;
    }
}

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Inserir, para mim, deve ser somente a inserção de No para Lista, e mais nada.

Assim:

 

 

Tipo de Dados Abstrato No

/* minha estrutura no */
typedef struct Note $node; /* definir alias para estrutura */
struct Note { int     informacao;
              $node * proximo; };

 

Função Novo no

/*  Alocar um novo no */
$node * node( int informacao )
{
    $node * novo= malloc(sizeof ($node));
    
    if( nov != NULL ){ * novo= ($node){ informacao, NULL }; }
    return novo;
}

 

Função Adicionar a lista no.

/* adicionar um no a lista */
bool lista_adicione( $node * p$node, $node ** lista )
{
    if ( (p$node == NULL) || (lista == NULL) ){ return false; } else
    if (* lista  == NULL){ * lista= p$node; } else { p$node->proximo= (* lista); 
                                                  * lista= p$node; }
    return true;
}

 

main

int main( void )
{
    /*  Declaro alguns ...  */
    $node * lista= NULL; /* < lista vazia com NULL */
    
    lista_adicione( node(1), &lista );
    lista_adicione( node(2), &lista );
    lista_adicione( node(3), &lista );
    lista_adicione( node(4), &lista );
    
    /* Simples rotina de impressão para teste */
    volatile $node * i= lista;
    while ( i != NULL ){ printf(" %d\n", i->informacao);
        i= i->proximo; }
        
    return EXIT_SUCCESS;
}

Alguma pergunta?

 

***

 

Já com relação ao seu código "o consertei": @AnsiC/CProgramming

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@AnsiC  A struct que inicia o codigo e obrigatoria no exercicio bem como o retirar elemento.

 

Em relação ao seu codigo, achei muita mais difícil. Nao sei se pelos nome que voce usou. e sobre o adicionar a lista, no caso seu já vem pronto. Eu queria que o usuario escrevesse seu numero. O que concertou no meu codigo?

 

Realmente nao entendi sua funcao adicionar, e ele ainda é do tipo bool. Não sei o que é isso.

 

Nao sei o que é isso de volatile.

 

Porque?Porque?

adicionado 12 minutos depois

 

 

@Igor Vargas Realmente sua função inserir está muito mais fácil, até de entender. Aí no caso a variável valor iria passar para a lista e função a valor que foi digitado no main. Pois quero que o usuário digite o valor, e não já esteja pré-definido. 

 

Mas e o resto da função, tudo certo ou tem algum erro? 

 

Sobre a dica de desenhar, acho que vou segui-lá pois realmente não estou entendendo esse tanto de função para ler somente uma variável.

adicionado 16 minutos depois

 

///////////////////////////////////////////////////////////////////////////////////////////////

Uma coisa que realmente não entendo é isso de na hora de fazer o novo apontar para o proximo elemento da lista seguir o seguinte modelo:

novo->prox = l   ;

 

Para mim parece que o "novo" está recebendo tudo o que tem no 'l' , e dessa forma parece que o "novo->info" perde o valor que eu coloquei.

 

Não é intuitivo entender essa matéria.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Josesousa Esquece! Logo eu que defendo tando a importância de documentar um código fui programar-lo sem um pingo de documentação.

 

> <' Deixa queto.

  • Confuso 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
2 horas atrás, Josesousa disse:

Uma coisa que realmente não entendo é isso de na hora de fazer o novo apontar para o proximo elemento da lista seguir o seguinte modelo:

novo->prox = l   ;

@Josesousa

"novo" = novo nó

"prox" = ponteiro que guarda a memória do prox valor inserido.

"l" =cabeça da lista.

 

"l" é a lista, mas como ela vai estar vazia ele vai receber NULL ou seja o ponteiro  novo->prox= l  vai apontar pro vazio que no momento é "l" pois não tem nada dentro ainda . No próximo valor inserido que vai ser o seu novo "NOVO" teu "NOVO->prox = l" recebe o resto da lista ou seja  "l" vai ter o nó anterior e o teu "NOVO->prox" vai apontar pra ele.

 

EX: 1->2->NULL quero adicionar o numero 3. passo o valor "novo->dado = 3", "l =1->2->NULL", "novo->prox=l" quando for adicionado meu novo "novo->prox "  vai apontar pro numero "1"  então 3->1->2->NULL.

 

A a inserção de valores é sempre no inicio então se já tiver um nó na lista o próximo valor vai ser inserido atrás dele.

 

Espero ter ajudado de alguma forma se ficou muito confuso desenhar é a melhor forma e praticar bastante.

 

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Igor Vargas  Acho que estou entendendo. 

Entao a lista Lista serve apenas para criar outras struct...? Pois em seguida a usei para criar a "l" e a "novo" e as auxiliares.

Minha maior duvida era com isso de apontar para o proximo. Vou tentar praticar mais. E desenhar como sugerido.

 

Valeu, amigo...

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Josesousa

6 horas atrás, Josesousa disse:

Entao a lista Lista serve apenas para criar outras struct...?

 isso é mais questão de se você escolhe ou não usar o typedef. Porque se não usar tem que escrever struct lista e o nome da variável.

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Igor Vargas Uai, estava estudando por meio de vídeos no youtube e alguns site e livro, pensei que era "obrigatório". 

(Na verdade pensei que não faria diferença)

 

Pois no caso eu escrevi struct lista e usei Lista como nome da variavel, só que com a inicial maiúscula. Parte obrigatoria do exercicio.

 

Valeu, Igor,

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro 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 publicações 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

×