Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Vinícius Alves

Copiar uma lista ligada (encadeada) para outra lista

Recommended Posts

Fala galera beleza? Estou com um problema para conseguir copiar uma lista (que o usuário insere os dados) para uma outra lista.
aqui esta o que eu ja fiz.

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

struct lista {
int info;
struct lista *prox;
};


struct lista addItem (struct lista *cabeca){
struct lista *atual,*novo;
atual = cabeca;
system("cls");
printf("Digite a informacao\n");
while (atual->prox != NULL) {
atual= atual->prox;
}
novo = (lista*) malloc (sizeof (lista));
scanf("%d",&atual->info);
novo->prox = NULL;
atual->prox= novo;
}


void imprime(struct lista *cabeca) {
system("cls");
struct lista *p;
printf("Elementos: \n");
for (p = cabeca; p->prox != NULL; p = p->prox) {
printf( " * %d\n",p->info);
}
}

struct lista *inicializa(){
return NULL;
}

struct lista copiar (struct lista *lista1,struct lista *lista2) {
system("cls");
struct lista *p,*q,*aux;
q = lista2;
for (p=lista1; p->prox != NULL; p=p->prox) {
q->info=p->info;
q=q->prox;
}

printf("Copia completa\n");
}

int main () {
int j;
struct lista *lista1;
lista1 = (lista*) malloc (sizeof (lista));
lista1->prox = inicializa();
struct lista *lista2;
lista2 = (lista*) malloc (sizeof (lista));
lista2->prox= inicializa();
do {
printf("Escolha uma das funcoes\n");
printf("Digite [1] para Inserir items\nDigite [2] para imprimir a lista\nDigite [3] para copiar a lista\nDigite [0] para encerrar o programa\n");
scanf("%d",&j);
if (j==1){
printf("Escolha se voce quer inserir na lista 1 ou na lista 2\n");
scanf("%d",&j);
if (j==1){
addItem(lista1);
}
else if (j==2){
addItem(lista2);
}
} else if (j==2) {
printf("Escolha se voce quer imprimir a lista 1 ou a lista 2\n");
scanf("%d",&j);
if (j==1){
imprime(lista1);
}
else if (j==2){
imprime(lista2);
}
} else if (j==3){
copiar(lista1,lista2);
}
} while (j!=0);
}



O meu objetivo é transferir os elementos da lista 1 para a lista 2 e assim ter duas listas idênticas na impressão.
Pode-se ver que a função copiar não esta funcionando ( o programa trava). Obrigado pela ajuda desde já =D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Alguns erros que encontrei.

 

1) Na alocação de memória, não é especificada a expressão completo do tipo.

lista1 = (struct lista*) malloc( sizeof(struct lista) );

2) Nas funções "copiar()" e "addItem()" , não possui retorno para o tipo dessas funções.

struct lista copiar (...)
struct lista addItem (...)

3) Na função "addItem()", precisa receber ponteiro para ponteiro, para que seja possível alterar o valor inicial da lista, sem perder a relação inicial.

void addItem (struct lista **cabeca)

Modificar dentro da função "addItem()" para:

atual = *cabeca;

Alterar as chamadas na função "main()":

                if ( j == 1 )
                    addItem(&lista1);
                else
                    if ( j == 2 )
                        addItem(&lista2);

4) Função "copiar()" faz a cópia do valor contido na lista 1 para a lista 2, sem conferir a quantidade de elementos existentes em cada um. Isso permitindo gravar valor excedentes na lista 2, caso a lista 1 possua mais elementos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiramente obrigado ScreenBlack, bem fiz as modificações que você falou e também passei as funções struct lista copiar e struct lista addItem para void copiar e void addItem, pois n tenho nenhuma intenção de retornar um valor nessas funções. Só que agora o programa n permite inserir dados ( ele trava). Anteriormente o programa inseria e imprimia os items corretamente( apenas não copiava). Mas o meu problema principal ainda é a copia, e mesmo se a lista1 tiver mais elementos q a lista2 eu queria que todos os elementos fossem copiados, até os excedentes.

 

