Вы находитесь на странице: 1из 39

Tipos de Dados Abstractos

Algoritmos e Estuturas de Dados

Ctia Vaz

Tipos Abstractos
Um tipo abstracto :
um tipo genrico de dados, dos quais no se conhece os valores uma interface que define os acessos e as operaes sobre os dados O conjunto das propriedades algbricas da interface, que delimitam as possveis implementaes.

Um programa que usa um tipo abstracto um cliente. O cliente no tem acesso implementao. Um programa que especifique o tipo de dados uma implementao.
Ctia Vaz

Pilha - Stack
Operaes abstractas:
inicializao; colocao de um elemento na pilha; remoo de um elemento (o ltimo colocado); LIFO indicar se pilha est vazia.

interface para uma pilha que contenha inteiros:


public interface intStack{ public boolean empty(); public void push(int i); public int pop(); }

Usando a mesma interface, podem ser definidas vrias implementaes!

Ctia Vaz

Pilha - Stack
Operaes abstractas:
inicializao; colocao de um elemento na pilha; remoo de um elemento (o ltimo colocado); LIFO indicar se pilha est vazia.

interface para uma pilha genrica:


public interface Stack< E > { public boolean isEmpty(); public E push(E i); public E pop(); public E peek(); }

Usando a mesma interface, podem ser definidas vrias implementaes!

Ctia Vaz

Pilha (Stack) - insero

Pilha (Stack) - remoo

Implementao do tipo pilha usando um array


//No compila!! public class StackArray<E> implements Stack<E>{ private E[] s; private int top; public StackArray(int capacity) { s=new E[capacity]; } //! a criao de um array genrico no permitida em Java public boolean isEmpty(){ return top == 0; } public E peek() { if(isEmpty()) throw new EmptyStackException(); return s[top-1]; } public E push(E item) { if( top == s.length ) return null; s[top++] = item; return item; } public E pop() { if(isEmpty()) throw new EmptyStackException(); E e = s[--top]; s[top] = null; return e; } }

Ctia Vaz

Implementao do tipo pilha usando um array


