Ir ao conteúdo
  • Cadastre-se

C++ inverter lista duplamente encadeada


nicholas22

Posts recomendados

Ajuda nessa questão aqui pf

Escreva uma função que, dada uma lista duplamente encadeada l de alunos, inverta os elementos de l em uma outra lista duplamente encadeada de saída. Portanto, a lista de entrada não pode ser alterada. O protótipo da função de inversão é o seguinte:
 

TLDE* inverte (TLDE* l);

A questão dá apenas isso: 

typedef struct lista{
	int matricula;
	float a1,a2,a3;
	struct lista *prox;
	struct lista *ant;
	
}TLDE;

E qual a diferença de uma lista encadeada para uma duplamente encadeada?

Link para o comentário
Compartilhar em outros sites

59 minutos atrás, nicholas22 disse:

E qual a diferença de uma lista encadeada para uma duplamente encadeada

 

Acho que a menos de prova em contrário toda lista é duplamente encadeada. É o caso em que cada nó aponta para o próximo e para o anterior. Em geral na literatura se vê uma tal  forward list em que os nós só tem ponteiro para o próximo. Claro que podia também ser para o anterior. Assim economiza um ponteiro para cada nó, mas lógico que se precisar seguir no sentido contrário tem que percorrera lista toda de novo.

 

Esse exercício é trivial: basta percorrer a lista e criar a outra ao contrário

Link para o comentário
Compartilhar em outros sites

5 minutos atrás, nicholas22 disse:

o que eu faço com a matricula e as notas?

 

Os mesmos dados vão estar nas duas listas, as matrículas e notas. Vai criar OUTRA lista, igual. Mais uma vez, não é uma lista de referência que aponta para os dados da outra. É uma lista completa, novinha.

 

Escreva uma função que percorre uma lista do fim para o início e mostra os dados. Use as funções que você já tem.

Depois mude essa função para ao invés de mostrar inserir em outra lista.
 

Use nomes mais indicativos do que está havendo... 
 

 

 

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

@arfneto eu tentei primeiro criar uma lista mas acho que fiz besteira pois não sei como fazer para mostrar as notas já que na função insere o x só aceita int. E eu acho que fica melhor se colocar as notas como vetor só que eu to um pouco confuso com isso

#include <stdlib.h>
#include<stdio.h>
typedef struct lista {
   int matricula ;
   float vetor[3];
   struct lista* prox; 
   struct lista *ant;
}TLista;


TLista* inicializa() {
   return NULL;
}


TLista* insere(TLista* l, int x){
 float a;
   TLista* novo = (TLista*) malloc(sizeof(TLista));
  
   novo->matricula = x;
	novo->vetor[3]=a;
   novo->prox = l;
   return novo;
}


TLista* retira(TLista* l, int x){
    TLista *ant=NULL, *p=l, *p2=l;
    int a;
    
    while((p != NULL) && (p->matricula!= x)){
        ant = p;
        p = p->prox;
    }
    
    if(!p){
        return l;
    }

  
    if(!ant){
        l = l->prox;
    }else{
        ant->prox = p->prox;
    }
    free(p);

    return l;
    
     while((p2 != NULL) && (p2->vetor[3]!= a)){
        ant = p2;
        p2 = p2->prox;
    }
    
    if(!p2){
        return l;
    }

  
    if(!ant){
        l = l->prox;
    }else{
        ant->prox = p2->prox;
    }
    free(p2);

    return l;
}

int vazia(TLista *l){
     if(l == NULL)
	return 1;
     else
	return 0;
}

void libera(TLista *l){
    TLista *p = l;
    TLista *aux;
    while(p != NULL){
        aux = p;
        p = p->prox;
        free(aux);
    }
}

void imprime(TLista* l){
   TLista* p;
   for (p = l; p != NULL; p = p->prox){
       printf("matricula = %d\n", p->matricula);
   }
    TLista* p2;
   for (p2 = l; p2 != NULL; p2 = p2->prox){
       printf("notas = %d\n", p2->vetor[3]);
   }
}
int main(){
	TLista *l;
	l = inicializa();
	l = insere(l, 10565644);
	l = insere(l, 208646465);
	l = insere(l, 30445465);
	l = insere(l, 404468546);

	imprime(l);

	
}

 

