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