Ir ao conteúdo
  • Cadastre-se
KIBUM

C lista encadeada em c

Recommended Posts

void imprime (lista* li){

    int i = 0, j = 0, count = 0;
    lista* p;
    do{
    for (p = li; p != NULL; p = p->prox){
    p->valor = p->valor-1;
    printf("N[%d] = %d\n", i, p->valor);
    count++;
    if(p->valor == 0)
    p->valor = count;
    count = 0;

    i++;
    j++;
    }
    }while(j < 10);
}

Boa noite a todos, estou tentando criar um programa em C utilizando lista encadeada, esse programa imprime uma variável T-1 até o 0 e reinicia a contagem.

Ex: Entrada - 3. Saída - 0,1,2,0,1,2,0,1,2,0,1,2...0,1,2

 

Não entendo onde está o erro, a saída do meu programa fica assim: 2,1,0,0,0,0,0....0,0,0

 

E se alguém puder me dar dicas de como inverter a saída eu agradeço.

 

Obrigado, abraços! :3  

Compartilhar este post


Link para o post
Compartilhar em outros sites

Única maneira que consigo pensar é que cada nó na lista seja menor que o nó posterior com exatamente 1 de diferença . Supondo que 1) prox->valor = 1, e 2)p->prox->valor = 2, 3) p->prox->prox->valo = 3 quando subtrair '1' de 1), 2) e 3) casos nesta sequência teríamos a saída : 0, 1, 2, 0 ... Entretanto, a variável  count [que renova a sequência a cada ocorrência de valor == 0] está zerada em cada interação, pelo motivo que declaração if (p->valor == 0) não a está protegendo:

void imprime (lista *li) {

    int i = 0, j = 0, count = 0;
    lista *p;
    do {
        for (p = li; p != NULL; p = p->prox) {
            p->valor = p->valor - 1;
            printf ("N[%d] = %d\n", i, p->valor);
            count++;
            if (p->valor == 0) {
                p->valor = count;
                count = 0;
                }

            i++;
            j++;
            }
        }
    while (j < 10);
    }

Se colocarmos dessa maneira resolve? 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Mauro, muito obrigado por responder :thumbsup:, consegui resolver o problema criando duas variáveis auxiliares, o código ficou assim:

void imprime (lista* li, int x){

    int i = 0, j = 0, count = 0, aux, aux2;
    lista* p;
    aux = x - x;
    aux2 = x;
    do{
    	for (p = li; p != NULL; p = p->prox){
    	p->valor = aux;
    	printf("N[%d] = %d\n", i, p->valor);
    	aux++;
    	if(p->valor == aux2-1)
    	aux = 0;
    	p->valor = aux;

    	i++;
    	j++;
    	}
    }while(j < 1000);
}

Tenho outra dúvida, como faço pra fechar um tópico aqui? :D

 

Abraços! ^_^

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá @KIBUM.

 

Tem alguns pontos que precisam ser verificados...

 

 

Vou tentar me basear pelo que observei do já postado, vamos lá:

 

1 hora atrás, KIBUM disse:

Olá Mauro, muito obrigado por responder :thumbsup:, consegui resolver o problema criando duas variáveis auxiliares, o código ficou assim:

Vamos tentar dar uma reanalisada.

 

Vide "enunciado":

Em 07/03/2018 às 22:25, KIBUM disse:

Boa noite a todos, estou tentando criar um programa em C utilizando lista encadeada, esse programa imprime uma variável T-1 até o 0 e reinicia a contagem.

Ex: Entrada - 3. Saída - 0,1,2,0,1,2,0,1,2,0,1,2...0,1,2

Certo, mas qual foi a utilidade da lista encadeada no seu algoritmo? Você até simplesmente pegando emprestado para imprimir na tela... seria o mesmo que fazer assim:

printf("N[%d] = %d\n", i, aux);

 

Eu tenho a impressão que não seria isso... Você está apenas fazendo uma lista "andar", e durante o processo está pegando emprestado a variável para imprimir o valor... ou seja, a estrutura está subutilizada... não tem porque existir uma lista nessa interpretação... basicamente a lista só está servindo como o ponto de parada, ou seja, "continua imprimindo até que chegue o fim da lista"... não está usando a lista em si como base do problema.

 

