aula 254

Como criar uma lista C a partir de duas listas A e B?

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;
}

Deixe um comentário

dezoito − dezessete =

Wagner Gaspar

Capixaba de São Gabriel da Palha, Espírito Santo. Bacharel em Ciência da Computação pela Universidade Federal do Amazonas e mestre em informática pela Universidade Federal do Espírito Santo.