Impressão de Listas com e sem cabeça.

Impressão de Listas com e sem cabeça.

por Renan Fichberg -
Número de respostas: 7

Fiz o código. Por sinal, fiz todos. Inversão no inicio, final, meio, busca& remocão...mas tem uma coisa que está me incomodando profundamente. Discuti com alguns colegas e todos tinham uma resposta, mas nenhuma certeza [assim como eu]. Indo ao ponto:

 

I) Fazendo o código de listas com cabeça, na hora que faço a impressão usando o que está na página do IME [link abaixo], a "célula lixo", a cabeça, não aparece na impressão. Até aí tudo bem, eu imagino que ela não era para aparecer mesmo, e sim as celulas que vêm na seqüência [procede?]

II) Nas listas sem cabeça, porém, é que a coisa ficou estranha. A minha celula inicial, o  tal do "ini", esse cara ele aparece na impressão seguindo a risca o que está na página do IME. Eu resolvi tentar tirar esse cara da imressão pq achei que ele fosse um erro, e quando fiz...percebi que tornava o código de impressão idêntico ao código de impressão para listas com cabeça.

tl;dr - Na impressão de listas sem cabeça, em oposição ao de listas com cabeça, é certo aparecer um "lixo" ?

 

 

Link: http://www.ime.usp.br/~pf/algoritmos/aulas/lista.html

Em resposta à Renan Fichberg

Re: Impressão de Listas com e sem cabeça.

por Claynon Souza -

I) Está certo assim mesmo. A cabeça é uma referência que serve pra facilitar as operações com a lista e não pra armazenar um pedaço (célula) da lista. Por isso ela não aparece.

II) Talvez esteja havendo uma confusão de conceitos aqui. Escrevi um exemplo bem simples pra exemplificar o que está acontecendo.

#include <stdio.h>
struct cel {
  int conteudo;
  struct cel *prox;
};
typedef struct cel celula;
void imprima(celula *ini);
int main() {
  celula *ini, a, b, c;
  ini = &a;
  a.prox = &b;
  a.conteudo = 1;
  b.prox = &c;
  b.conteudo = 2;
  c.prox = NULL;
  c.conteudo = 3;
  imprima(ini);
  return 0;
}
void imprima(celula *ini) {
  celula *p;
  for (p = ini; p != NULL; p = p->prox)
    printf("%d\n", p->conteudo);
}

O ini é um ponteiro que aponta pra celula a, ou seja, o ini não é uma célula mas sim um endereço que aponta para uma célula (no caso a celula a). a.prox é um ponteiro que aponta para celula b. O mesmo acontece para a célula c.

A função imprima imprime o conteúdo das células (e não dos ponteiros). Imprime o conteúdo de a, de b e de c.

A diferença dessa lista (sem cabeça) pra uma lista com cabeça é que ini apontaria para um célula (a célula cabeça) cujo conteúdo não seria relevante e cabeca.prox apontaria para a célula a.

Em resposta à Claynon Souza

Re: Impressão de Listas com e sem cabeça.

por Renan Fichberg -

Então nos dois casos nenhuma 'impressão' deve aparecer o "lixo"?

Eu entendi a sua explicação, mas ainda estou estranhando bastante, para falar a verdade [mais pelo que está no site, e não pela sua explicação]. Vou deixar aqui os meus trechos de código que fazem a impressão com o 'lixo'.

 

Celula *criaListaSemCabeca(Celula *ini)
{
    ini = NULL;
    return ini;
}

 

void imprimeSemCabeca(Celula *ini)
{
    Celula *p;
    p = ini;
    printf("Endereco\tNumero\tString\tEnd.Prox\n");
    while (p != NULL)
    {
        printf("%p    %d    %s    %p\n", p, p->numero, p->string, p->prox);
        p = p->prox;
    }
}

 

 

Creio que não fiz errada isso, foi baseado na página do IME mesmo, só que eu criei funções específicas para criar e para a impressão.

 

Segue junto uma imagem com a saída depois de 3 inserções no inicio de uma lista encadeada sem cabeça [usando os códigos acima]. O "lixo" está apontado nos retângulos branco.

Anexo Saida.JPG
Em resposta à Renan Fichberg

Re: Impressão de Listas com e sem cabeça.

por Henrique Morimitsu -

Oi Renan,

Você pode colocar também o código de insercão? Veja que, para o caso de insercão no início de lista sem cabecas, deve haver um tratamento especial.

Em resposta à Henrique Morimitsu

Re: Impressão de Listas com e sem cabeça.

por Renan Fichberg -

Sim, claro.

 

Segue abaixo o código da inserção.

 

 

Celula *insereInicio(Celula *ini)
{
    int numeroInsercao; char *stringInsercao;
    Celula *aInserir, *p;

    stringInsercao = malloc(sizeof(char));
    aInserir = malloc(sizeof(Celula));
    printf("Numero a inserir:\n");
    scanf("%d", &numeroInsercao);
    printf("String a inserir:\n");
    scanf("%s", stringInsercao);
    aInserir->numero = numeroInsercao;
    aInserir->string = stringInsercao;

    p = ini->prox;
    ini->prox = aInserir;
    aInserir->prox = p;


    return ini;

}

Em resposta à Renan Fichberg

Re: Impressão de Listas com e sem cabeça.

por Victor Sanches Portella -

Esse código de inserção eu suponho que é para uma lista com cabeça,  então ta certinho.

Quanto a impressão, quando é sem cabeça, nao deve existir, como você diz, "lixo". Se você considerar o primeiro como lixo, você literalmente transforma essa lista com cabeça, e é claro que o código ficaria igual.

Mas quando a lista é sem cabeça, o primeiro termo é importante sim (essa é a definição de lista sem cabeça), e nao deve ser considerado lixo.

Não sei se consegui me expressar bem, mas espero que de para entender.

Em resposta à Renan Fichberg

Re: Impressão de Listas com e sem cabeça.

por Rodrigo F. Almeida -
Apenas um palpite, ok?

Essa linha aqui faz alocação suficiente para apenas um caractere:
stringInsercao = malloc(sizeof(char));

Nas digitações via scanf são gravados três caracteres de cada vez:.Na primeira vez:
1 para 'A'
1 para 'B'
1 para o terminador de strings ('\0' - barra invertida seguida de zero)

O mesmo para 'CD' e 'EF'.
Veja se trocando para a linha abaixo alguma coisa muda:
stringInsercao = malloc(sizeof(char) * 3);


Em resposta à Rodrigo F. Almeida

Re: Impressão de Listas com e sem cabeça.

por Henrique Morimitsu -

Além do malloc para um char só. Como o Victor mencionou antes, essa insercão é para inserir em listas com cabeca. Mas pelo que entendi dos posts anteriores, você está usando listas sem cabeca. Assim, na primeira chamada a variável *ini é NULL e, portanto, não tem prox, nem nenhuma estrutura de Célula. Não entendi bem como ele não dá erro de segmentacão aqui.

E no caso de insercões no início de listas sem cabeca, o próprio ini deveria passar a apontar para a nova célula criada, pois caso contrário você estará sempre inserindo na segunda posicão da lista, não no início.