Você está na página 1de 17

Estrutura de Dados

Alocao Esttica de Memria Listas


Conceito:
So estruturas que permitem representar um conjunto de dados de forma a
preservar a relao de ordem linear entre eles. Uma lista linear composta de ns
que podem conter tanto tipos de dados primitivos quanto construdos.
Operaes:
As operaes mais comuns efetuadas sobre os dados contidos em uma lista linear
so:

acessar determinado n da lista;


inserir um n em determinada posio da lista;
remover determinado n da lista;
determinar o nmero de ns de uma lista;
localizar determinado dado dentro da lista;

Classificaes:
Resumidamente, as seguintes variaes de listas lineares podem ser consideradas:

lista
lista
lista
lista
lista

linear
linear
linear
linear
linear

seqencial (ou contgua)


simplesmente ligada (ou encadeada)
duplamente ligada (ou encadeada)
seqencial ou ligada com disciplina de acesso LIFO (pilha)
seqencial ou ligada com disciplina de acesso FIFO (fila)

Lista Linear Seqencial (ou contguas)


Representao:
1

...

n-1

Caractersticas:
so implementadas atravs de variveis estticas;
o acesso aos seus componentes feito de maneira direta (atravs de um ndice,
por exemplo);
as estruturas de representao que melhor permitem a implementao de listas
lineares seqnciais (ou contguas) so os vetores (arrays).
Vantagens:
Alm de todas as vantagens inerentes a manipulao de variveis estticas,
tambm tm como caracterstica marcante o fato de poderem ser implementadas
em praticamente todas as linguagens de programao mais utilizadas (C, Pascal,
COBOL, Fortran, Clipper etc).

Estrutura de Dados
Desvantagens:
Todas as desvantagens inerentes a manipulao de variveis estticas, como por
exemplo, a necessidade de se prefixar seu tamanho inicial, a impossibilidade de se
redimensionar este tamanho pr-fixado em tempo de execuo, a dificuldade em se
realizar sobre ela certas operaes (insero e remoo, por exemplo) etc..
Ex.: para a lista lineares seqencial abaixo, que contm uma lista de nomes
arranjados em ordem alfabtica, a incluso de um novo nome (Benedito, por
exemplo), acarretaria a necessidade de se rearranjar todos os nomes a partir de
Carlos, para poder abrir espao para a incluso do novo nome.
1

Aaro

Carlos

Clia

Dalva

Eldio

Fbio

Francisco

Gustavo

Hlio

10

Iria

11

Joaquim

12

Jos
Ktia

13

Zaqueu

....
n-1

Zulmira

Aps a incluso do novo nome, novas incluses seriam impossveis, visto que no
mais haveria espao disponvel para tanto.
Principais Operaes em Listas:
As principais operaes so:

Insero: no incio ou final da Lista;


Remoo: no incio ou final da Lista;
Impresso
Pesquisa

Implementao de Listas em Vetor


Como as listas lineares podem ser representadas em C? Como uma lista apenas
um conjunto de ns, um vetor de ns uma idia imediata.
Insero no Final da Lista
Dado o vetor de nome valor abaixo com capacidade para 10 posies para
inteiros, a insero pelo final, ser realizada a seguinte forma:

valor
i= 0

Estrutura de Dados
Ao inserir um elemento inteiro 10 pelo final do vetor valor, como o mesmo se
encontra vazio, o elemento ir ocupar a posio referente ao ndice 0 do vetor.
Essa posio passa a ser a primeira e a ltima posio do vetor. Um prximo
elemento inteiro 20 a ser inserido ir ocupar a posio 1 do vetor. O elemento
seguinte ir ocupar a posio 2 do vetor e assim por diante at o vetor ter todas as
suas posies preenchidas.
Suponha a insero dos elementos: 10, 20, 30, 40, 50 e 60 nesta ordem. A lista
ficar representada conforme a figura abaixo:

valor

10

20

30

40

50

60

i= 0

Conforme o vetor acima, a prxima posio livre a posio 6 do vetor valor,


sendo assim o prximo elemento dever ser inserido nessa posio e a ltima
posio livre do vetor passar a ser a posio 7.

valor

10

20

30

40

50

60

70