Link para o comentário
Compartilhar em outros sites

56 minutos atrás, nicholas22 disse:

eu tentei primeiro criar uma lista mas acho que fiz besteira pois não sei como fazer para mostrar as notas já que na função insere o x só aceita int. E eu acho que fica melhor se colocar as notas como vetor só que eu to um pouco confuso com isso

 

Entendi. Mas está usando as funções que recebeu no outro exercício? 

Acho que deve tentar só adaptar aquilo num primeiro momento. 

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

@arfneto Na verdade é um exercício de a, b e c cujo o enunciado é:

Um determinado professor deseja criar um programa para armazenar as notas dos alunos de suas turmas. Basicamente, cada aluno possui matrícula e três notas como exemplificado na tabela abaixo.
Matricula               A1            A2          A3
20170123456       10,0         10,0       10,0
20160223456         9,0           8,0         7,0
Considere uma lista duplamente encadeada que armazena os seguintes dados de alunos de uma disciplina:
-  Matrícula: número inteiro
- A1: Número de ponto flutuante
- A2: Número de ponto flutuante

- A3: Número de ponto flutuante

 

a)Escreva uma função RECURSIVA que, dadas duas listas de alunos duplamente encadeadas l1 e l2, verifique se as mesmas são iguais. As listas l1 e l2 devem permanecer inalteradas. Esta função retorna 1 se as listas são iguais e 0, caso
contrário. O protótipo desta função é o seguinte: int igual_recursivo (TLDE *l1, TLDE *l2)

Essa eu já fiz e a resposta é: 

#include<stdlib.h>
#include<stdio.h>
  
typedef struct lista{
  int matricula;
  float a1,a2,a3;
  struct lista *prox;
  struct lista *ant;
}TLDE;

int igual_recursivo (TLDE *l1, TLDE *l2){
if(l1==NULL &&l2==NULL){
return 1;
}
  if(l1==NULL || l2==NULL){
return 0;
}
  if(l1!=NULL && l2!=NULL){
if((l1->a1==l2->a1)&&(l1->a2==l2->a2)&&(l1->a3==l2->a3)&&(l1->matricula==l2->matricula)){
return  igual_recursivo (l1->prox,l2->prox);
}
    else{
return 0;
    }
  }
  else{
return 0;
  }
}
  
  


b)Escreva uma função que, dada uma lista duplamente encadeada l de alunos, inverta os elementos de l em uma outra lista duplamente encadeada de saída. Portanto, a lista de entrada não pode ser alterada. O protótipo da função de inversão é o seguinte: TLDE* inverte (TLDE* l);

 

 

Link para o comentário
Compartilhar em outros sites

 

Eu estava dizendo sobre você manter o código que tinha nesse tópico, ou melhorar um pouco, e partir daí escrever os próximos exercícios, inclusive esses aqui... E não escrever tudo de novo.

 

Veja uma definição mais "arrumadinha" de lista

struct no
{
    void*      item;
    struct no* proxima;
    struct no* anterior;
};  // no
typedef struct no Node;

struct a_propria_lista
{
    char*     nome;
    unsigned  quantos;
    unsigned  maximo;
    Node*     inicio;
    Node*     fim;
};
typedef struct a_propria_lista Lista;

 

E veja que item é só um ponteiro. Então tanto faz se vai usar um int ou uma struct com matricula e notas ou uma playlist ou uma lista de produtos de uma nota fiscal ou o inevitável exercício dos livros na biblioteca.

 

Nenhuma função da lista trata os dados e isso faz toda a diferença. Programe algo assim a partir daquele código que tinha

 

E a lista tem uns atributos, por exemplo o tamanho atual e capacidade...

 

Veja insere() por exemplo:

Lista*      inserir_na_ordem(void*, Lista*, int(*)(void*, void*));
Lista*      inserir_no_inicio(void*, Lista*);
Lista*      inserir_no_final(void*, Lista*);

Entende a diferença? Pode inserir qualquer coisa. Só tem o nome lá. Epode inserir no fim ou no começo. Ou na ordem. E mesmo assim não precisa saber o que são os dados porque quem vai usar a função insere_na_ordem() vai fornecer a função que compara...

 