Teoricamente você precisará utilizar de alguma forma mais objetiva o recurso do encadeamento.. por exemplo, criando uma lista com T posições e após reimprimir a mesma lista X vezes (a quantidade de vezes que o ciclo se repete também não me ficou claro). Algo como fazendo um encadeamento circular, onde a última posição aponta para primeira...

 

Seria algo do tipo:

p->valor = T-1; //pega o valor inicial
p->prox->valor = p->valor -1; //o valor do próximo é igual o valor atual menos um
p = p->prox; //vai para o próximo
p->prox->valor = p->valor -1;
p = p->prox;
p->prox->valor = p->valor -1;
p = p->prox;
p->prox->valor = p->valor -1;

Nisso, até chegar no 0. Aí faz o último aponta para o primeiro e após imprime em sequência até o limite desejado, ou seja, a lista só precisa se criada uma vez.

 

obs.: veja que você também poderia usar o aux. O importante que após ter a sequência, passaria imprimir direto, pois a lista já tem os dados necessários.

 

 

RESUMINDO:

Pelo que eu entendi, a lista encadeada seria suma "lista encadeada circular" OU, como você fez, reinicia a lista. Apenas que não precisaria ficar reatualizando;

 

Por favor, poste o enunciado completo para analisarmos melhor;

Poste também o código completo para melhor análise.

 

 

ADENDO:

Pequeno detalhe:

1 hora atrás, KIBUM disse:

aux = x - x;

"algo"-"aglo" = 0. Vide propriedade da anulação. Logo, mais fácil utilizar:

aux = 0;

 

No aguardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Simon, desculpa a demora, estou muito ocupado com a faculdade. Essa é a questão 1177 do URI e esse é o código completo:

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


struct Lista{

    int valor;
    struct lista *prox;


};

typedef struct Lista lista;


lista* inicializa(void){

return NULL;
}


lista* insere(lista* li, int i){

    lista* novo = (lista*) malloc(sizeof(lista));
    novo->valor = i;
    novo->prox = li;

return novo;
}


void imprime (lista* li, int x){

    int i = 0, j = 0, count = 0, aux, aux2;
    lista* p;
    aux = x - x;
    aux2 = x;
    do{
    for (p = li; p != NULL; p = p->prox){
    p->valor = aux;
    printf("N[%d] = %d\n", i, p->valor);
    aux++;
    if(p->valor == aux2-1)
    aux = 0;
    p->valor = aux;

    i++;
    j++;
    }
    }while(j < 1000);
}


void libera (lista* li){

    lista* p = li;
    while (p != NULL) {
    lista* t = p->prox;

free(p);
p = t;
    }
}


int main()
{

    int t;
    lista* lista1;
    lista1 = inicializa();
    scanf("%d", &t);
    lista1 = insere(lista1, t);
    imprime(lista1, t);
    libera(lista1);

return 0;
}

Pelo que entendi, você está me sugerindo adicionar um novo elemento na struct que seria um ponteiro para o nó anterior, certo? Então, ficaria mais ou menos assim:

struct Lista{

    int valor;
    struct lista *prox;
	struct lista *ante;

};


lista* insere(lista* li, int i){

    lista* novo = (lista*) malloc(sizeof(lista));
    novo->valor = i;
    novo->prox = li;
	novo->ante = NULL;	

return novo;
}

void imprime (lista* li, int x){

    int i = 0, j = 0, aux;
    lista* p;
    //aux = 0;
  	p->valor = 0;
    do{
    for (p = li; p != NULL; p = p->prox){
    printf("N[%d] = %d\n", i, p->valor); 
    p->prox->valor = p->valor+1;
    p->ante->valor = p->valor;
    if(p->ante->valor == p->valor-1)
    p->valor = 0;

    i++;
    j++;
    }
    }while(j < 1000);
}
                     

Acho que não, né? :huh:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá.

 

1) ESTRUTURA DA LISTA

14 horas atrás, KIBUM disse:

Pelo que entendi, você está me sugerindo adicionar um novo elemento na struct que seria um ponteiro para o nó anterior, certo? Então, ficaria mais ou menos assim:

Não... isso é outra coisa... ai você está fazendo uma "lista duplamente encadeada", ou seja, "cadeia" para frente e também para traz... Algo assim:

 

