Listas Duplamente Encadeadas
Profs Prog2 e Lab2 Unisinos
Listas Duplamente Encadeadas
• Cada nó possui dois ponteiros:
previous
element
next
nó
• Vantagem: simplifica certas operações e permite
percorrer a lista nos dois sentidos.
• Desvantagem: gasta mais espaço do que a
simplesmente encadeada (mais um ponteiro em cada
nó) e pode tornar mais complexas certas operações.
Programação II
2
Lista encadeada com referência
ao ultimo elemento da lista
head
Apontador para o
primeiro nó da lista
Apontador para o
último nó da lista
null
início de lista
tail
null
final de lista
Programação II
3
classe DNode
public class DNode<E> {
private E element;
private DNode<E> next;
private DNode<E> previous;
public DNode(E element) {
this (element, null, null);
}
public DNode(E element, DNode<E> next,
DNode<E> previous) {
super();
this.element = element;
this.next = next;
this.previous = previous;
}
public E getElement() {
return element;
}
public void setElement(E element) {
this.element = element;
}
public DNode<E> getNext() {
return next;
}
public void setNext(DNode<E> next) {
this.next = next;
}
public DNode<E> getPrevious() {
return previous;
}
public void setPrevious(DNode<E> previous)
{
this.previous = previous;
}
} // end of class
previous
element
next
nó
Programação II
4
class DLinkedList (1)
public class DLinkedList<E> {
protected DNode<E> head; //nodo cabeça da lista
protected DNode<E> tail; //nodo cauda da lista
protected long size; //número de nodos da lista
public DLinkedList() {
size = 0;
head = tail = null;
}
public boolean isEmpty() {
return head == null;
}
head
tail
Programação II
5
class DLinkedList (2)
public E getFirst() throws UnderflowException {
if (isEmpty())
throw new UnderflowException();
return head.getElement();
}
public E getLast() throws UnderflowException {
if (isEmpty())
throw new UnderflowException();
return tail.getElement();
}
tail
head
b
c
d
e
Programação II
6
class DLinkedList (3)
public void addFirst(E insertItem) {
DNode<E> n = new DNode<E>(insertItem);
}
tail
head
n
b
c
d
e
a
Programação II
class DLinkedList (3)
public void addFirst(E insertItem) {
DNode<E> n = new DNode<E>(insertItem);
if (isEmpty()) {
head = tail = n;
}
}
tail
head
n
a
Programação II
class DLinkedList (3)
public void addFirst(E insertItem) {
DNode<E> n = new DNode<E>(insertItem);
if (isEmpty()) {
head = tail = n;
}
else {
head.setPrevious(n);
n.setNext(head);
head = n;
}
size++;
}
head
n
b
c
d
tail
e
a
Programação II
class DLinkedList (4)
public void addLast(E insertItem) {
DNode<E> n = new DNode<E>(insertItem);
if (isEmpty()) {
head = tail = n;
}
else {
tail.setNext(n);
n.setPrevious(tail);
tail = n;
}
size++;
head
}
b
c
tail
d
e
n
x
Programação II
class DLinkedList (5)
public E removeFirst() throws UnderflowException {
if (isEmpty()) {
throw new UnderflowException();
}
E removedItem = head.getElement();
if (head == tail) {
head = tail = null;
}
return removedItem;
}
head
removedItem
Programação II
tail
e
null
12
class DLinkedList (5)
public E removeFirst() throws UnderflowException {
if (isEmpty()) {
throw new UnderflowException();
}
E removedItem = head.getElement();
if (head == tail) {
head = tail = null;
}
else {
head = head.getNext();
head.setPrevious(null);
}
size--;
return removedItem;
head
}
b
c
Programação II
tail
d
e
13
class DLinkedList (6)
public E removeLast() throws UnderflowException {
if (isEmpty()) {
throw new UnderflowException();
}
E removedItem = tail.getElement();
if (head == tail) {
head = tail = null;
}
else {
DNode<E> penultimo = tail.getPrevious();
tail = penultimo;
tail.setNext(null);
}
size--;
return removedItem;
penultimo
head
}
b
c
Programação II
d
tail
e
14
class DLinkedList (7)
public void print() {
DNode<E> current = head;
while (current != null) {
System.out.println(current.getElement());
current = current.getNext();
}
}
head
2
current =null
3
4
tail
5
Programação II
15
Testando a lista
public static void main(String args[]) {
DLinkedList<Integer> list = new DLinkedList<Integer>();
list.addLast(2);
list.addLast(4);
list.addLast(6);
list.addLast(1);
list.addLast(8);
list.addLast(9);
list.print();
try {
list.removeFirst();
} catch (UnderflowException e) {
e.printStackTrace();
}
list.print();
}
Programação II
16
Exercício 1
• Na classe DLinkedList (implementação de lista
duplamente encadeada), implementar um método
com a seguinte assinatura:
– “private Node<E> find(E key)”.
• Este método deve buscar na lista o nó de chave key
e retorná-lo.
Programação II
17
Exercício 1
public DNode<E> find(E key) {
DNode<E> current = head;
while (current != null) {
if (current.getElement().equals(key)) {
return current;
}
current = current.getNext();
}
return null;
}
Programação II
18
Exercício 2
• Na classe DLinkedList (implementação de lista
duplamente encadeada), implementar um método
com a seguinte assinatura:
– “public boolean addBefore (E el, E key)”.
• Este método deve inserir na lista um nó com chave el
na posição anterior ao nó que contenha a chave key.
Programação II
19
Exercício 2
public boolean addBefore(E el, E chave) {
DNode<E> current = find(chave);
if (current == null) {
return false;
} else if (current == head) {
addFirst(el);
return true;
} else {
DNode<E> n2 = new DNode<E>(el);
DNode<E> before = current.getPrevious();
before.setNext(n2);
n2.setPrevious(before);
n2.setNext(current);
current.setPrevious(n2);
return true;
}
}
Programação II
20
Download

Listas - Unisinos