Esse é um conceito muito importante. Muitos algoritmos funcionam assim.

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

@arfneto Eu consegui fazer usando ponteiro de ponteiro porém meu professor falou que só ia aceitar com um ponteiro. Tem como mudar pra ficar com um só nas funções insere e inverte?

#include <iostream>
using namespace std;
struct TLDE {
   int dados;
   struct TLDE *ant, *prox;
};
  
TLDE* novaLista(int val){
   TLDE* temp = new TLDE;
   temp->dados = val;
   temp->ant = temp->prox = NULL;
   return temp;
}
void exibir(TLDE* l){
   while (l->prox != NULL) {
      cout << l->dados << " ---- ";
      l = l->prox;
      }
   cout << l->dados << endl;
}
  
TLDE *insere(TLDE** l, int elem){
	
   TLDE* temp = novaLista(elem);
   temp->prox = *l;
   (*l)->ant = temp;
   (*l) = temp;
}
  
TLDE *inverte(TLDE** l){

   TLDE* esquerda = *l, * direita = *l;
  
   while (direita->prox != NULL)
   direita = direita->prox;
  
   while (esquerda != direita && esquerda->ant != direita) {
  
      swap(esquerda->dados, direita->dados);
  
      esquerda = esquerda->prox;
  
      direita = direita->ant;
   }
}
int main()
{
   TLDE* no_principal = novaLista(201698546);
   insere(&no_principal, 6.9);
   insere(&no_principal, 9.6);
   insere(&no_principal, 2);
   cout << "Lista original: " << endl;
   exibir(no_principal);
   cout << "Lista inversa:  " << endl;
   inverte(&no_principal);
   exibir(no_principal);
  
   return 0;
}

 

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

1 hora atrás, nicholas22 disse:

@arfneto Eu consegui fazer usando ponteiro de ponteiro porém meu professor falou que só ia aceitar com um ponteiro. Tem como mudar pra ficar com um só nas funções insere e inverte?


#include <iostream>
using namespace std;
struct TLDE {
   int dados;
   struct TLDE *ant, *prox;
};
  
TLDE* novaLista(int val){
   TLDE* temp = new TLDE;
   temp->dados = val;
   temp->ant = temp->prox = NULL;
   return temp;
}
void exibir(TLDE* l){
   while (l->prox != NULL) {
      cout << l->dados << " ---- ";
      l = l->prox;
      }
   cout << l->dados << endl;
}
  
TLDE *insere(TLDE** l, int elem){
	
   TLDE* temp = novaLista(elem);
   temp->prox = *l;
   (*l)->ant = temp;
   (*l) = temp;
}
  
TLDE *inverte(TLDE** l){

   TLDE* esquerda = *l, * direita = *l;
  
   while (direita->prox != NULL)
   direita = direita->prox;
  
   while (esquerda != direita && esquerda->ant != direita) {
  
      swap(esquerda->dados, direita->dados);
  
      esquerda = esquerda->prox;
  
      direita = direita->ant;
   }
}
int main()
{
   TLDE* no_principal = novaLista(201698546);
   insere(&no_principal, 6.9);
   insere(&no_principal, 9.6);
   insere(&no_principal, 2);
   cout << "Lista original: " << endl;
   exibir(no_principal);
   cout << "Lista inversa:  " << endl;
   inverte(&no_principal);
   exibir(no_principal);
  
   return 0;
}

 

Alguém me da uma luz pf preciso entregar amanhã 

@herbertbahia Moço, você saberia me explicar?

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

 

1 hora atrás, nicholas22 disse:

Eu consegui fazer usando ponteiro de ponteiro porém meu professor falou que só ia aceitar com um ponteiro. Tem como mudar pra ficar com um só nas funções insere e inverte?

 

Não entendo o que tem a ver a ponto de aceitar ou não uma solução. Não sei o que tentam ensinar com essa ideia. Foi ele que escreveu aquele código do outro exercício?

 

A questão de usar Lista** ou Lista**** ou Lista* é ou deveria ser irrelevante. O que importa na lista --- e em todas essa estruturas --- é o grau de abstração. Para um estudante, claro.

 

Aqui está sua versão de insere()