A lista duplamente encadeada ficou assim:

 NoAnterior <- Nó -> NoPosterior

 

Mas correta seria assim mesmo:

No -> NoPosterior

 

Já o que eu sugerir foi:

Em 10/03/2018 às 21:35, Simon Viegas disse:

[...] um encadeamento circular, onde a última posição aponta para primeira...

 

E complemento:

Em 10/03/2018 às 21:35, Simon Viegas disse:

Nisso, até chegar no 0. Aí faz o último apontar para o primeiro e após imprime em sequência até o limite desejado, ou seja, a lista só precisa se criada uma vez.

 

 

 

2) ESTRUTURA DO ALGORITMO

2.1) INDENTAÇÂO DO CÓDIGO

O código SEMPRE deve está indentado... Segue exemplo:

Spoiler

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

struct Lista {
    int valor;
    //struct lista *prox;
    //struct lista *ante;
    struct Lista *prox;
    struct Lista *ante;
};

Lista* inicializa(void) {
    return NULL;
}

//lista* insere(lista* li, int i){
Lista* insere(Lista* li, int i) {
    //lista* novo = (lista*) malloc(sizeof(lista));
    Lista* novo = (Lista*)malloc(sizeof(Lista));
    novo->valor = i;
    novo->prox  = li;
    novo->ante  = NULL;	
    return novo;
}

//void imprime (lista* li, int x){
void imprime (Lista* li, int x) {
    int i = 0, j = 0, aux;
    //lista* p;
    Lista* p;
    //aux = 0;
    p->valor = 0;
    do {
        for (p = li; p != NULL; p = p->prox) {
            printf("N[%d] = %d\n", i, p->valor); 
            p->prox->valor = p->valor+1;
            p->ante->valor = p->valor;
            if (p->ante->valor == p->valor-1)
                p->valor = 0;
            i++;
            j++;
        }
    // } while(j < 1000);
    } while(j < 10);
}

void libera (Lista* li) {
    Lista* p = li;
    while (p != NULL) {
        Lista* t = p->prox;
        free(p);
        p = t;
    }
}

int main() {
    int t;
    Lista* lista1;
    lista1 = inicializa();
    scanf("%d", &t);
    lista1 = insere(lista1, t);
    imprime(lista1, t);
    libera(lista1);
    return 0;
}

Veja a diferença...

 

 

2.2) GERANDO SEQUÊNCIA

14 horas atrás, KIBUM disse:

            p->prox->valor = p->valor+1;
            p->ante->valor = p->valor;
            if (p->ante->valor == p->valor-1)
                p->valor = 0;

Veja, aqui você está tentando fazer a mesma coisa... ou seja, para está manipulando a lista para imprimir... não seria assim... Você apenas terá uma lista com T posições, onde a última posição aponta para primeira.

 

Após, só faz "navegar" na lista e ir imprimindo... imprime o primeiro e vai pro próximo, imprime vai para o próximo, imprime vai para o próximo etc...

 

 

 

3) ENUNCIADO DO PROBLEMA

14 horas atrás, KIBUM disse:

[...] Essa é a questão 1177 do URI e esse é o código completo:

 

Dando uma pesquisa, encontrei isso:

uri1177.jpg

 

Em nenhum momento fala em

Em 07/03/2018 às 22:25, KIBUM disse:

um programa em C utilizando lista encadeada

 

Ou seja, está partindo da premissa errada...

 

A base para resolver um problema está primeiramente em entender o problema... por isso que pedi:

Em 10/03/2018 às 21:35, Simon Viegas disse:

[...] o enunciado completo para analisarmos melhor;

 

Não vai adiantar fazer um lista encadeada circular toda certinha, sendo que o problema pede apenas um "simples vetor".

 

RESUMINDO:

Qual o enunciado correto? sem ter a definição do problema, fica mais difícil encontrar uma solução para ela.

 

Se for o da imagem, seria mais ou menos como @Mauro Britivaldo sugeriu, apenas que será com VETORES e deve ser separado. Primeiro gerar o vetor, depois imprimi ele. Pega um for de 0 a 1000-1, e vai inserir de 0 a T-1, sendo que ao chegar o T-1, zera o contador.

 

Se for com lista encadeada mesmo, podemos revisar...

 

 

Qualquer dúvidas é só postar.

 

No aguardo.

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

×