public class StackArray<E> implements Stack<E>{ private E[] s; private int top; public StackArray(int capacity) { s= ( E[] ) new Object[capacity]; //soluo! } public boolean isEmpty(){ return top == 0; } public E peek() { if(isEmpty()) throw new EmptyStackException(); return s[top-1]; } Vantagens: simplicidade. public E push(E item) { Desvantagens: tamanho if( top == s.length ) return null; s[top++] = item; return item; mximo limitado partida. } public E pop() { if(isEmpty()) throw new EmptyStackException(); E e = s[--top]; s[top] = null; return e; } }

Ctia Vaz

Lista Simplesmente Ligada


Uma lista ligada uma coleco de objectos, designados por ns , em que cada um contm dados e apenas uma referncia para outro n, de modo a formarem uma lista. O primeiro n designado por head node. Uma lista ligada diz-se simplesmente ligada quando cada n contm uma referncia para o prximo n. private class Node<E>{
private E data; private Node next; ... } Exemplo: :SLinkedList head :Node item c next :Node item g next

null Ctia Vaz

Implementao do tipo pilha usando um lista ligada


public class StackList<E> implements Stack<E>{ private static class Node<E> { E item; Node<E> next; Node(E i, Node<E> n){ item=i; next = n;} } private Node<E> head; public boolean isEmpty() {return head == null; } public E peek() { Vantagens: if(isEmpty()) throw new EmptyStackException(); - aumenta e diminui consoante se return head.item; } inserem ou removem novos public E push(E item) { elementos na pilha. head = new Node<E>(item, head); Desvantagens: return item; - ocupa mais memria. } - acesso mais lento. public E pop() { if(isEmpty()) throw new EmptyStackException(); E item = head.item; head = head.next; return item; } }

Ctia Vaz

10

Que estrutura de dados escolher?


Depende :
das operaes que sejam mais frequentes no algoritmo a implementar:
Se a escolha for entre arrays e listas, dever-se- escolher:
modificao; listas se forem predominantes as operaes de insero e remoo. Usar listas simples, se estas operaes ocorrem sempre no incio. Usar listas simples com ponteiro adicional para o fim da lista, se a insero se fizer no fim e a remoo no incio.

arrays se forem predominantes as operaes de acesso e

da previsibilidade sobre a memria necessria:


o uso de arrays pressupe que se saiba que memria suficiente; quando no previsvel necessrio gerir a memria dinamicamente. Ctia Vaz
11

Autoboxing
Implementao da pilha genrica:
Permite objectos, no tipos primitivos.

Tipo Wrapper:
Cada tipo primitivo tem um tipo de objecto wrapper ; Ex: Integer o tipo wrapper para int.

Autoboxing: converso automtica entre um tipo primitivo e o seu wrapper.

Ctia Vaz

12

Exerccio
Implemente uma aplicao que leia do standard input uma expresso aritmtica em notao posfixa e calcule o valor da expresso. Considere que:
a expresso apenas envolve os operadores binrios + e x; os operadores e operandos so delimitados por um espao. Exemplo:
598+46**7+* equivalente a: (5*(((9+8)*(4*6))+7)) isto , o seu valor 2075

Ctia Vaz

13

Fila-Queue
Operaes abstractas:
inicializao; colocao de um elemento na fila; remoo de um elemento (FIFO); indicar se fila est vazia.

interface para uma fila :


public interface Queue<E>{ public boolean isEmpty(); public boolean offer(E i); public E poll(); public E remove(); public E peek(); }

Usando a mesma interface, podem ser definidas vrias implementaes!

Ctia Vaz

14

Fila (Queue) - insero

15

Fila (Queue) - remoo

16

Implementao do tipo fila usando um array


public class QueueArray<E> implements Queue<E> { private E[] q; private int size, head, tail; public QueueArray(int maxN) { q=(E[])new Object[maxN]; } public boolean isEmpty() { return size == 0 ;} public boolean offer(E e){ if( size == q.length) return false; q[tail] = e; tail = (tail+1) % q.length; ++size; return true; } public E remove() { if(isEmpty()) throw new NoSuchElementException(); E e= q[head]; q[head]= null; head= (head+1)%q.length; --size; return e; } public E poll(){ return ( size == 0 ) ? null : remove();} public E peek() {return ( size == 0 ) ? null : q[head]; } }

17

Implementao do tipo fila usando uma lista ligada


public class QueueList<E> implements Queue<E> { private static class Node<E> { E item; Node<E> next; Node() { next=this; } Node(E i, Node<E> n) { item=i; next = n; } } private Node<E> tail = new Node<E>(); public boolean isEmpty() { return tail == tail.next; } public boolean offer(E e){ tail.next = new Node<E>( e, tail.next ); tail = tail.next; return true; } public E remove() { if(isEmpty()) throw new NoSuchElementException(); Node<E> rem = tail.next.next; tail.next.next = rem.next; if ( rem == tail ) tail = tail.next; return rem.item; } public E poll() { return ( isEmpty() ) ? null : remove(); } public E peek() { return ( isEmpty()) ? null : tail.next.next.item; } } 18

ADTs
ADTs permitem programao modular:
separam o programa em mdulos mais pequenos; clientes diferentes podem partilhar a mesma ADT.

ADTs permitem o encapsulamento:


mantm-se os mdulos independentes; podem-se substituir as vrias classes que implementam a mesma interface, sem alterar o cliente.

Aspectos do desenho de uma ADT:


especificao formal do problema; a implementao tem tendncia a tornar-se obsoleta.
Ctia Vaz

19

Lista duplamente ligada Insero

20

Lista duplamente ligada Pesquisa

21

Lista duplamente ligada Remoo

22

Lista Duplamente Ligada


public interface DList<E> extends Iterable<E>{ public int size(); public boolean isEmpty(); public void add(E e); public boolean remove(E e); }

Ctia Vaz

23

Iteradores
public interface Iterable<E> { public Iterator<E> iterator(); } public interface Iterator<E> { public boolean hasNext(); public E next(); public void remove(); }

Ctia Vaz

24

Lista Duplamente Ligada


public class DLinkedList1<E> implements DList<E> { private static class DNode<T> { public DNode<T> next, prev; public T key; public DNode() { } public DNode(T e ) { key=e; } } protected int size; protected DNode<E> head; public int size() { return size;} public boolean isEmpty(){ return head == null;} public void add(E e) { // Adiciona o elemento no inicio da lista ligada DNode<E> n=new DNode<E>(e); if(head!=null){ n.next=head; head.prev=n;} head=n; } //(continua...) }

Ctia Vaz

25

Lista Duplamente Ligada


public class DLinkedList1<E> implements DList<E> { //(continuao...) // Remove o primeiro elemento da lista igual a e public boolean remove (E e){ DNode aux=search(e); if(aux!=null){ if(aux.prev != null) {aux.prev.next = aux.next;} else{head = aux.next;} if(aux.next != null){ aux.next.prev = aux.prev;} return true; } else return false; } protected DNode<E> search( E e ){ DNode<E> aux = head; while( aux != null && !aux.key.equals(e)) aux=aux.next; return aux; } //(continua...) }

Ctia Vaz

26

Lista Duplamente Ligada


public class DLinkedList1<E> implements DList<E> { //(continuao...) public static <E> void show(DNode<E> l){ System.out.print("< "); while(l != null){ System.out.print(l.key+" "); l = l.next;} System.out.println(">"); } public void reverse() { DNode<E> iter = head, aux; while( iter != null ) { head = iter; aux = iter.next; iter.next = iter.prev; iter.prev = aux; iter = aux; } } //(continua...) }

Ctia Vaz

27

Lista Duplamente LigadaIteradores


public class DLinkedList1<E> implements DList<E> { //(continuao...) private class LinkedIterator implements Iterator<E> { // N dos dados retornados pelo next() seguinte. protected DNode<E> node = head; /* N retornado pelo next() anterior. Como inicialmente no existiu next() referecia null. Depois de um remove() permite assinalar que no existe next() anterior.*/ protected DNode<E> prev = null; // Retorna true se existem mais elementos para iterar. public boolean hasNext() { return node != null; } // Retorna o elemento da posio corrente e avana. public E next() { if ( node == null )throw new NoSuchElementException(); prev = node; node = node.next; // Avana return prev.key; } //(continua...) }

Ctia Vaz

28

Lista Duplamente LigadaIteradores


public class DLinkedList1<E> implements DList<E> { //(continuao...) public void remove() { // Se a ltima operao no foi next() lana excepo if ( prev == null ) throw new IllegalStateException(); // Remove o n do elemnto retornado pelo ltimo next DLinkedList1.this.remove(prev); prev = null; // Assinala que a operao anterior no foi um next() } }//termina a classe LinkedIterator public Iterator<E> iterator() {return new LinkedIterator(); } protected void remove( DNode<E> rem ){ if ( rem.next != null) rem.next.prev=rem.prev; if ( rem.prev != null ) rem.prev.next=rem.next; else head = rem.next; --size; } //(...) }

Ctia Vaz

29

Lista com sentinela Insero

30

Lista com sentinela Remoo

31

Lista com sentinela Pesquisa

32

Lista Duplamente Ligada


public interface DCList<E>{ public int size(); public boolean isEmpty(); public void add(E e); public boolean remove(E e); }

Ctia Vaz

33

Lista Duplamente Ligada com Sentinela e Circular


public class DLinkedList3<E> implements DCList<E>{ private static class DNode<E> { public DNode<E> next, prev; public E key; public DNode() { } public DNode(E e ) { key=e; } } private int size; protected DNode<E> dummy; public DLinkedList3() { dummy=new DNode<E>(); dummy.next= dummy.prev = dummy;} public int size() { return size;} public boolean isEmpty() { return dummy.next == dummy;} //(continua...) }

Ctia Vaz

34

Lista Duplamente Ligada com Sentinela e Circular


public class DLinkedList3<E> implements DCList<E> { //(continuao...) public E getFirst() { return dummy.next.key; } public E getLast() { return dummy.prev.key; } // Adiciona o elemento no fim da lista ligada public void add(E e) { DNode<E> n=new DNode<E>(e); ++size; n.prev=dummy.prev; n.next=dummy; dummy.prev.next=n; dummy.prev=n; } public boolean remove(E e){ DNode<E> aux=search(e); if(aux!=null){ aux.next.prev=aux.prev; aux.prev.next=aux.next; return true;} return false; } //(continua..) }

Ctia Vaz

35

Lista Duplamente Ligada com Sentinela e Circular


public class DLinkedList3<E> implements DCList<E> { //(continuao...) public DNode<E> search(E e){ DNode<E> aux=dummy.next; while(aux!=dummy){ if(aux.key.equals(e)){ return aux;} aux=aux.next; } return null; } //(continua...) }

Ctia Vaz

36

Lista Duplamente Ligada com Sentinela e Circular


public class DLinkedList3<E> implements DCList<E> { //(...)/*Move os ns da lista 2 para a lista 1. Assume que as duas listas esto ordenadas *pela ordem dada pelo comparador. A lista 1 permanece ordenada e a lista 2 fica vazia.*/ public static < E > DNode<E> merge( DNode<E> dummy1, DNode<E> dummy2, Comparator<E> cmp) { DNode<E> head1 = dummy1.next; DNode<E> head2 = dummy2.next; while (head1 != dummy1 && head2 != dummy2 ) { if ( cmp.compare( head1.key, head2.key) <= 0 ) head1= head1.next; else { head2.prev = head1.prev; head1.prev.next = head2; head1.prev=head2; head2 = head2.next; head1.prev.next = head1; } } if ( head2 != dummy2 ) { head1.prev.next = head2; head2.prev = head1.prev; head1.prev = dummy2.prev; dummy2.prev.next = head1; } dummy2.next = dummy2.prev = dummy2; return dummy1; Ctia Vaz }} 37

Lista Duplamente Ligada com Sentinela e Circular


public class DLinkedList3<E> implements DList<E>{ //(...)/*Move os ns da lista 2 para a lista 1. Assume que as duas listas esto ordenadas *pela ordem dada pelo comparador. A lista 1 permanece ordenada e a lista 2 fica vazia.*/ public static < E > DNode<E> merge( DNode<E> dummy1, DNode<E> dummy2, Comparator<E> cmp) { DNode<E> head1 = dummy1.next; DNode<E> head2 = dummy2.next; while (head1 != dummy1 && head2 != dummy2 ) { if ( cmp.compare( head1.key, head2.key) <= 0 ) head1= head1.next; else { head2.prev = head1.prev; head1.prev.next = head2; head1.prev=head2; head2 = head2.next; head1.prev.next = head1; } } if ( head2 != dummy2 ) { head1.prev.next = head2; head2.prev = head1.prev; head1.prev = dummy2.prev; dummy2.prev.next = head1; } dummy2.next = dummy2.prev = dummy2; return dummy1; Ctia Vaz }} 38

Exerccio
Implementar o algoritmo merge sort para duas listas duplamente ligadas.

Ctia Vaz

39

Вам также может понравиться