aula 247

Estrutura de Dados Lista Simplesmente Encadeada. SEGUNDA VERSÃO

Dando continuidade ao nosso Curso de Programação C e ao estudo da Estrutura de Dados Lista Simplesmente Encadeada, vamos aprender nesta aula como criar a estrutura Lista, não sendo mais necessário utilizar ponteiro para ponteiro.

Em programação é importante que você entenda que existem diversas formas de fazer a mesma coisa, de resolver o mesmo problema, algumas mais simples e outras nem tanto. Algumas mais eficientes e outras nem tanto. Assim, quando encontrar um código que você não consegue entender, procure outro mais simples, procure entender o algoritmo (os passos lógicos para resolver um problema), isso certamente lhe ajudará.

Dito isso, talvez você, assim como muitos, não goste de ponteiros para ponteiros. Será que existe outra forma de implementar uma lista encadeada? Preferencialmente, será que existe uma forma de implementar uma lista encadeada sem fazer uso de ponteiro para ponteiro?

Sim, existe, e aqui apresentamos uma solução.

Utilizamos ponteiro para ponteiro porque, ao inserir o primeiro nó, precisamos alterar o valor de uma variável declarada na função main. E se essa variável ficasse dentro de outra estrutura? Isso resolveria o problema, certo?

Basicamente é isso que faremos. Vamos criar outra estrutura chamada lista. Esta estrutura terá em seu interior dois campos, um ponteiro para o primeiro nó da lista e uma variável inteira para armazenar o tamanho da lista, assim:

/*
    Estrutura lista
*/
typedef struct{
    No *inicio;
    int tam;
}Lista;

Como no início nossa lista está vazia, precisamos dizer isso. Podemos fazer isso por meio de um procedimento para inicializar os campos de nossa lista, o início da lista é nulo e seu tamanho é zero, assim:

/*
    Procedimento para inicializar a lista
*/
void criar_lista(Lista *lista){
    lista->inicio = NULL;
    lista->tam = 0;
}

Feito isso, precisamos agora alterar os procedimentos que desenvolvemos nas aulas anteriores, pois agora passaremos como parâmetro não mais um ponteiro para ponteiro para um nó, mas apenas um ponteiro para nossa lista, pois o ponteiro para o primeiro nó da lista agora está dentro da estrutura lista.

Código de exemplo completo em C para a estrutura Lista encadeada com a estrutura Lista

/*
            Código escrito por Wagner Gaspar
            Agosto de 2021

            Aula 247: Lista Simplesmente Encadeada: Segunda versão com a estrutura Lista
/*

typedef struct no{
    int valor;
    struct no *proximo;
}No;

typedef struct{
    No *inicio;
    int tam;
}Lista;

void criar_lista(Lista *lista){
    lista->inicio = NULL;
    lista->tam = 0;
}

// procedimento para inserir no início
void inserir_no_inicio(Lista *lista, int num){
    No *novo = malloc(sizeof(No));

    if(novo){
        novo->valor = num;
        novo->proximo = lista->inicio;
        lista->inicio = novo;
        lista->tam++;
    }
    else
        printf("Erro ao alocar memoria!\n");
}

// procedimento para inserir no fim
void inserir_no_fim(Lista *lista, int num){
    No *aux, *novo = malloc(sizeof(No));

    if(novo){
        novo->valor = num;
        novo->proximo = NULL;

        // é o primeiro?
        if(lista->inicio == NULL)
            lista->inicio = novo;
        else{
            aux = lista->inicio;
            while(aux->proximo)
                aux = aux->proximo;
            aux->proximo = novo;
        }
        lista->tam++;
    }
    else
        printf("Erro ao alocar memoria!\n");
}

// procedimento para inserir no meio
void inserir_no_meio(Lista *lista, int num, int ant){
    No *aux, *novo = malloc(sizeof(No));

    if(novo){
        novo->valor = num;
        // é o primeiro?
        if(lista->inicio == NULL){
            novo->proximo = NULL;
            lista->inicio = novo;
        }
        else{
            aux = lista->inicio;
            while(aux->valor != ant && aux->proximo)
                aux = aux->proximo;
            novo->proximo = aux->proximo;
            aux->proximo = novo;
        }
        lista->tam++;
    }
    else
        printf("Erro ao alocar memoria!\n");
}

void imprimir(Lista lista){
    No *no = lista.inicio;
    printf("\n\tLista tam %d: ", lista.tam);
    while(no){
        printf("%d ", no->valor);
        no = no->proximo;
    }
    printf("\n\n");
}

int main(){

    int opcao, valor, anterior;
    //No *lista = NULL;
    Lista lista;

    criar_lista(&lista);

    do{
        printf("\n\t0 - Sair\n\t1 - InserirI\n\t2 - inserirF\n\t3 - InserirM\n\t4 - Imprimir\n");
        scanf("%d", &opcao);

        switch(opcao){
        case 1:
            printf("Digite um valor: ");
            scanf("%d", &valor);
            inserir_no_inicio(&lista, valor);
            break;
        case 2:
            printf("Digite um valor: ");
            scanf("%d", &valor);
            inserir_no_fim(&lista, valor);
            break;
        case 3:
            printf("Digite um valor e o valor de referencia: ");
            scanf("%d%d", &valor, &anterior);
            inserir_no_meio(&lista, valor, anterior);
            break;
        case 4:
            imprimir(lista);
            break;
        default:
            if(opcao != 0)
                printf("Opcao invalida!\n");
        }

    }while(opcao != 0);

    return 0;
}

Este post tem um comentário

  1. elvis

    Boa tarde
    o asterisco do final do comentario do cabeçalho tem que inverter …senão fica todo comentado..

Deixe um comentário

dezessete − doze =

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.