EDB 12 - TAD Sequencia - Implementacao

Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1de 30

TAD Sequencia

Formas de implementação
Formas de implementação de sequencias num computador

• Vetor: Toda a sequencia como um bloco único e contínuo na


memória.

• Lista Ligada: Representa a sequencia de uma maneira distribuída na


memória, com os elementos conectados entre si de forma lógica.
Formas de manipulação de uma sequência
• Inserção: 3 7 2 1 9 => 3 7 2 0 1 9
• Remoção: 3 7 2 0 1 9 => 3 7 2 0 9
• Acesso: Quando perguntamos qual elemento está numa determinada
posição. Ex. na sequencia 3 7 2 1 9, qual está na posição 3? Elemento 1.
As três operações podem ser realizadas de três formas:
• Arbitrária (Em qualquer posição)
• No Início
• No Fim
• Isso é importante a depender do tipo de uso da sequência, como pilhas
ou filas vistos a seguir.
Tipos Abstratos de dados para as operações
• Pilha: Só pode inserir e remover o último elemento.
Remoção 3 =>
2 2
1 1
0 0

Inserção => 3
2 2
1 1
0 0
Tipos Abstratos de dados para as operações
• Implementação da Pilha: Só é preciso se preocupar com as operações
de inserção e remoção no fim (ou início, dependendo do ponto de
vista) da pilha, não precisando se preocupar com a forma arbitrária,
que não é possível.
Tipos Abstrato de dados para as operações
• TAD Fila: Remoção no início e inserção no fim, ou remoção no fim e
inserção no início. Usa o buffer de memória.
• Ex.: Vídeos, por exemplo com o download dos frames no início e a
remoção da fila ao fim, a medida que os frames são exibidos. Outros
exemplos de buffer são áudios ou wi-fi.
TAD Filha - Buffer

Inserção Arbitrária Início Fim

Remoção Arbitrária Início Fim

Acesso Arbitrária Início Fim


Formas de implementação de sequencias num computador /
vantagens e desvantagens

• No vetor é necessária a disponibilidade de um bloco de memória


contínuo para armazenar toda a lista de forma sequencial. Na Lista
Ligada isso não é necessário, é preciso apenas uma quantidade de
blocos do tamanho de cada um dos elementos, não precisando ser
contínuos.
• Outra desvantagem do vetor é que todos os elementos precisam ser
do mesmo tipo, já na lista ligada, como cada elemento é posicionado
em posições diferentes, e um apontando para o outro, isso não é
necessário, pode-se haver heterogeneidade de elementos (Ex: um é
um áudio, outro um arquivo texto, o outro um vídeo).
Formas de implementação de sequencias num computador /
vantagens e desvantagens

• Já uma desvantagem da lista ligada é a necessidade do uso de


ponteiros, que também ocupam espaço de memória.
• Outro ponto é a questão do acesso, enquanto no vetor temos acesso
aleatoriamente a qualquer elemento, na lista ligada só temos acesso
ao primeiro elemento, precisando percorrer a lista para acessar
elementos numa posição arbitrária. O acesso é sequencial, sendo
mais custoso.
Implementação de sequências
usando vetor
Implementação de sequências usando a
estrutura de dados vetor
• Inserção
• Remoção
• Acesso
• Outras duas:
• Criação
• Liberação
de espaço
Implementação de sequências usando a
estrutura de dados vetor
• Criando o código:
• Variáveis:
se o valor já é
char V* = (char* x) malloc(Nmax * sizeof(char));// ou char V[10] conhecido
(alocação
int N = 0; estática)
int Nmax = 10;
...
free(V); //caso a alocação tenha sido dinâmica, para liberar o espaço
Implementação de sequências usando a
estrutura de dados vetor
• Criando o código:
• Acesso:
char acesso(char *V, int N; int pos);
Sequencia controle
return V[pos]; //genericamente seria *(V + pos), o valor na posição V + pos
Obs: Complexidade O(1). Independente de posição, acesso randômico, constante
(vetor). Ex: V[2] 0 1 2 3 4 5

3 2 1 7 6

5 2
Char * V N pos
Implementação de sequências usando a
estrutura de dados vetor
Criando o código (cont.), inserção:
void inserir(char *V, int N; int Nmax, int pos, int el);
Vetor Parâmetros inserção
if N == Nmax return;
for (int ii = N-1; ii ≥ pos; ii-- )
V[ii+1] = V[ii];
V[pos] = el;
0 1 2 3 4 5
Ex: 0 1 2 3 4 5
2 3 9 1 5
2 3 1 5

5 2 6 9
4 2 6 9
Char Char N pos Nmax el
*V N pos Nmax el *V
Implementação de sequências usando a
estrutura de dados vetor
Ex inserção: sequencia 7 3 2 1 5, pos = 1 N = 5 Nmax= 6, el = 9.
Sequencias: 7 3 2 1 5 5 -> 7 3 2 1 1 5 -> 7 3 2 2 1 5 -> 7 3 3 2 1 5 -> 7 9 3 2 1 5