TLDE *insere(TLDE** l, int elem)
{
   TLDE* temp = novaLista(elem);
   temp->prox = *l;
   (*l)->ant = temp;
   (*l) = temp;
}

 

Aqui está a que havia postado antes

void insere(TFila* f, int elem)
{
	TLista* novo = (TLista*)malloc(sizeof(TLista));
	novo->info = elem;
	novo->prox = NULL;
	if (f->fim)
	{
		f->fim->prox = novo;
	}
	f->fim = novo;
	if (!f->ini)
	{
		f->ini = novo;
	}
}

Não escreva uma única linha de código sem razão, sem saber porque está lá. E escreva sempre seus programas em torno dos dados, não da interface, de menus, que funções...

 

Qual a diferença entre as duas?
 

Como chegou a essa? Vou você que escreveu a outra?

 

Entendeu a estrutura que te mostrei? Podia comentar algo talvez? Preciso saber se entende o que te explico

 

De volta á sua função:

TLDE *insere(TLDE** l, int elem)
{
   TLDE* temp = novaLista(elem);
   temp->prox = *l;
   (*l)->ant = temp;
   (*l) = temp;
}

Sua função retorna um ponteiro. Ao menos foi declarada assim. Seu compilador não reclamou de não estar retornando nada? Não achou que seria importante? Se achou que era importante porque não retornou algo? Se não achou porque não declarou como void como no código original?

 

Você está inserindo no início. O código original inseria no final. Se você pensasse no que retornar teria talvez entendido que podia retornar o novo endereço de início. ;) E se retornasse o novo endereço de início não precisaria passar TLDE** :D

 

Pense nisso: apenas retorne temp e atribua o valor de volta... Só isso.

    lista = insere(lista, valor);

Mais um palpite: inverta isso: você insere um valor na lista. É mais legível e intuitivo declarar

Lista*    insere(int elem, Lista* L); // insere 'elem' na lista 'L'

 

Mais: está declarando uma função insere()  que retorna um endereço de TLDE então formalmente, como é uma declaração, devia escrever

 

TLDE*        insere(int, TLDE*); // insere() retorna TLDE*

 

o fato de *insere ser do tipo TLDE é uma consequência.

 

 

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

@arfneto Sim, foi o professor que escreveu o código anterior. Essa função que eu fiz antes eu tinha visto um exemplo na internet e tentei fazer no mesmo estilo só que não deu certo.Eu entendo o que o senhor fala porém  mas quando eu vou fazer parece que dá um nó na minha mente e eu me enrolo kkk. Eu fiz um outro código usando o inserir no fim como você mostrou e parece que deu meio certo pois ele não dá erro no compilador mas quando coloco um elemento do tipo float  no main só aparece como se fosse inteiro. 

#include<stdio.h>
 #include<stdlib.h>
struct TLDE
{
  int dados;
  struct TLDE* prox;
};
 
 TLDE* inserir_no_fim( TLDE*p , float elem)
{
   TLDE *raiz = p;
  TLDE* pTemp = (struct TLDE*)malloc(sizeof(struct TLDE*));
  pTemp->dados = elem;
  pTemp->prox = NULL;
 
  if(!raiz)
    return pTemp;       
  else
  {
   TLDE* pPar = p;
    while(p->prox)
    {
      p=p->prox;
    }
    p->prox =pTemp;
    return raiz;
  }
}
 
void exibir(TLDE* p)
{
  if(!p)
    printf("Lista vazia");
  else
  { 
    do
    {
      printf(" %d", p->dados);
      p=p->prox;
    }
    while(p);
  }
}
 


 TLDE * inverte( TLDE *l)
{
   	TLDE*r =NULL; // r é o ponteiro para a lista invertida
 	TLDE*s =NULL; //s é o ponteiro para o ultimo elemento da lista invertida
     
  while(l)
  {
    s=r;
    r=l;
    l=l->prox;
    r->prox=s;
  }
  return r;
}
 
int main()
{
TLDE *inicializa =NULL;
  
  inicializa = inserir_no_fim(inicializa,1056985466);
  inicializa = inserir_no_fim(inicializa,9);
  inicializa = inserir_no_fim(inicializa,6.5);
  inicializa = inserir_no_fim(inicializa,4.5);
  
  printf("\nLista normal:    ");
  exibir(inicializa);
  
  inicializa = inverte(inicializa);
 
  printf("\nLista invertida:  ");
  exibir(inicializa);
}

 

