Você está na página 1de 41

Algoritmos e Estrutura de Dados

(AED)
2º semestre 2022/2023
Semana 5
Sacos, Deques, Listas e Filas
Prioritárias – Implementação

Caroline Conti & Filipe Santos


Sumário
▪ Este módulo pretende introduzir a implementação matricial
(Array) e dinâmica (Linked-Lists) de outros tipos de dados
lineares

▪ Parte 1:
▪ Bags – Implementação com Array e Linked-Lists
▪ Deques – Implementação com Array e Linked-Lists

▪ Parte 2:
▪ Lists – Implementação com Array e Linked-Lists
▪ Priority Queues – Implementação com Array e Linked-Lists
Referência

▪ Algorithms, 4th edition by R.


Sedgewick and K. Wayne,
Addison-Wesley Professional,
2011:
▪ Chapter 1.3
▪ Lecture Slides: Bags, Queues, and
Stacks
h t t p : / / a l g s 4. c s . p r i n c e t o n . e d u
Saco (Bag)
Bag API
▪ Principal aplicação: Adicionar itens para a coleção
e iterar sobre estes itens (a ordem não é relevante)

public class Bag<Item> implements Iterable<Item>

Bag() create an empty bag

void add(Item x) insert a new item onto bag

int size() number of items in bag

Iterable<Item> iterator() iterator for all items in bag

▪ Implementação:
Stack (sem a operação pop) ou Queue (sem a
operação dequeue).
(from KW slides, used with permission)
Lista duplamente terminada
(Deque)
Deque API
▪ Principal aplicação: Utilização simultânea de operações
existentes em Stack e Queue. Suporta facilmente rotações
de elementos no sentido horário e anti-horário.

public class Deque<Item> implements Iterable<Item>


Deque() create an empty deque
boolean isEmpty() is the deque empty?
int size() number of items
void pushLeft(Item item) add an item to the left end
void pushRight(Item item) add an item to the right end
Item popLeft() remove an item from the left end
Item popRight() remove an item from the left end
Deque – Implementação
com Array
Deque – Implementação com Array

▪ Representação:
▪ d[]: array redimensionável para armazenar os itens do deque
▪ first: índice do primeiro item do deque
▪ last: índice do último item do deque
▪ pushLeft(item): decrementa first; adiciona item em d[first]
▪ pushRight(item): incrementa last; adiciona item em d[last]
▪ popLeft(): remove item de d[first]; incrementa first
▪ popRight(): remove item de d[last]; decrementa last
▪ Ocupação circular do array para otimizar o espaço

d[] null null he who is brave is free null null

0 1 2 3 4 5 6 7 8 9
first last
Deque – Implementação com Array

▪ Representação:
▪ Incremento circular: Resto da divisão pela capacidade do array
next(i) = (i + 1) % d.lenght

▪ Decremento circular: Antes da componente índice 0 está a


componente índice d.lenght-1

i – 1 , i > 0
previous(i) = ቊ
d.length – 1 , i == 0

null null he who is brave is free null null


d[]
0 1 2 3 4 5 6 7 8 9
first last
Deque – Implementação
com Linked-List
Deque – Implementação com Linked-List
▪ Representação: Sequência de nós duplamente ligados
▪ Cada nó guarda a referência dos dois nós vizinhos (anterior e próximo)
▪ first: atributo usado para manter a referência do primeiro nó
▪ last: atributo usado para manter a referência do último nó
▪ pushLeft(item): adiciona novo item antes do apontado por first
▪ pushRight(item): adiciona novo item depois do apontado por last
▪ popLeft(): remove o item apontado por first
▪ popRight(): remove o item apontado por last

first last

null to be or not to be null


Deque – Implementação com Linked-List
▪ Classe Node:
▪ Classe interna que representa um nó
▪ item: contém um item do deque
▪ next: contém a referência para o próximo nó no deque, ou null
▪ prior: contém a referência para o nó anterior no deque, ou null

private class Node { nó


item
Item item;
hello
Node next, prior;
null next
}
null prior

Deque – Implementação com Linked-List
Obs.: Deve também verificar
▪ Operação popLeft(): se há itens para retirar!
Classe Nó

private class Node {


▪ Guarda item da primeira posição no deque Item item;
Node next, prior;
Item item = first.item;
}
last
▪ Remove o primeiro nó do deque to be or
first
if (first != last) { null

first = first.next; null last

first.prior = null; first be or


} else { null

first = null; null

last = null; (caso especial, em que a fila fica vazia)


} last last

▪ Devolve o item salvo to first


first null
return item; null
null
Deque – Implementação com Linked-List
Obs.: Deve também verificar
▪ Operação popRight(): se há itens para retirar!
Classe Nó

private class Node {


▪ Guarda item da ultima posição no deque Item item;
Node next, prior;
Item item = last.item;
}
▪ Remove o primeiro nó do deque last

