Dando continuidade ao nosso Curso de Programação C, vamos resolver um exercício para praticar tudo que estudos sobre a estrutura de dados lista encadeada? Como criar uma lista C a partir de duas listas A e B?
Perceba que já temos todo o conhecimento que precisamos para resolver este exercício. A ideia fundamental aqui é entender que precisamos percorrer a lista A copiando todos os elementos para a lista C e, em seguida, percorrer a lista B novamente copiando todos os elementos e inserindo na lista C.
Há diversas formas de fazer isso. Vou apresentar uma solução mas sinta-se livre para desenvolver mais de uma solução para este exercício. Esta é uma forma de exercitar seu raciocínio e sua criatividade, pensando diferentes soluções para o mesmo problema.
Pense comigo, se queremos copiar todos os elementos de uma lista para outra, podemos fazer um procedimento que recebe duas listas e copia os elementos de uma para outra, certo? Como já temos diversos procedimentos para inserção, podemos utilizar qualquer um deles.
É exatamente esta ideia que desenvolvemos no procedimento a seguir. Percorremos a lista l e, para cada nó, chamamos o procedimento inserir_no_inicio para inserir o valor daquele nó na lista c. Ao final a lista c possuirá todos os elementos presentes em l.
/* Procedimento que copia os valores da lista l para a lista c */ void copiar_lista(No **l, No **C){ No *aux = *l; while(aux){ inserir_no_inicio(C, aux->valor); aux = aux->proximo; } }
Como desejamos copiar para a lista C os elementos das listas A e B, basta chamar o procedimento acima duas vezes, com as listas A e C e em seguida com as listas B e C, assim:
/* Copiando as listas A e B para a lista C */ case 8: copiar_lista(&A, &C); copiar_lista(&B, &C); break;
Para testar o nosso código precisamos agora de três listas. Assim, a função main foi alterada para inserir nas listas A e B, para então podermos copiar seus elementos para a lista C.
Código completo em C para copiar duas listas para uma terceira lista
/* Código escrito por Wagner Gaspar Agosto de 2021 Aula 254: Lista Simplesmente Encadeada Gerar uma lista C com os elementos das Listas A e B /* typedef struct no{ int valor; struct no *proximo; }No; // procedimento para inserir no início void inserir_no_inicio(No **lista, int num){ No *novo = malloc(sizeof(No)); if(novo){ novo->valor = num; novo->proximo = *lista; *lista = novo; } else printf("Erro ao alocar memoria!\n"); } // procedimento para inserir no fim void inserir_no_fim(No **lista, int num){ No *aux, *novo = malloc(sizeof(No)); if(novo){ novo->valor = num; novo->proximo = NULL; // é o primeiro? if(*lista == NULL) *lista = novo; else{ aux = *lista; while(aux->proximo) aux = aux->proximo; aux->proximo = novo; } } else printf("Erro ao alocar memoria!\n"); } // procedimento para inserir no meio void inserir_no_meio(No **lista, int num, int ant){ No *aux, *novo = malloc(sizeof(No)); if(novo){ novo->valor = num; // é o primeiro? if(*lista == NULL){ novo->proximo = NULL; *lista = novo; } else{ aux = *lista; while(aux->valor != ant && aux->proximo) aux = aux->proximo; novo->proximo = aux->proximo; aux->proximo = novo; } } else printf("Erro ao alocar memoria!\n"); } void inserir_ordenado(No **lista, int num){ No *aux, *novo = malloc(sizeof(No)); if(novo){ novo->valor = num; // a lista está vazia? if(*lista == NULL){ novo->proximo = NULL; *lista = novo; } // é o menor? else if(novo->valor < (*lista)->valor){ novo->proximo = *lista; *lista = novo; } else{ aux = *lista; while(aux->proximo && novo->valor > aux->proximo->valor) aux = aux->proximo; novo->proximo = aux->proximo; aux->proximo = novo; } } else printf("Erro ao alocar memoria!\n"); } No* remover(No **lista, int num){ No *aux, *remover = NULL; if(*lista){ if((*lista)->valor == num){ remover = *lista; *lista = remover->proximo; } else{ aux = *lista; while(aux->proximo && aux->proximo->valor != num) aux = aux->proximo; if(aux->proximo){ remover = aux->proximo; aux->proximo = remover->proximo; } } } return remover; } No* buscar(No **lista, int num){ No *aux, *no = NULL; aux = *lista; while(aux && aux->valor != num) aux = aux->proximo; if(aux) no = aux; return no; } void copiar_lista(No **l, No **C){ No *aux = *l; while(aux){ inserir_no_inicio(C, aux->valor); aux = aux->proximo; } } void imprimir(No *no){ printf("\n\tLista: "); while(no){ printf("%d ", no->valor); no = no->proximo; } printf("\n\n"); } int main(){ int opcao, valor, anterior; No *removido, *A, *B, *C; A = NULL; B = NULL; C = NULL; do{ printf("\n\t0 - Sair\n\t1 - InserirI\n\t2 - inserirF\n\t3 - InserirM\n\t4 - InserirO\n\t5 - Remover\n\t6 - Imprimir\n\t7 - Buscar\n\t8 - Copiar\n"); scanf("%d", &opcao); switch(opcao){ case 1: // insere nas listas A e B printf("Digite um valor: "); scanf("%d", &valor); inserir_no_inicio(&A, valor); printf("Digite um valor: "); scanf("%d", &valor); inserir_no_inicio(&B, valor); break; case 2: // insere apenas na lista A printf("Digite um valor: "); scanf("%d", &valor); inserir_no_fim(&A, valor); break; case 3: // insere apenas na lista B printf("Digite um valor e o valor de referencia: "); scanf("%d%d", &valor, &anterior); inserir_no_meio(&B, valor, anterior); break; case 4: // insere apenas na lista A printf("Digite um valor: "); scanf("%d", &valor); inserir_ordenado(&A, valor); break; case 5: printf("Digite um valor a ser removido: "); scanf("%d", &valor); removido = remover(&C, valor); if(removido){ printf("Elemento a ser removido: %d\n", removido->valor); free(removido); } else printf("Elemento inexistente!\n"); break; case 6: printf("\nLista A:\n"); imprimir(A); printf("\nLista B:\n"); imprimir(B); printf("\nLista C:\n"); imprimir(C); break; case 7: printf("Digite um valor a ser buscado: "); scanf("%d", &valor); removido = buscar(&C, valor); if(removido) printf("Elemento encontrado: %d\n", removido->valor); else printf("Elemento nao encontrado!\n"); break; case 8: copiar_lista(&A, &C); copiar_lista(&B, &C); break; default: if(opcao != 0) printf("Opcao invalida!\n"); } }while(opcao != 0); return 0; }