Link para o comentário
Compartilhar em outros sites

17 minutos atrás, nicholas22 disse:

e tentei fazer no mesmo estilo só que não deu certo

 

Em 4 linhas não dá pra ter muito estilo

 

17 minutos atrás, nicholas22 disse:

o que o senhor fala

 

senhor foi mal 😔

 

18 minutos atrás, nicholas22 disse:

eu vou fazer parece que dá um nó na minha mente e eu me enrolo kkk. Eu fiz um outro código usando o inserir no fim como você mostrou e parece que deu meio certo pois ele não dá erro no compilador mas quando coloco um elemento do tipo float  no main só aparece como se fosse inteiro

 

Isso foi engraçado... Foi você que escreveu esse código que insere no fim. E seu professor escreveu o que insere no começo.

 

o que eu te mostrei foi uma declaração diferente de Lista. Mais "séria" digamos. Mas não postei nenhuma implementação e você não disse se entendeu a diferença

 

21 minutos atrás, nicholas22 disse:

não dá erro no compilador mas quando coloco um elemento do tipo float  no main só aparece como se fosse inteiro

 

Compilar nada ou pouco quer dizer. Mas você não pode ir mudando os tipos sem pensar. Não mexa em nada enquanto a lista não estiver certinha. O que houve com sua função?

 TLDE* inserir_no_fim( TLDE*p , float elem)
{
   TLDE *raiz = p;
  TLDE* pTemp = (struct TLDE*)malloc(sizeof(struct TLDE*));
  pTemp->dados = elem;
  pTemp->prox = NULL;
 
  if(!raiz)
    return pTemp;       
  else
  {
   TLDE* pPar = p;
    while(p->prox)
    {
      p=p->prox;
    }
    p->prox =pTemp;
    return raiz;
  }
}

Ela cresceu pra caramba, bem depois de eu dizer que não só precisava retornar o nó. 

 

E aquela parte em que eu escrevi para não mudar uma linha sequer sem um motivo

 

Sua função agora tem dois return????? Sério? Pense bem:
 

Citação

se você insere no início o valor de retorno SEMPRE vai ser a nova raiz


ou o que é uma lista final? Qual o significado de raiz e inserir no início?

 

Esta complicando demais...

 

Eis como se implementa uma lista,  ao menos um estudante:

  • primeiro a função mostra(Lista*) que mostra na tela um a um os caras da lista
  • depois a função cria() que cria a lista
  • depois a função insere() que... insere

Você não sai escrevendo mil funções. E você nem tem a mostra() que era pra ser a primeira. 

 

Isto está quase certo:

TLDE *insere(TLDE** l, int elem)
{
   TLDE* temp = novaLista(elem);
   temp->prox = *l;
   (*l)->ant = temp;
   (*l) = temp;
}

Nem li a que escreveu depois. Muito complicado. Com DOIS return para inserir no início não pode estar bom.

 

Pense assim: quer inserir no INÍCIO e a lista é

struct TLDE
{
  int dados;
  struct TLDE* prox;
};

typedef struct TLDE Lista;

Não sei de quem foi a ideia de usar esse nome folclórico, mas para mim Lista é Lista. Mais importante: TLDE é uma struct então TODAS as declarações teriam que ter a palavra struct porque TLDE não é um tipo...

 

Eu te mostrei uma maneira bem melhor do que essa que seu professor usou e você tentou usar...

 

 

 

Link para o comentário
Compartilhar em outros sites

@arfneto po cara valeu mesmo por tentar me ajudar nessa questão, eu vou desistir dela, tenho que entregar essa questão e mais 3 exercícios que não sei fazer até até as 6 da manhã, além de que eu  realmente não sei mais o que fazer pra essa questão dar certo.Ter aula com ead e dizer quais são as dúvidas de maneira escrita é muito complicado pra mim eu literalmente aprendi muito pouco dessa matéria nesse semestre e meu professor quer as coisas sempre do jeito dele o que acaba dificultado muito pois se eu modifico uma coisinha se quer ele já tira quase todo o ponto. Mas enfim , obrigado de verdade e desculpa por fazer você perder seu tempo.