Código atual:

 

#include <stdio.h>

#include <stdlib.h>

struct lista {
int info;
struct lista *prox;
};


void addItem (struct lista **cabeca){
struct lista *atual,*novo;
atual = *cabeca;
system("cls");
printf("Digite a informacao\n");
while (atual->prox != NULL) {
atual= atual->prox;
}
novo = (lista*) malloc (sizeof (lista));
scanf("%d",&atual->info);
novo->prox = NULL;
atual->prox= novo;
}


void imprime(struct lista **cabeca) {
system("cls");
struct lista *p;
printf("Elementos: \n");
for (p = *cabeca; p->prox != NULL; p = p->prox) {
printf( " * %d\n",p->info);
}
}

struct lista *inicializa(){
return NULL;
}

void copiar (struct lista **lista1,struct lista **lista2) {
system("cls");
struct lista *p,*q,*aux;
q = *lista2;
for (p=*lista1; p->prox != NULL; p=p->prox) {
q->info=p->info;
q=q->prox;
}

printf("Copia completa\n");
}

int main () {
int j;
struct lista *lista1;
lista1 = (struct lista*) malloc( sizeof(struct lista) );
lista1= inicializa();
struct lista *lista2;
lista2 = (struct lista*) malloc (sizeof (struct lista));
lista2 = inicializa();
do {
printf("Escolha uma das funcoes\n");
printf("Digite [1] para Inserir items\nDigite [2] para imprimir a lista\nDigite [3] para copiar a lista\nDigite [0] para encerrar o programa\n");
scanf("%d",&j);
if (j==1){
printf("Escolha se voce quer inserir na lista 1 ou na lista 2\n");
scanf("%d",&j);
if (j==1){
addItem(&lista1);
}
else if (j==2){
addItem(&lista2);
}
} else if (j==2) {
printf("Escolha se voce quer imprimir a lista 1 ou a lista 2\n");
scanf("%d",&j);
if (j==1){
imprime(&lista1);
}
else if (j==2){
imprime(&lista2);
}
} else if (j==3){
copiar(&lista1,&lista2);
}
} while (j!=0); }
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

1) Você esqueceu de especificar o tipo completo no "malloc()" da função "addItem()".

novo = (struct lista*) malloc ( sizeof(struct lista) );

2) Você declarou o retorno das função para ponteiro void, que é diferente de apenas void.

void addItem (struct lista **cabeca)
void imprime(struct lista **cabeca)

3) O programa está fechando, porque na função "main()", está sendo alocada memória para o primeiro elemento da lista e em seguida setando a lista pra NULL, perdendo assim a referência para o primeiro elemento.

Além disso, a função "addItem()" não está fazendo a verificação se já existe o primeiro elemento válido na lista.

Aconselho deixar toda a parte de alocação de memória para inserção de novos elementos, na função "addItem()", apenas.

 

Trecho que mostra a alocação e depois setando pra NULL, que é o retorno da função "inicializa()":

 

    lista1 = (struct lista*) malloc( sizeof(struct lista) );
    lista1= inicializa();

Compartilhar este post


Link para o post
Compartilhar em outros sites

Em meu post anterior, no item 2, mostra a declaração sem ponteiro void.

No item 3, informa o porque seu programa está sendo fechado de maneira inesperada.

Compartilhar este post


Link para o post
Compartilhar em outros sites

A sim, me desculpe deu algum bug no meu navegador e não apareceu os últimos items. Fiz o que você falou e agora estou conseguindo inserir os items. Mas a função copiar ainda n funciona. Alguma ideia?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Aqui o código

 

 

#include <stdio.h>

#include <stdlib.h>

struct lista {
int info;
struct lista *prox;
};

struct lista **inicializa(){
return NULL;
}

