Listas Encadeadas

De Wiki Cursos IFPR Foz
Ir para navegaçãoIr para pesquisar

Listas Encadeadas

Uma lista encadeada ou lista ligada é uma estrutura de dados linear e dinâmica. Cada elemento de uma lista encadeada é chamado de célula ou , e possui dois campos, um para guardar a informação e o outro para guardar o endereço do nó seguinte. O último nó da lista aponta para nulo[1].

O esquema a seguir representa uma lista ligada/encadeada:

As listas encadeadas são dinâmicas, ou seja, tem a vantagem terem seu tamanho variável. Diferente das Pilhas ou Filas implementadas a partir de vetores, as quais tem um tamanho máximo fixo, limitado pela declaração do tamanho do vetor[1].

Implementação de listas encadeadas em linguagem C

Na linguagem C, para implementar uma lista encadeada, formada por nós, utilizamos para a declaração do nó uma struct com dois campos, um para a informação e um ponteiro que aponta para o próximo nó.

Declaração de um nó de uma lista encadeada

typedef struct {
       int    conteudo;
       struct node *prox;
} node;

Observações:

  1. É conveniente tratar os nós de uma lista encadeada como um novo tipo de dados, usando typedef, e atribuir um nome a esse novo tipo (ver Estruturas em C).
  2. A declaração da estrutura usa recursividade, onde um dos campos da estrutura é do tipo da estrutura sendo declarada.
Exemplo
Declaração de uma lista encadeada em um programa main[2].
void main(void){
   node c;   /*A variável c é do tipo nó*/
   node *p; /*A variável p do tipo apontador para node*/ 
   c.conteudo = 1;
   p = &c; 
   printf("%d\n", c.conteudo);
   printf("%d\n", p->conteudo); 
}

Neste exemplo, ambas as chamadas à função printf() iriam imprimir o número 1.

Inicialização de uma lista

Uma lista encadeada é toda composta por elementos alocados dinamicamente em memória.

Para criar uma lista é preciso uma base ou raiz, que será sempre a mesma para uma lista. Esta raiz é uma variável ponteiro que aponta para uma lista ou que aponta para um primeiro nó vazio [3].

Normalmente, para listas, é usada a nó vazio (conhecido como lista sem cabeça), já para as pilhas e filas dinâmicas é usado o apontador para as respectivas bases (lista com cabeça).

A função seguinte pode ser usada no main após ser declarada a variável raiz que será do tipo apontador para lista. Esta cria um nó vazia e faz a raiz a apontar para a mesma:

node *cria_lista(){
    node *novo, *aux;
    novo = (node *) malloc(sizeof(node)); /*Aloca memória do tamanho de uma célula*/
    if(novo == NULL) exit(0);           /*Se não alocar hpuver espaço na memória deve sair*/
    novo->prox = NULL;  /*Célula vazia aponta para NULL*/ 
    aux = novo; /*Para retornar o aux com o endereço da célula vazia*/ 
    return (aux); /*Retorna o aux*/
}

Incluindo um elemento no início da lista

A função recebe como parâmetro um ponteiro para a lista e o conteúdo que se deseja incluir:

node * inserirNoInicio(node * raiz, int numero){
    node *novo, *aux;
    aux = raiz;
    novo = (node *) malloc(sizeof(node)); //Aloca memória para nova célula
    if(novo == NULL) exit(0);           //Se não consegue alocar espaço sai   
    novo->conteudo = numero;
    novo->prox = aux->prox;
    aux->prox = novo;
    return(aux);
}

Exemplos de listas encadeadas implementadas em C

Exemplo de lista completa implementada em C[4]

Outras referências
[5] [6] [7]

Exercícios

  1. Implementar uma pilha utilizando listas encadeadas.
  2. Implementar uma fila utilizando listas encadeadas.

Referências


--Evandro.cantu (discussão) 12h40min de 22 de outubro de 2014 (BRST)