i= 0

Remoo no Final da Lista


A Remoo pelo Final da Lista, deve acontecer pela ltima posio do vetor valor
que possui elemento. De acordo com o vetor valor, a ltima posio com elemento
a posio 6, logo, o elemento a ser removido pelo final do vetor, o elemento
que ocupa esta posio, sendo o elemento 70. Aps o elemento 70 ser removido, o
ltimo elemento do vetor passa a ser o elemento da posio 5, isto , o elemento
60. Dessa forma, as remoes dessa lista representada pelo vetor valor ocorrem
pelo final da lista.

valor

10

20

30

40

50

60

i= 0

importante verificar em uma insero, se a lista est cheia. Dessa forma, no


possvel inserir mais elementos. Da mesma forma, importante verificar em uma
remoo se a lista no est vazia.
Impresso da Lista
A impresso da lista consiste em apresentar todos os elementos que fazem parte
da lista, mostrando os elementos que ocupam a posio 0 do vetor at a ltima
posio preenchida do vetor.

Estrutura de Dados
Pesquisa na Lista
A pesquisa na lista consiste em procurar elementos no vetor, informando se o
elemento foi encontrado ou no e qual a posio do vetor que este elemento ocupa.
A Impresso e a Pesquisa de elementos da lista se mostram de forma semelhante,
tanto para inseres e remoes do incio ou final da lista.
Exemplo: Implementao de Lista Esttica em C para nmeros inteiros, com
operaes de insero no final da lista, remoo do final da lista, consulta e
pesquisa de elementos.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define MAX 5
void insere_final();
void remove_final();
void imprime_lista();
void busca();
struct lista
{
int valor[MAX];
int tamanho;
int inicio;
}; struct lista l;
main()
{
l.inicio = l.tamanho = 0;
int op;
while(op != 5)
{
system("cls");
printf("Manipulacao de Lista Estatica");
printf("\nDigite 1 para Insercao no Inicio");
printf("\nDigite 2 para Imprimir a Lista");
printf("\nDigite 3 para Remover do Inicio");
printf("\nDigite 4 para Buscar Elemento");
printf("\nDigite 5 para Sair");
printf("\nDigite a opcao desejada: ");
scanf("%i",&op);
switch(op)
{
case 1: insere_final(); break;
case 2: imprime_lista(); break;
case 3: remove_final(); break;
case 4: busca();
break;
case 5: exit(1);
default: printf("\nEntre com uma opcao valida!");
}
}

Estrutura de Dados
}
void insere_final()
{
int x;
if(l.tamanho == MAX)
{
printf("\nLista cheia!");
exit(1);
}
else
{
printf("\nDigite uma valor: ");
scanf("%i",&x);
l.valor[l.tamanho] = x;
l.tamanho++;
printf("Elemento %i inserido com sucesso!",x);
}
getch();
}
void remove_final()
{
if(l.tamanho == 0)
{
printf("\nLista Vazia!");
exit(1);
}
l.tamanho--;
printf("Elemento %i removido com sucesso!",l.valor[l.tamanho]);
getche();
}
void imprime_lista()
{
int v;
int i;
i = l.inicio;
while(i != l.tamanho)
{
v = l.valor[i];
printf("\nElemento %i da lista eh: %i",i,v);
i++;
}
getche();
}
void busca()
{
bool encontrou;
int valor_procurado;
int v;
int i;
i = l.inicio;
printf("Entre com o valor que deseja buscar: ");
scanf("%i",&valor_procurado);

Estrutura de Dados
while(i != l.tamanho)
{
v = l.valor[i];
if(v == valor_procurado)
{
printf("Elemento %i encontrado na posicao %i",l.valor[i],i);
encontrou = 1;
}
i++;
}
if(encontrou != 1)
printf("Elemento %i nao encontrado",valor_procurado);
getche();
}
Remoo do Incio da Lista
A Remoo pelo Incio da Lista, deve acontecer sempre pela primeira posio do
vetor valor, isto , a posio de ndice 0. De acordo com o vetor valor, a primeira
posio ocupada pelo elemento 70, logo, ele o primeiro elemento a ser
removido do vetor. Aps o elemento 70 ser removido, o primeiro elemento do
vetor passa a ser o elemento passa a ser o elemento que ocupava a posio 1 do
vetor, isto , o elemento 60. E todos os elementos andam uma posio para
trs.