if (first != last) { first


to be or
null
last = last.prior;
null
last.next = null;
last
} else { first
to be
null
first = null;
null null
last = null;
} (caso especial, em que a fila fica vazia)
last
last
▪ Devolve o item salvo
to
first
return item; first null
null
null
Deque – Implementação com Linked-List
oldfirst
▪ Operação pushLeft(item): last

to be or
first
▪ Guarda a referência do primeiro nó null
null
Node oldfirst = first;
oldfirst
last
▪ Cria um novo nó para o primeiro to be or
first
null null
first = new Node();
null null

▪ Insere item ao novo nó e liga o


last
nó ao deque oldfirst
not to be or
first.item = item; first
null
first.next = oldfirst; null
if(last != null)
(caso especial com o deque vazio)
oldfirst.prior = first;
oldfirst last
else last
not
first
last = first; first
null null
Deque – Implementação com Linked-List
oldlast
▪ Operação pushRight(item): last
to be or
first
▪ Guarda a referência do último nó null
null
Node oldlast = last;
oldlast last
▪ Cria um novo nó para o último
to be or not
first
last = new Node(); null null
null null

▪ Insere item ao novo nó e liga o


oldlast last
nó ao deque
to be or not
last.item = item; first
null
last.prev = oldlast;
null
if(first != null)
(caso especial com o deque vazio)
oldlast.next = last; last
last not
else oldlast
first null
first = last; first
null
Lista (List)
List API
▪ Principal aplicação: Suportar mais operações que as
coleções vistas anteriormente (por ex., Stack e Queue),
incluindo aceder itens pelo seu índice. A ordem é relevante.

public class List<Item> implements Iterable<Item>


List() create an empty list
boolean isEmpty() is the list empty?
int size() number of items
void add(Item item) append item to the end
Item get(int index) return item at given index
Item remove(int index) return and delete item at given index
boolean contains(Item item) does the list contain the given item?
Iterator<Item> iterator() iterator over all items in the list
...

(from KW slides, used with permission)


List – Implementação com Array
List – Implementação com Array

▪ Representação:
▪ l[]: array redimensionável para armazenar os itens da lista

▪ first: índice do primeiro item da lista

▪ last: índice do último item da lista

▪ Ocupação circular do array para otimizar o espaço

l[] null null he who is brave is free null null

0 1 2 3 4 5 6 7 8 9
first last
List – Implementação com Array
▪ Operações adicionais:

l[] to be null null null null to be or not

0 1 2 3 4 5 6 7 8 9
last first get(3)
▪ contains(item): verifica se encontra o item entre as posições
first e last
▪ get(index): devolve o item na posição index a contar a partir
de first
▪ remove(index): remove o item na posição index a partir de
first e reagrupa os restantes elementos no array (à esquerda
ou direita)
2 1

l[] to be null null null null to be or not

0 1 2 3 4 5 6 7 8 9
last first remove(3)
List – Implementação com Array

▪ Representação:
▪ Incremento circular: Resto da divisão pela capacidade do array
next(i) = (i + 1) % l.lenght

▪ Decremento circular: Antes da componente índice 0 está a


componente índice l.lenght-1

i – 1 , i > 0
previous(i) = ቊ
l.length – 1 , i == 0

null null he who is brave is free null null


l[]
0 1 2 3 4 5 6 7 8 9
first last
List – Implementação

public boolean contains(Item item){


if(isEmpty()) return false;
else {
boolean exists = item.equals(l[first]);
for(int i=next(first); i!=next(last)&&!exists; i=next(i))
if(item.equals(l[i])) exists = true;
return exists;
}
}

public Item get(int index){


if (index <= 0 || index > size())
throw new IllegalArgumentException("Error: index out of bounds");

int position = (first+index-1)%l.length;


return l[position];
}
List – Implementação
public Item remove(int index){
if (index <= 0 || index > size())
throw new IllegalArgumentException("Error: index out of bounds");

int position = (first+index-1)%l.length;


Item item = l[position];

if(first == last) {
first = -1;
last = -1;
}
else if(position<l.length/2) {
for(int i = position; i != first; i = previous(i))
l[i] = l[previous(i)];
l[first] = null;
first = next(first);
}
else {for(int i = position; i != last; i = next(i))
l[i] = l[next(i)];
l[last] = null;
last = previous(last);
}
return item;
}
List – Implementação
com Linked-List
List – Implementação com Linked-List
▪ Exemplo:
to be or not to
first last
null

▪ contains(item): indica se o item existe entre as posições first e


last

▪ get(index): indica qual o item na posição índex a partir de first


get(3)
▪ remove(index): remove o item na posição index a partir de first

to be or not to
first last
null

remove(3)
List – Implementação

public boolean contains(Item item){


boolean exists = false;
for(Node i = first; i != null && !exists; i = i.next)
if(item.equals(i.item)) exists = true;
return exists;
}