void addItem (struct lista **lista1) {
struct lista *atual,*novo;
lista1 = (struct lista**) malloc( sizeof(struct lista) );
lista1= inicializa();
atual = *lista1;
system("cls");
printf("Digite a informacao\n");
while (atual->prox != NULL) {
atual= atual->prox;
}
novo = (struct lista*) malloc ( sizeof(struct lista) );
scanf("%d",&atual->info);
novo->prox = NULL;
atual->prox= novo;
}


void imprime(struct lista **cabeca) {
system("cls");
struct lista *p;
printf("Elementos: \n");
for (p = *cabeca; p->prox != NULL; p = p->prox) {
printf( " * %d\n",p->info);
}
}


void copiar (struct lista **lista1,struct lista **lista2) {
system("cls");
struct lista *p,*q,*aux;
q = *lista2;
for (p=*lista1; p->prox != NULL; p=p->prox) {
q->info=p->info;
q=q->prox;
}

printf("Copia completa\n");
}

int main () {
int j;
struct lista *lista1;
struct lista *lista2;
do {
printf("Escolha uma das funcoes\n");
printf("Digite [1] para Inserir items\nDigite [2] para imprimir a lista\nDigite [3] para copiar a lista\nDigite [0] para encerrar o programa\n");
scanf("%d",&j);
if (j==1){
printf("Escolha se voce quer inserir na lista 1 ou na lista 2\n");
scanf("%d",&j);
if (j==1){
addItem(&lista1);
}
else if (j==2){
addItem(&lista2);
}
} else if (j==2) {
printf("Escolha se voce quer imprimir a lista 1 ou a lista 2\n");
scanf("%d",&j);
if (j==1){
imprime(&lista1);
}
else if (j==2){
imprime(&lista2);
}
} else if (j==3){
copiar(&lista1,&lista2);
}
} while (j!=0);
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não função "addItem()", está sendo setado NULL para o ponteiro errado.

E, também, permanece o mesmo equívoco de definir NULL após uma alocação de memória, fazendo com que seja perdida a referência pra essa alocação.

 

        *lista = (struct LISTA *) malloc( sizeof(struct LISTA) );
        atual = *lista;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bem eu uso o Dev-C pois é o compilador que meu professor recomenda.

Eu consegui fazer a função copiar funcionar, mas apenas no meu programa antigo, ou seja sem usar ponteiro para ponteiro.

Eu não consegui achar em lugar nenhum uma função de copiar lista para outra lista sem usar recursividade. Por isso vou postar o meu programa aqui para que outros não tenham o mesmo problema, esse programa também remove elementos da lista e concatena as duas.

 

 

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


struct lista {
int info;
struct lista *prox;
};

struct lista addItem (struct lista **cabeca){
struct lista *atual,*novo;
atual = *cabeca;
system("cls");
printf("Digite a informacao\n");
while (atual->prox != NULL) {
atual= atual->prox;
}
novo = (lista*) malloc (sizeof (lista));
scanf("%d",&atual->info);
novo->prox = NULL;
atual->prox= novo;
}

void imprime(struct lista *cabeca) {
system("cls");
struct lista *p;
printf("Elementos: \n");
for (p = cabeca; p->prox != NULL; p = p->prox) {
printf( " * %d\n",p->info);
}
}

char verifica(struct lista *cabeca) {
//buscar um elemento na lista encadeada
int valor;
printf("Digite um valor a ser buscando");
scanf("%d",&valor);
char busca; //variavel para retorno
struct lista *aux; //ponteiro auxiliar
aux=cabeca; //ponteiro auxiliar proximo, recebe o inicio
while(aux!=NULL) //enquanto o proximo não for nulo
{
if((aux->info)==valor){ //se o proximo valor for = ao valor digitado então a busca é bem sucedida
busca = 'S';
return busca;
}
aux = aux -> prox; //próximo registro
}
busca = 'N';
return busca;
}



struct lista *inicializa(){
return NULL;
}

struct lista remover (struct lista *cabeca) {
system("cls");
int y;
printf("Digite a informacao a ser removida");
scanf("%d",&y);
lista *p, *q;
p = cabeca;
q = cabeca->prox;
while (q != NULL && q->info != y) {
p = q;
q = q->prox;
}
if (q != NULL) {
p->prox = q->prox;
free( q);
}
printf("Informacao Removida da lista\n");
}


struct lista *copiar (struct lista *L,struct lista *l2) {
struct lista *atual = L;
struct lista *novo;
while (atual->prox != NULL) {
l2->info = atual->info;
novo = (lista*) malloc (sizeof (lista));
novo->prox = NULL;
l2->prox = novo;
l2=l2->prox;
atual=atual->prox;
}
printf("Copia completa\n");
}

struct lista concatena (struct lista *lista1,struct lista *lista2) {
system("cls");
lista *p,*q,*aux;
aux = lista1; /* variável auxiliar para percorrer a lista */
do
{
p = lista1;
lista1 = lista1->prox;
}while(lista1->prox != NULL);
p->prox = lista2;
printf("Concatecacao completa\n");
}

int main () {
int j;
struct lista *lista1;
lista1 = (struct lista*) malloc( sizeof(struct lista) );
lista1->prox = inicializa();
struct lista *lista2;
lista2 = (lista*) malloc (sizeof (lista));
lista2->prox= inicializa();
struct lista *listacopy;
do {
printf("Escolha uma das funcoes\n");
printf("Digite [1] para Inserir items\nDigite [2] para imprimir a lista\nDigite [3] para verificar se o numero pertence a lista\nDigite [4] para remover um numero pertencente a lista\nDigite [5] para copiar a lista 1 para lista 2\nDigite [6] para concatenar as listas\nDigite [0] para encerrar o programa\n");
scanf("%d",&j);
if (j==1){
addItem(&lista1);
} else if (j==2) {
printf("Escolha se voce quer imprimir a lista 1 ou a lista 2\n");
scanf("%d",&j);
if (j==1){
imprime(lista1);
}
else if (j==2){
imprime(lista2);
}
} else if (j==3) {
printf("\n'S' significa que ha o valor na lista 'N' Nao ha o valor na lista\nA busca retornou: %c\n",verifica(lista1));
} else if (j==4) {
remover (lista1);
} else if (j==5){
copiar(lista1,lista2);
} else if (j==6) {
concatena(lista1,lista2); }
} while (j!=0);
}

 

 

Queria agradecer a todos, e se tiverem mais algum conselho podem comentar ae =P

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

 

Vocês saberiam me explicar porque no meu compilador (Dev-C) quando eu executo o programa do Screen aparece esses erros?

 

In function 'void addItem(LISTA**)':
29	47 [Error] invalid conversion from 'void*' to 'LISTA*' [-fpermissive]
37	52 [Error] invalid conversion from 'void*' to 'LISTA*' [-fpermissive]
In function 'void copiar(LISTA**, LISTA**)':
77	52  [Error] invalid conversion from 'void*' to 'LISTA*' [-fpermissive]
83	56   [Error] invalid conversion from 'void*' to 'LISTA*' [-fpermissive]

 

Creio que foi isso que impediu o aproveitamento das dicas dadas aqui.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se você tem o tamanho da lista e sua base então é só armazenar memória para a outra lista que receberá a cópia e copiar com memcpy.

Veja:

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

struct lista {
int info;
struct lista *prox;
};

int main()
{
	struct lista *base, *l1, *l2;
	struct lista *node;
	int lista_len = 0;
	int i;
	int len;

	for (i = 0; i < 5; i++, lista_len++)
	{
		node = (struct lista*) malloc(sizeof(struct lista));
		node->info = i+1;
		node->prox = NULL;

		if (lista_len == 0)
		{
			l1 = node;
			base = node;
		}
		else
		{
			base->prox = node;
			base = base->prox;
		}

	}

	//Copiando l1 para l2;
	len = sizeof(struct lista) * lista_len;
	l2 = (struct lista*) malloc(len);
	memcpy(l2, l1, len);

	//Verificando se copiou
	while (l2->prox != NULL)
	{
		node = l2;
		printf("Info: %d\n", node->info);
		l2 = l2->prox;
	}

	return 0;
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.