valor

60

50

40

30

20

10
0

i= 0

Da mesma forma que a insero pelo final da lista, importante verificar em uma
insero, se a lista est cheia. Dessa forma, no possvel inserir mais elementos.
Deve-se verificar tambm em uma remoo se a lista no est vazia.
Exemplo: Implementao de Lista Esttica em C para nmeros inteiros, com
operaes de insero no incio da lista, remoo do incio da lista, consulta e
pesquisa de elementos.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define MAX 5
void insere_inicio();
void remove_inicio();
void imprime_lista();
void busca();
struct lista
{
int valor[MAX];
int inicio, final, tamanho;

Estrutura de Dados
}; struct lista l;
main()
{
l.inicio = l.tamanho = 0;
l.final = -1;
int op;
while(op != 5)
{
system("cls");
printf("Manipulacao de Lista Estatica");
printf("\nDigite 1 para Insercao no Inicio");
printf("\nDigite 2 para Imprimir a Lista");
printf("\nDigite 3 para Remover do Inicio");
printf("\nDigite 4 para Buscar Elemento");
printf("\nDigite 5 para Sair");
printf("\nDigite a opcao desejada: ");
scanf("%i",&op);
switch(op)
{
case 1: insere_inicio(); break;
case 2: imprime_lista(); break;
case 3: remove_inicio(); break;
case 4: busca();
break;
case 5: exit(1);
default: printf("\nEntre com uma opcao valida!");
}
}
}
void insere_inicio()
{
int i, vezes = 0;
int x;
if(l.tamanho == MAX)
{
printf("\nLista cheia!");
exit(1);
}
else
{
printf("\nDigite uma valor: ");
scanf("%i",&x);
i = l.final;
while (vezes < l.tamanho)
{
l.valor[i+1] = l.valor[i];
i--;
vezes++;
}
l.final++;
l.valor[l.inicio] = x;
l.tamanho++;
}

Estrutura de Dados
getche();
}
void remove_inicio()
{
int i, vezes=0;
if(l.tamanho == 0)
{
printf("\nLista Vazia!");
exit(1);
}
i = l.inicio;
while (vezes < (l.tamanho-1))
{
l.valor[i] = l.valor[i+1];
i++;
vezes++;
}
l.final--;
l.tamanho--;
getche();
}
void imprime_lista()
{
int v;
int i;
i = l.inicio;
while(i != l.tamanho)
{
v = l.valor[i];
printf("\nElemento %i da lista eh: %i",i,v);
i++;
}
getche();
}
void busca()
{
bool encontrou;
int valor_procurado;
int v;
int i;
i = l.inicio;
printf("Entre com o valor que deseja buscar: ");
scanf("%i",&valor_procurado);
while(i != l.tamanho)
{
v = l.valor[i];
if(v == valor_procurado)
{
printf("Elemento %i encontrado na posicao %i",l.valor[i],i);
encontrou = 1;
}
i++;

Estrutura de Dados
}
if(encontrou != 1)
printf("Elemento %i nao encontrado",valor_procurado);
getche();
}
Exemplo de Insero e Remoo do Final da Lista usando Ponteiro
O exemplo a seguir, implementa o mesmo exemplo acima, porm as funes iro o
ponteiro da varivel umaLista que pertece a estrutura, isto , as funes iro
receber o endereo da varivel umaLista.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define MAX 5
struct lista
{
int valor[MAX];
int tamanho;
int inicio;
};
void inicia(struct lista *umaLista)
{
umaLista->inicio = umaLista->tamanho = 0;
}
void insere_final(struct lista *l, int x)
{
if(l->tamanho == MAX)
{
printf("\nLista cheia!");
exit(1);
}
else
{
l->valor[l->tamanho] = x;
l->tamanho++;
printf("Elemento %i inserido com sucesso!",x);
}
getch();
}
int remove_final(struct lista *l)
{
if(l->tamanho == 0)
{
printf("\nLista Vazia!");
exit(1);
}
l->tamanho--;
printf("Elemento %i removido com sucesso!",l->valor[l->tamanho]);
return l->valor[l->tamanho];
getche();

Estrutura de Dados
}
void imprime_lista(struct lista *l)
{
int v;
int i;
i = l->inicio;
while(i != l->tamanho)
{
v = l->valor[i];
printf("\nElemento %i da lista eh: %i",i,v);
i++;
}
getche();
}
void busca(struct lista *l)
{
bool encontrou;
int valor_procurado;
int v;
int i;
i = l->inicio;
printf("Entre com o valor que deseja buscar: ");
scanf("%i",&valor_procurado);
while(i != l->tamanho)
{
v = l->valor[i];
if(v == valor_procurado)
{
printf("Elemento %i encontrado na posicao %i",l->valor[i],i);
encontrou = 1;
}
i++;
}
if(encontrou != 1)
printf("Elemento %i nao encontrado",valor_procurado);
getche();
}
main()
{
int op;
int valor, retorno;
struct lista umaLista;
inicia(&umaLista);
while(op != 5)
{
system("cls");
printf("Manipulacao de Lista Estatica");
printf("\nDigite 1 para Insercao no Final");
printf("\nDigite 2 para Imprimir a Lista");
printf("\nDigite 3 para Remover do Final");

Estrutura de Dados
printf("\nDigite 4 para Buscar Elemento");
printf("\nDigite 5 para Sair");
printf("\nDigite a opcao desejada: ");
scanf("%i",&op);
switch(op)
{
case 1:
printf("Digite um valor para lista: ");
scanf("%i",&valor);
insere_final(&umaLista,valor);
break;
case 2:
imprime_lista(&umaLista);
break;
case 3:
retorno = remove_final(&umaLista);
break;
case 4:
busca(&umaLista);
break;
case 5: exit(1);
default: printf("\nEntre com uma opcao valida!");
}
}
}
Outro exemplo de Insero e Remoo Final da Lista usando Ponteiro para
duas listas distintas
Este exemplo muito semelhante ao anterior, porm faz uso da criao de duas
listas distintas. As funes so as mesmas apresentadas anteriormente, porm
agora com dois ponteiros distintos.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define MAX 5
struct lista
{
int valor[MAX];
int tamanho;
int inicio;
};
void inicia(struct lista *l)
{
l->inicio = l->tamanho = 0;
}
void insere_final(struct lista *l, int x)
{
if(l->tamanho == MAX)
{

Estrutura de Dados
printf("\nLista cheia!");
exit(1);
}
else
{
l->valor[l->tamanho] = x;
l->tamanho++;
printf("Elemento %i inserido com sucesso!",x);
}
getch();
}
int remove_final(struct lista *l)
{
if(l->tamanho == 0)
{
printf("\nLista Vazia!");
exit(1);
}
l->tamanho--;
printf("Elemento %i removido com sucesso!",l->valor[l->tamanho]);
return l->valor[l->tamanho];
getche();
}
void imprime_lista(struct lista *l)
{
int v;
int i;
i = l->inicio;
while(i != l->tamanho)
{
v = l->valor[i];
printf("\nElemento %i da lista eh: %i",i,v);
i++;
}
getche();
}
void busca(struct lista *l)
{
bool encontrou;
int valor_procurado;
int v;
int i;
i = l->inicio;
printf("Entre com o valor que deseja buscar: ");
scanf("%i",&valor_procurado);
while(i != l->tamanho)
{
v = l->valor[i];
if(v == valor_procurado)
{
printf("Elemento %i encontrado na posicao %i",l->valor[i],i);
encontrou = 1;

Estrutura de Dados
}
i++;
}
if(encontrou != 1)
printf("Elemento %i nao encontrado",valor_procurado);
getche();
}
main()
{
int op;
int valor, retorno;
struct lista l1, l2;
inicia(&l1);
inicia(&l2);
while(op != 9)
{
system("cls");
printf("Manipulacao de 2 Listas Estaticas");
printf("\nDigite 1 para Insercao no Final da Lista l1");
printf("\nDigite 2 para Insercao no Final da Lista l2");
printf("\nDigite 3 para Imprimir a Lista l1");
printf("\nDigite 4 para Imprimir a Lista l2");
printf("\nDigite 5 para Remover do Final da Lista l1");
printf("\nDigite 6 para Remover do Final da Lista l2");
printf("\nDigite 7 para Buscar Elemento na Lista l1");
printf("\nDigite 8 para Buscar Elemento na Lista l2");
printf("\nDigite 9 para Sair");
printf("\nDigite a opcao desejada: ");
scanf("%i",&op);
switch(op)
{
case 1:
printf("Digite um valor para a lista l1: ");
scanf("%i",&valor);
insere_final(&l1,valor);
break;
case 2:
printf("Digite um valor para a lista l2: ");
scanf("%i",&valor);
insere_final(&l2,valor);
break;
case 3:
printf("\nImpressao da lista l1");
imprime_lista(&l1);
break;
case 4:
printf("\nImpressao da lista l2");
imprime_lista(&l2);
break;
case 5:
printf("\nRemocao da lista l1");
retorno = remove_final(&l1);

Estrutura de Dados
break;
case 6:
printf("\nRemocao da lista l2");
retorno = remove_final(&l2);
break;
case 7:
busca(&l1);
break;
case 8:
busca(&l2);
break;
case 9: exit(1);
default: printf("\nEntre com uma opcao valida!");
}
}
}

