UNIRP Resumo Listas Encadeadas Dinamicas
Click here to load reader
-
Upload
yuri-igor-marchioni -
Category
Documents
-
view
17 -
download
2
Transcript of UNIRP Resumo Listas Encadeadas Dinamicas
LISTAS ENCADEADAS DINÂMICAS
CONCEITOS BÁSICOS: é uma sequencia de nós, cuja relação de sucessão é estabelecida
por um ponteiro de endereço do próximo nó.
Diferentemente das listas sequenciais, em que a sucessão dos nós é estabelecida de
forma física ou contígua, nas listas encadeadas, a sucessão dos nós é estabelecida de forma
lógica.
Para cada novo elemento inserido na estrutura, alocamos um espaço de memória para
armazená-lo. Dessa forma, o espaço total de memória gasto pela estrutura é proporcional ao
número de elementos armazenado. No entanto, não podemos garantir que os elementos
armazenados na lista ocuparão um espaço de memória contíguo; portanto, não temos acesso
direto aos elementos da lista. Para percorrer todos os elementos, devemos explicitamente
guardar o seu encadeamento, o que é feito armazenando-se, junto com a informação de cada
elemento, um ponteiro para o próximo elemento da lista.
Sendo assim, em uma lista encadeada dinâmica, cada elemento é chamado nó. Cada nó é
composto por dois campos:
• info: contém a informação do nó;
• prox: contém o endereço do próximo nó.
Os nós da lista estão ligados entre si pelo campo prox e mostram o encadeamento (a
ligação de um nó a nó). O campo prox é chamado ponteiro para o próximo nó.
Lista encadeada dinâmica = é acessada a partir de um ponteiro p que aponta para o
primeiro elemento (nó) da lista.
O campo prox do último nó da lista armazena o valor NULL, que indica o final da lista.
Arranjo da memória de uma lista encadeada
A estrutura consiste em uma sequencia encadeada de elementos, os nós da lista. A lista é
representada por um ponteiro para o primeiro elemento (nó). Do primeiro elemento,
podemos alcançar o segundo, seguindo o encadeamento, e assim por diante. O último
elemento da lista armazena, como próximo elemento, um ponteiro inválido, com valor NULL, e
sinaliza, assim, que não existe um próximo elemento.
Uma lista sem nó é chamada lista vazia ou lista nula e seu ponteiro p é nulo (NULL).
Exemplo:
Declaração do Nó da Lista
struct no {
<tipo> info;
struct no *prox;
};
typedef struct no Lista;
ou
typedef struct no {
<tipo> info;
struct no *prox;
} Lista;
Sabendo que <tipo> pode ser:
� int
� char
� float
� vetor
� struct
� ....
O tipo Lista representa um nó da lista, e a estrutura de lista encadeada é representada
pelo ponteiro para seu primeiro elemento (tipo Lista*).
Lista x; //nó da lista
Lista *p; //ponteiro para um nó da lista
p = &x; ou p = (Lista*) malloc(sizeof(Lista));
Temos que “x” é um nó da lista, portanto:
x.info; //acessa a informação do nó
x.prox; //acessa o endereço do próximo nó
Temos que “p” é um ponteiro para um nó da lista, portanto:
p->info; //acessa a informação do nó
p->prox; //acessa o endereço do próximo nó
O endereço de uma lista encadeada é o endereço do seu primeiro nó.
Portanto, se p aponta para o primeiro nó da lista, então podemos dizer que p é a lista,
pois ele é o único endereço acessível diretamente.
Se p é uma lista, então:
• p = NULL; //lista vazia
• p->prox; //é uma lista
Operações com Listas
Além da representação dos nós, temos os procedimentos básicos sobre listas encadeadas,
que são:
(a) definição da estrutura da lista;
(b) inicialização da lista;
(c) inserção tendo um endereço com referencia;
(d) alocação de um endereço do nó para inserção na lista;
(e) remoção tendo um endereço como referencia para exclusão do nó;
(f) desalocação do nó que foi removido da lista;
(g) localização de um elemento da lista.
(h) etc...
Todas estas operações serão discutidas e implementadas.
Função de Criação
A função que cria uma lista vazia deve ter como valor de retorno uma lista sem nenhum
elemento.
Como a lista é representada pelo ponteiro para o primeiro elemento, uma lista vazia é
representada pelo ponteiro NULL, pois não existem elementos na lista.
A função tem como valor de retorno a lista vazia inicializada, isto é, o valor de retorno é
NULL.
Uma possível implementação da função de criação:
/* função de criação: retorno uma lista vazia */
Lista * cria_lista(void)
{
return NULL;
}
Função de Inserção
Criada a lista vazia, podemos inserir nela novos elementos.
Em uma lista com/sem cabeça, podemos inserir um novo elemento:
� no início;
� no final;
� no meio;
� antes/depois de um elemento;
� antes/depois de uma posição
Para cada elemento inserido, devemos alocar dinamicamente a memória necessária para
armazenar o elemento e encadeá-lo na lista existente.
A função de inserção mais simples insere o novo elemento no início da lista.
Inserção no Início – Lista SEM cabeça
1º passo) Alocação de memória
2º passo) Preencher o campo info
3º passo) novo->prox = p;
4º passo) p = novo;
Ilustração de lista vazia:
Ilustração de lista com elementos:
IMPLEMENTAÇÃO
Uma possível implementação dessa função é mostrada a seguir.
Devemos notar que o ponteiro que representa a lista deve ter seu valor atualizado, pois a
lista deve passar a ser representado pelo ponteiro para o novo primeiro elemento.
Por essa razão, a função de inserção recebe como parâmetros de entrada a lista na qual
será inserido o novo elemento e a informação do novo elemento e tem como valor de retorno
a nova lista, representada pelo ponteiro para o novo elemento.
/* inserção no início: retorna a lista atualizada */
Lista * insere_lista(Lista *p, int x)
{
Lista *novo;
novo = (Lista *) malloc(sizeof(Lista));
novo->info = x;
novo->prox = p;
p = novo;
return (p);
}
main()
{
int x;
char resp = ‘S’;
Lista *p = NULL;
do
{
puts(“Insira um numero inteiro: “);
scanf(“%d”, &x);
p= insere_lista(p,x);
puts(“Insere outro elemento [S/N]: “);
fflush(stdin);
scanf(“ %c”, &resp);
} while (resp == ‘S’ || resp == ‘s’);
}