Copy list simply chained to C

0

Hello everyone, I need help copying a list that is simply chained backwards. For example, if the original list is 1- > 2- > 3- > null, it needs to be 3- > 2- > 1- > null.

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

typedef int bool;
enum { false, true };

// elemento da lista
typedef struct estr {
    char letra;
    struct estr *prox;
} NO;

typedef struct {
    NO *inicio;
} LISTA;

void inicializarLista(LISTA *l) {
    l->inicio = NULL;
}

void criarLista(LISTA *l, char plvr[]) {
    NO *ult = NULL;
    for (int i = 0; i < strlen(plvr); i++) {
        NO *novo = (NO *) malloc(sizeof(NO));
        novo->letra = plvr[i];
        novo->prox = NULL;
        if (ult) {
            ult->prox = novo;
        } else {
            l->inicio = novo;
        }
        ult = novo;
    }
}

void imprimirLista(LISTA l) {
    NO *p = l.inicio;
    while(p) {
        printf("%c", p->letra);
        p = p->prox;
    }
}

LISTA* clonarLista(LISTA* l){
  NO novo = NULL;
  LISTA* resp = novo; //inicializar lista resp
  while(l){
    novo = (NO *) malloc(sizeof(NO));
    novo->letra = l->letra;
    novo->prox = NULL;
    l = l->prox;
  }
  return resp;
}

void inverter(LISTA* resp){
  NO* ant = NULL;
  NO* atual = //inicio da lista resp
  NO* seg; //seguinte
  while (atual){
    seg = atual->prox;  
    atual->prox = ant;   
    ant = atual;
    atual = atual->prox;
    }
    //inicio da lista resp = ant;
}

int main() {
    LISTA l;
    LISTA resp;
    inicializarLista(&l);
    inicializarLista(resp);
    char palavra[] = "caio";
    criarLista(&l, palavra);
    inverter(&resp)
    imprimirLista(resp);

    return 0;
}
    
asked by anonymous 02.09.2017 / 21:49

1 answer

2

The inverter function has a variable with the value open:

NO* atual = //inicio da lista resp

This generates a syntax error because the value and ; are missing. Just as logic does not do the intended. Instead you can rebuild the list by adding the nodes to the head which will do the inversion:

void inverter(LISTA* resp){

    NO* atual = resp->inicio;

    //redefinir a lista para começar vazia, sendo que o ponteiro atual ainda 
    //aponta para os seus elementos
    resp->inicio = NULL; 

    while (atual){ //enquanto tiver nós
        NO* corrente = atual; //guardar o nó corrente
        atual = atual->prox; //avançar o nó atual


        corrente->prox = resp->inicio; //fazer o prox do corrente ser o 1 da lista invertida
        resp->inicio = corrente; //o inicio passa a ser este ultimo nó
    }
}

The list print function should receive a pointer, equal to what the other functions receive, and then:

void imprimirLista(LISTA *l) { //agora com *l
    NO *p = l->inicio; //agora com ->
    while(p) {
        printf("%c", p->letra);
        p = p->prox;
    }
}

What causes main to become different. And the main that it had, invested a list that had no value assigned, the list resp , just as it lacked a & . It should look like this:

int main() {
    LISTA l;
    LISTA resp;
    inicializarLista(&l);
    inicializarLista(&resp); //agora com &
    char palavra[] = "caio";
    criarLista(&l, palavra);
    inverter(&l); //inverter o l que é o que tem a palavra
    imprimirLista(&l); //imprimir o que foi invertido

    return 0;
}

Edit :

In order to invert a clone from the original list it is necessary first to hit the cloning function that has some things wrong:

  • NO novo = NULL; is an invalid initialization unless it is a pointer
  • novo->letra = l->letra; l is of type LISTA therefore only has the inicio field and not the letra field and the same happens in while(l) which is not useful for navigation
  • Missing prox construction of new nodes, so that the list has all the elements connected

Correcting everything we get:

LISTA* clonarLista(LISTA* l){
  LISTA* resp = malloc(sizeof(LISTA)); 

  NO *corrente = l->inicio;
  NO *anterior = NULL; //utilizar um nó anterior para ligar os vários elementos

  while(corrente){ //agora com corrente em vez de l
    NO *novo = (NO *) malloc(sizeof(NO));
    novo->letra = corrente->letra;
    novo->prox = NULL;

    if (anterior == NULL){ //se é o primeiro fica no inicio da nova lista
        resp->inicio = novo;
    }
    else { //se não é o primeiro liga o anterior a este pelo prox
        anterior->prox = corrente;
    }

    anterior = novo;
    corrente = corrente->prox;
  }

  return resp;
}

In order for main to invert a copy instead of the original we can change to:

int main() {
    LISTA l;
    inicializarLista(&l);
    char palavra[] = "caio";
    criarLista(&l, palavra);

    LISTA* resp = clonarLista(&l); //obter o clonado
    inverter(resp); //inverter o clonado
    imprimirLista(resp); //imprimir o clonado -> oaic

    return 0;
}
    
02.09.2017 / 23:45