Link para o comentário
Compartilhar em outros sites

4 minutos atrás, nicholas22 disse:

@arfneto po cara valeu mesmo por tentar me ajudar nessa questão, eu vou desistir dela, tenho que entregar essa questão e mais 3 exercícios que não sei fazer até até as 6 da manhã, além de que eu  realmente não sei mais o que fazer pra essa questão dar certo.Ter aula com ead e dizer quais são as dúvidas de maneira escrita é muito complicado pra mim eu literalmente aprendi muito pouco dessa matéria nesse semestre e meu professor quer as coisas sempre do jeito dele o que acaba dificultado muito pois se eu modifico uma coisinha se quer ele já tira quase todo o ponto. Mas enfim , obrigado de verdade e desculpa por fazer você perder seu tempo.

 

Antes de tudo inclua isso no seu programa

struct stTLDE
{
    int             dados;
    struct TLDE*    prox;
};
typedef struct stTLDE TLDE;

porque do jeito que declarou está errado

 

insere() estava ok do jeito que estava antes como escreveu com 5 linhas. faltava so retornar o valor e tirar O **

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

@arfneto Eu declarei da forma que o professor declarou todas as listas que ele fez... Ainda não entendi porque essa última lista que eu fiz está errada pois ela roda e mostra certinho a lista normal e a inversa. A única coisa que dá errado é que ela só mostra número inteiro. Vou tentar declarar como você falou.

Link para o comentário
Compartilhar em outros sites

veja esse exemplo, que digitei em cima do seu programa agora, na ordem em que te falei há pouco:

 

Mostra

Lista nao alocada
0
1 0
2 1 0
3 2 1 0
4 3 2 1 0

Para

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

struct stTLDE
{
    int             dados;
    struct stTLDE*    ant;
    struct stTLDE*    prox;
};
typedef struct stTLDE TLDE;

TLDE*   insere_no_inicio(int,TLDE*);
int     mostra(TLDE*);

int main()
{
    TLDE* lista = NULL;
    mostra(lista);
    for (int i = 0; i < 5; i += 1)
    {
        lista = insere_no_inicio(i, lista);
        mostra(lista);
    };
    return 0;
};

TLDE* insere_no_inicio(int E, TLDE* L)
{
    TLDE* novo = (TLDE*)malloc(sizeof(TLDE));
    novo->dados = E;
    novo->prox = L;
    if(L!=NULL) L->ant = novo;
    return novo;
};

int mostra(TLDE* L)
{
    if (L == NULL)
    {
        printf("Lista nao alocada\n");
        return -1;
    };
    while (L != NULL)
    {
        printf("%d ", L->dados);
        L = L->prox;
    };  // while()
    printf("\n");
    return 0;
};
//fim

 

adicionado 2 minutos depois
1 minuto atrás, nicholas22 disse:

Eu declarei da forma que o professor declarou todas as listas que ele fez... Ainda não entendi porque essa última lista que eu fiz está errada pois ela roda e mostra certinho a lista normal e a inversa. A única coisa que dá errado é que ela só mostra número inteiro. Vou tentar declarar como você falou

 

O modo como ele fez não está nada bom.

 

Nesse que escreveu acho que faltou o typedef 

 

adicionado 22 minutos depois

inserir no fim não é muito diferente:

 

Só é um pouco maior porque tem o caso de a lista estar vazia e porque não declarou a lista como eu mostrei, mantendo alguns parâmetros como o tamanho, o limite e o endereço de início e de fim... Assim precisa varrer a lista toda para achar o fim...

TLDE* insere_no_final(int E, TLDE* L)
{
    TLDE* novo = (TLDE*)malloc(sizeof(TLDE));
    novo->dados = E;
    novo->prox = NULL; // sempre no fim
    if (L == NULL)
    {
        novo->ant = NULL;
        return novo;
    };
    TLDE* raiz = L;
    // vai ate o fim ja que nao tem o ponteiro
    while (L->prox != NULL) L = L->prox;
    L->prox = novo;
    novo->ant = L;
    return raiz;
};

 

Link para o comentário
Compartilhar em outros sites

  • 4 meses depois...