Exemplo: Implementao de Lista Esttica Tenenbaum. Este exemplo, implementa


uma lista para 500 ns, utilizando uma estrutura com campos info (que contm o
elemento inserido) e next (prximo elemento da lista) e criado um vetor
node[NUMNODES] para as 500 posies. A figura abaixo representa a manipulao
dessa lista.

info

next

499

-1

Estrutura de Dados
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define NUMNODES 500
int avail;
struct nodetype
{
int info, next;
};
struct nodetype node[NUMNODES];
void inicia()
{
avail = 0;
for(int i = 0; i < NUMNODES-1; i++)
node[i].next = i + 1;
node[NUMNODES-1].next = -1;
}
int getnode()
{
int p;
if(avail == -1)
{
printf("estouro\n");
exit(1);
}
p = avail;
avail = node[avail].next;
return(p);
}
int freenode(int p)
{
node[p].next = avail;
avail = p;
return avail;
}
void insafter(int p, int x)
{
int q;
if(p == -1)
{
printf("insercao nula\n");
return;
}
q = getnode();
node[q].info = x;
node[q].next = node[p].next;
node[p].next = q;
printf("\nElemento %i inserido com sucesso!",x);
getche();

Estrutura de Dados
}
int delafter(int p, int *px)
{
int q;
if((p == -1) || (node[p].next == -1))
{
printf("remocao nula\n");
return -1;
}
q = node[p].next;
*px = node[q].info;
node[p].next = node[q].next;
freenode(q);
return *px;
}
main()
{
int op;
int valor;
int retorno;
inicia();
while(op != 3)
{
system("cls");
printf("Manipulacao de Lista");
printf("\nDigite 1 para inserir elemento na lista");
printf("\nDigite 2 para remover elemento da lista");
printf("\nDigite 3 para sair");
printf("\nEntre com a opcao desejada: ");
scanf("%i",&op);
switch(op)
{
case 1:
printf("Entre com um valor: ");
scanf("%i",&valor);
insafter(1, valor); break;
case 2:
retorno = delafter(1,&valor);
printf("O valor de retorno eh: %i",retorno);
getch();
break;
case 3: exit(1);
}
}
}
A funo inicia() responsvel por montar a lista ilustrada no desenho acima e
colocar nos campos next o valor dos campos prximos. A ltima posio, tem -1
na posio next.

Estrutura de Dados
A funo void insafter(int p, int x), responsvel pela insero dos elementos na
lista. realizado uma chamada para a funo getnode() que verifica se a lista est
cheia e caso no esteja, devolve a prxima posio livre em que o elemento pode
ser inserido.
A funo int delafter(int p, int *px), responsvel pela excluso dos elementos.
realizada uma chamada para a funo freenode() libera um n que no ser mais
utilizado.
Este exemplo apresenta de uma forma um pouco mais complexa, o exemplo
apresentado anteriormente para lista com insero no final e remoo do final da
lista.