Complexidade do algoritmo no pior caso: O(N), para o caso de uma inserção no primeiro
elemento, pois o for percorre todo o vetor. Isso também ocorre para o caso de um
elemento aleatório intermediário. Contudo, para o melhor caso, uma inserção na posição
N, o algoritmo não vai entrar no loop, vai direto para a atribuição V[pos] = el, com isso a
complexidade no melhor caso é O(1), constante.
Implementação de sequências usando a
estrutura de dados vetor
Ajustando o código da inserção, pois o N deve ser alterado:
int inserir(char *V, int N; int Nmax, int pos, int el);
Vetor Parâmetros inserção
if N == Nmax return;
for (int ii = N-1; ii ≥ pos; ii-- )
V[ii+1] = V[ii];
V[pos] = el;
return N + 1;
Implementação de sequências usando a
estrutura de dados vetor
Criando o código (cont.), remoção:
int remover(char *V, int N; int pos);
Vetor Parâmetros remoção
if N == 0 return N;
for (int ii = pos; ii ≤ N-2; ii++ )
V[ii] = V[ii + 1];
return N - 1
0 1 2 3 4 5 0 1 2 3 4 5
Ex:
2 3 8 1 5 2 3 1 5

5 2 4
Char Char
*V N pos *V N
Implementação de sequências usando a
estrutura de dados vetor
Ex remoção: sequencia 7 3 2 1 5, pos = 1, N = 5.
Sequencias: 7 3 2 1 5 -> 7 2 2 1 5 -> 7 2 1 1 5 -> 7 2 1 5 5 -> 7 2 1 5

Complexidade do algoritmo no pior caso: O(N), para o caso de uma remoção do primeiro
elemento, pois o for percorre todo o vetor, analogamente ao algoritmo de inserção. Isso
também ocorre para o caso da remoção de um elemento aleatório intermediário.
Contudo, para o melhor caso, uma remoção na posição N, o algoritmo não vai entrar no
loop, com isso a complexidade no melhor caso é O(1), constante.
Implementação de sequências usando a
estrutura de dados vetor
• Complexidade, resumo:
Inicio Fim Aleatório
Inserção Linear Constante Linear
Remoção Linear Constante Linear
Acesso Constante Constante Constante

Legenda:
• Pilha:
• Fila:
Implementação de fila com vetor
circular
Implementação de fila com vetor circular
O vetor circular dá a ideia de posições infinitas em ambos os lados.

0 1 2 3 4 5

A C D E F

...-2 -1 0 1 2 3 4 5 6...

A C D E F
Implementação de fila com vetor circular
O vetor circular dá a ideia de posições infinitas em ambos os lados.

...-2 -1 0 1 2 3 4 5 6...

A C D E F

5 ∞ 0
...-2 -1 0 1 2 3 4 5 6...
Char * V N Nmax B

X R A C D E F

5 ∞ -2
Char * V N Nmax B
Implementação com vetor circular
Como implementar? Considerando que Nmax = ∞ não é possível. A ideia é um espelhamento do
vetor, para isso é necessário usar o mod (%).

...-3 -2 -1 0 1 2 3 4 5 6 7 8 9

X Z F R X T X Z F R

6 10 5
Char * V N Nmax B
Implementação com vetor circular
• Uso do operador %(mod). Ex: Para Nmax = 4

Pos % 3 0 1 2 3 0 1 2 3 0 1
Nmax

pos -1 0 1 2 3 4 5 6 7 8 9
Implementação com vetor circular
Void inserir_inicio(char * V, int *N, int *B, int Nmax, char el)
if (*N == Nmax) return
*B--; //incompleto
V[*B] = el;
*N++;
Obs: O B representa a posição do primeiro elemento, o inicio da
sequência
Implementação com vetor circular
Void inserir_inicio(char * V, int *N, int *B, int Nmax, char el)
if (*N == Nmax) return 0 1 2 3 4 5

*B = (*B – 1) % Nmax; // O(1)


A C D E Z
V[*B] = el;
*N++; 4→5 6 0 Z
A posição *B recebe ela mesma – 1, visto que N Nmax B el

estamos inserindo no inicio, mas é preciso usar o % (mod), para


funcionar pra qualquer valor, inclusive para o 0 (fica - 1 % Nmax = 5) .
No exemplo, o novo elemento (el = Z) está sendo inserido no inicio da
sequencia, que é a posição 5.
Implementação com vetor circular
Void inserir_fim(char * V, int *N, int *B, int Nmax, char el)
if (*N == Nmax) return 0 1 2 3 4 5

V[*N + *B]% Nmax] = el; // O(1)


H X 3 Z
*N++;
Para a inserção no fim, diferentemente do 3→4 6 3 H
caso anterior, não é preciso alterar a posição N Nmax B el

de B, pois a posição do elemento inicial não muda.


É preciso apenas atribuir o elemento à posição de valor (*N + *B)
%Nmax, que resultará na última posição do vetor.
Implementação com vetor circular
char acesso(char *V, int N; int pos, int Nmax, int B);
return V[pos + B]%Nmax; //O(1);
Implementação com vetor circular
Void remover_inicio(char * V, int *N, int *B, int Nmax)
if (*N == 0) return
*N--;
*B = (*B + 1) % Nmax; // Complexidade O(1)
3 4 5 6 7 8

T G X 3 Z

5→4 6 4→5
N Nmax B
Implementação com vetor circular
Void remover_fim(char * V, int *N, int *B, int Nmax)
if (*N == 0) return
*N--;

// Complexidade O(1).
Implementação com vetor circular
• Complexidade, resumo:
Inicio Fim Aleatório
Inserção Constante Constante Linear
Remoção Constante Constante Linear
Acesso Constante Constante Constante

Legenda:
• Pilha:
• Fila:

Você também pode gostar