Sugiro não postar código em espaço duplo. Só fica comprido e mais difícil de ler

 

void exibirAoContrario (TLista U)
{
	TLista aux;  
   	//verificando se a lista está vazia
   	if (!U)
   	{
      	printf ("Lista vazia!\n");
   	}
   	else
   	{
      	printf ("Lista: ");      	
      	aux = U;      
      	while (aux)
      	{
         	printf ("%d ", aux->valor);
         	aux = aux->ant;
      	}           
      	printf ("\n");
   	}
}


Imagino que tenha um programa todo onde testou isso. Poste o programa. E teste

 

  • Evite chamar variáveis de "aux"...
  • Se a lista está vazia simplesmente retorne. Não há sentido em deslocar todo o código da função para a direita por um caso particular que deve acontecer em uma fração modesta das execuções. Só dificultaa leitura e manutenção do código.

E entenda que se aux está posicionada para o inicio da lista adivinha o que vai ter em aux->ant? NADA. Zero, NULL. Não vai listar nadinha exceto o primeiro valor...

 

 

O tópico aqui era gerar uma lista inversa e e não simplesmente listar ao contrário

Link para o comentário
Compartilhar em outros sites

7 minutos atrás, arfneto disse:

Sugiro não postar código em espaço duplo. Só fica comprido e mais difícil de ler

 


void exibirAoContrario (TLista U)
{
	TLista aux;  
   	//verificando se a lista está vazia
   	if (!U)
   	{
      	printf ("Lista vazia!\n");
   	}
   	else
   	{
      	printf ("Lista: ");      	
      	aux = U;      
      	while (aux)
      	{
         	printf ("%d ", aux->valor);
         	aux = aux->ant;
      	}           
      	printf ("\n");
   	}
}


Imagino que tenha um programa todo onde testou isso. Poste o programa. E teste

 

  • Evite chamar variáveis de "aux"...
  • Se a lista está vazia simplesmente retorne. Não há sentido em deslocar todo o código da função para a direita por um caso particular que deve acontecer em uma fração modesta das execuções. Só dificultaa leitura e manutenção do código.

E entenda que se aux está posicionada para o inicio da lista adivinha o que vai ter em aux->ant? NADA. Zero, NULL. Não vai listar nadinha exceto o primeiro valor...

 

 

O tópico aqui era gerar uma lista inversa e e não simplesmente listar ao contrário

Imagino que tenha um programa todo onde testou isso (lógico). Poste o programa(não precisa). E teste (aff)

Evite chamar variáveis de "aux"...(vou continuar chamando; irrelevante).

 

Se a lista está vazia simplesmente retorne. Não há sentido em deslocar todo o código da função para a direita por um caso particular que deve acontecer em uma fração modesta das execuções. Só dificultaa leitura e manutenção do código. (você não entendeu a função)

 

E entenda que se aux está posicionada para o inicio da lista adivinha o que vai ter em aux->ant? NADA. Zero, NULL. Não vai listar nadinha exceto o primeiro valor...(extamante, assim o laço termina; não entendeu o código outra vez).

 

O tópico aqui era gerar uma lista inversa e e não simplesmente listar ao contrário (isso sim é relevante; no programa, a lista "U" é a inversa da lista original "L".

 

 

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...
Em 16/11/2020 às 23:06, arfneto disse:

 

ah! Pena que o programa não veio falar por ele :D 

Tem razão pequeno gafanhoto! Viu? nem sempre discordo de você.
Segue a função que inclui os itens na lista e da onde surge o "U".

 

typedef struct No
{
   int valor;
   struct No *prox, *ant;
} TNo;

typedef TNo* TLista;

void inserir (TLista *L, TLista *U, int num)
{
    TLista aux = (TLista) malloc (sizeof(TNo));
   
       {
           aux->valor = num;
          aux->prox = *L;
          aux->ant = NULL;
      
          (*L)?(*L)->ant = aux:*U = aux;
      
          *L = aux;
    }
}

void exibir (TLista L)
{
	if(L)
	{
		printf ("%d ", L->valor);
		exibir (L->prox);		
	}
}

void exibirAoContrario (TLista U)
{
	if(U)
	{
		printf ("%d ", U->valor);
		exibirAoContrario (U->ant);
	}
}

 

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