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; }
Boa tarde
o asterisco do final do comentario do cabeçalho tem que inverter …senão fica todo comentado..