public Item get(int index){


if (index <= 0 || index > size())
throw new IllegalArgumentException("Error: index out of bounds");

Node pos = first;


for (int n = 1; n != index; n++)
pos = pos.next;
return pos.item;
}
List – Implementação

public Item remove(int index){


if (index <= 0 || index > size())
throw new IllegalArgumentException("Error: index out of bounds");

Node ant = null, pos = first;


for (int n = 1; n != index; n++) {
ant = pos;
pos = pos.next;
}

if(ant == null)
first = first.next;
else
ant.next = pos.next;
if(first == null)
last = null;
return pos.item;
}
Priority Queue – Implementação
com Array
Priority Queue API
▪ Principal aplicação: Aceder a elementos mais prioritários,
independentemente da ordem de inserção

public class PQ<Item extends comparable<Item>>


PQ() create an empty PQ
boolean isEmpty() is the list empty?
int size() number of items
void insert(Item item) insert item
Item delete() return and delete most priority item

(from KW slides, used with permission)


Priority Queue – Implementação com Array
▪ 1ª versão: sem ordenação de elementos por prioridade

pq[] he who is brave is null null null null null

0 1 2 3 4 5 6 7 8 9
N
▪ insert(item): adiciona um novo item em q[N] eg insert(“free”) ~1

pq[] he who is brave is free null null null null

0 1 2 3 4 5 6 7 8 9
N
▪ delete(): procura mais prioritário remove item e desloca p/ esquerda todos ~N
os elementos à sua direita eg mais prioritário é maior na ordem
lexicográfica
1 2 3 4

pq[] he is brave is free null null null null null

0 1 2 3 4 5 6 7 8 9
N
Priority Queue – Implementação

public void insert(Item x){


pq[N++] = x;
}

public Item delete(){


int max = 0;
for (int i = 1; i < N; i++)
if (less(pq[max],pq[i])) max = i;

Item maxItem = pq[max];


pq[max] = pq[--N];
pq[N] = null;
return maxItem;
}
Priority Queue – Implementação com Array
▪ 2ª versão: com ordenação de elementos por prioridade

pq[] brave he is is who null null null null null

0 1 2 3 4 5 6 7 8 9
N
▪ insert(item): desloca p/ direita todos os elementos maiores do que ~N
novo item eg insert(“free”)

4 3 2 1

pq[] brave free he is is who null null null null

0 1 2 3 4 5 6 7 8 9

▪ delete(): remove item em pq[N] eg mais


N
prioritário é maior na ~1
ordem lexicográfica

pq[] brave free he is is null null null null null

0 1 2 3 4 5 6 7 8 9
N
Priority Queue – Implementação

public void insert(Key x){


int i = N++;
for(; i>0 && less(x,pq[i-1]); i--)
pq[i]=pq[i-1];
pq[i] = x;
}

public Key delete(){


Key maxItem = pq[--N];
pq[N] = null;
return maxItem;
}
Priority Queue – Implementação com Array
▪ 3ª versão: com amontoados binários (veremos mais tarde)

▪ insert(item) ~ lg N

▪ delete() ~ lg N


Priority Queue – Implementação
com Linked-List
Priority Queue – Implementação com
Linked-List
▪ 1ª versão: sem ordenação de elementos por prioridade
brave is who he
first
null

▪ insert(item): adiciona um novo nó com item em first eg insert(“free”) ~1

free brave is who he


first
null

▪ delete(): procura nó com o mais prioritário, coloca-lhe item do primeiro nó ~N


do encadeamento e retira primeiro nó do encadeamento eg mais
prioritário é maior na ordem lexicográfica

brave is free he
first
null
Priority Queue – Implementação

public void insert(Item x){


Node oldfirst = first;
first = new Node();
first.item = x;
first.next = oldfirst;
}

public Item delete(){


Node max = first;
for(Node i = first.next; i != null; i = i.next)
if (less(max.item,i.item)) max = i;
Item item = max.item;
max.item = first.item;
first = first.next;
return item;
}
Priority Queue – Implementação com
Linked-List
▪ 2ª versão: com ordenação de elementos por prioridade
who is he brave
first
null

▪ insert(item): adiciona um novo nó com item ordenadamente eg ~N


insert(“free”)

who is he free brave


first
null

▪ delete(): retira primeiro nó do encadeamento eg mais prioritário é ~1


maior na ordem lexicográfica

is he free Brave
first
null
Priority Queue – Implementação
public void insert(Item x){
Node aux = new Node();
aux.item = x;
if(first == null || less(first.item,x)){
aux.next = first;
first = aux;
}
else{ Node i = first;
while(i.next != null && less(x,i.next.item))
i = i.next;
aux.next = i.next;
i.next = aux;
}
}

public Item delMax(){


Item item = first.item;
first = first.next;
return item;
}

Você também pode gostar