AULA TEÓRICA 17 Tema 14. Lista duplamente encadeada. Fila. Ø Lista duplamente encadeada Ø Fila (Queue) 1 Lista Duplamente Encadeada Frequentemente as listas encadeadas são implementadas como listas duplamente encadeadas – cada nó contém uma referência para o próximo nó na lista e uma referência para o nó anterior na lista. O primeiro e o último nó de uma lista duplamente ligada possuem a referência null. 2 public class UmNo { private int valor; public UmNo next, prev; public UmNo(int valor,UmNo next,UmNo prev) { this.valor = valor; this.next = next; this.prev = prev; } public UmNo() { this(0,null,null); } public void setValor(int valor) { this.valor = valor; } public String toString() { return valor+""; } } ====================================== public class ListaDupla { private UmNo head,tail; //referencias para cabeça e para cauda da lista public ListaDupla() { head = null; tail = null; } //lista ainda nao existe public void addOnTop(int novoValor) //adiciona ao topo { UmNo novo = new UmNo(); //criação de um novo elemento - nó novo.setValor(novoValor); 3 if (head == null) //verifique se lista nao tem nos { head = novo; tail = novo; novo.next = null; novo.prev=null; } else { novo.next = head; head.prev = novo; head = novo; novo.prev = null; } } public void addLast(int novoValor) { UmNo novo = new UmNo(); novo.setValor(novoValor); if (head == null) { head = novo; tail = novo; novo.next = null; novo.prev=null; } else { tail.next = novo; novo.prev = tail; tail = novo; tail.next = null; } } 4 public String printListfromTop() { UmNo aux = head; //referencia auxiliar, aponta ao topo da lista String str=""; if (aux == null) str="Lista nao existe"; else while (aux != null) { str+=aux.toString(); aux = aux.next; //move para o nó seguinte } return str; } public String printListfromEnd() { UmNo aux = tail; //referencia auxiliar, aponta ao fim da lista String str=“”; if (aux == null) str="Lista nao existe"; else while (aux != null) { String str="";; aux = aux.prev; //move para o nó anterior } return str; } 5 public void removeHead() { if (head == null) System.out.println ("Lista nao exise!"); else if (head.next == null) //existe somente um elemento { head = null; tail = null; } else { head = head.next; head.prev = null; } } public void removeTail() { if (head == null) System.out.println ("Lista nao existe!"); else if (tail.prev == null) //existe somente um elemento { head = null; tail = null; } else { tail = tail.prev; tail.next = null; } } } 6 Vantagens: podemos deslocar-se para o nó anterior ou para o nó seguinte, ou a um nó dado com igual facilidade; permite-nos remover um nó qualquer da lista em tempo constante, usando apenas uma referência para esse nó. Desvantagens: Uma lista duplamente ligada duplica o espaço necessário para guardar referências para nós e duplica o número de manipulações de referências por cada operação básica. FILA (Queue ADT) Uma fila é semelhante a uma lista, em que elementos (nós) são inseridos no fim e removidos do topo da fila. Filas utilizam processamento do tipo FIFO (first-in, first-out). Todos os elementos de uma fila são do mesmo tipo. Para aceder a um elemento da fila, é necessário que ele esteja no topo da fila, caso contrário, os elementos que estiverem na sua frente devem ser retirados antes. Numa fila se mantém uma referência para o primeiro e para o último nó. O acesso aos elementos da fila é feito pela extermidade oposta à da inserção, ou seja: 7 As operações de inserção e remoção são conhecidas como enqueue e dequeue. As filas têm muitas aplicações em sistemas de computador. Quando um aplicativo é atendido os pedidos dos outros aplicativos são colocados em uma fia. As filas também são utilizadas para suportar spooling de impressão. Os pacotes de informações também esperam em filas em redes de computadores. public class QueueNode { private Object info; public QueueNode link; public QueueNode() {} public QueueNode(Object i) { info = i; link = null;} public QueueNode(Object i, QueueNode l) { info = i; link = l; } } 8 public class Queue { private QueueNode front; private QueueNode rear; private int size; //referencia para o topo //reference para o fim //tamanho de fila // Para inserir um item na fila : public void insert(Object item) { if (isEmpty()) { rear = new QueueNode(item); front = rear; } else { rear.link = new QueueNode(item); rear = rear.link; } size++; } 9 //Método que remove elemento que está no topo da fila: public Object remove() { QueueNode oldFront = front; //referencia ao topo Object item = peek(); //obtém 1o elemento. front = front.link; // Remove 1o nó da fila oldFront.link = null; // Desconectá-o da fila size--; // Decrementa variavel size return item; } public Object peek() { if (isEmpty()) throw new NullPointerException(); return front.info; } public boolean isEmpty() { return (size == 0); } public int getSize() { return size; } } 10 public class QueueTest { public static void main (String[] args) { Queue q = new Queue(); q.insert("Maria"); q.insert("Joao"); q.insert("Carlos"); q.insert("Olga"); String name = (String) q.remove(); System.out.println(name); q.insert("Sergio"); name = (String) q.remove(); System.out.println(name); System.out.println("Tamanho da fila: "+q.getSize()); } } Exemplo: armazenar informação sobre livros numa fila dinâmica. Efecturar operações de inserção, remoção dum livro e visualização. 11 public class UmLivroNode { private String titulo; private int quant; private float preco; public UmLivroNode link; public UmLivroNode(String titulo,int quant,float preco,UmLivroNode l) { this.titulo = titulo; this.quant = quant; this.preco = preco; link = l; } public UmLivroNode(String titulo,int quant,float preco) { this.titulo = titulo; this.quant = quant; this.preco = preco; } public void setTitulo (String titulo) { this.titulo = titulo; } public void setQuant(int quant) { this.quant = quant; } public void setPreco(float preco) { this.preco = preco; } public float getPreco() { return preco; } public int getQuant () { return quant; } public String toString() 12 { return titulo+ "\t" +quant + "\t" + preco; } } public class Fila { private UmLivroNode front; private UmLivroNode rear; private int size; // referencia à cabeça // referencia à cauda public void insert(String titulo,int quant,float preco) { if (isEmpty()) //fila está vazia { // Conecta referencias da cabeça e cauda ao novo nó rear = new UmLivroNode(titulo,quant,preco); front = rear; } else //caso fila não está vazia { rear.link = new UmLivroNode(titulo,quant,preco); rear = rear.link; } size++; } public Object remove() { UmLivroNode oldFront = front; Object item = peek(); // devolve primeiro item // Remove primeiro elemento front = front.link; // apaga primeiro nó oldFront.link = null; // desconecta ele da fila size--; return item; } 13 /* Retorna elemento da cabeça da fila precondition : Fila foi criada postcondition: Se fila não está vazia, retorna o primeiro elemento da fila */ public Object peek() { if (isEmpty()) throw new NullPointerException(); return front.toString(); } public boolean isEmpty() { return (size == 0); } public int getSize() { return size; } public void removeAndDisplay() { String str=""; if (isEmpty()) System.out.println ("Fila nao existe"); else while( !isEmpty()) // remove e visualiza todos elementos removidos da fila { str = (String)remove(); System.out.println(str); } } } 14 public class TestandoFila { public static void main (String[] args) { FilaLivros q = new FilaLivros(); q.insert("Apontamentos de Java",10,1200); q.insert("Programação em Java",15,1300); q.insert("Algoritmos",20,1400); q.insert("Sistemas Operativos",25,1500); q.insert("Introdução a programação",30,1546); System.out.println("\nFila contem " +q.getSize()+" elementos\n"); q.removeAndDisplay(); System.out.println("\nFila contem " +q.getSize()+" elementos\n"); } } 15 Referência bibliográfica: António José Mendes; Maria José Marcelino. “Fundamentos de programação em Java 2”. FCA. 2002. Elliot Koffman; Ursula Wolz. “Problem Solving with Java”. 1999. F. Mário Martins; “Programação Orientada aos objectos em Java 2”, FCA, 2000, John Lewis, William Loftus; “Java Software Solutions: foundation of program design”, 2nd edition, Addision-Wesley John R. Hubbard. “Theory and problems of programming with Java”. Schaum’s Outline series. McGraw-Hill. H. Deitel; P. Deitel. “Java, como programar”. 4 edição. 2003. Bookman. Rui Rossi dos Santos. “Programando em Java 2– Teoria e aplicações”. Axcel Books. 2004 16