Estruturas de Dados 2019/2020 (CC1007) - DCC/FCUP

Voltar a Lista de Codigo de Exemplo


Dicionarios (com arvores binarias)

No da arvore (BTSMapNode.java)

// -----------------------------------------------------------
// Estruturas de Dados 2019/2020 (CC1007) - DCC/FCUP
// http://www.dcc.fc.up.pt/~pribeiro/aulas/edados1920/
// -----------------------------------------------------------
// No de uma arvore binaria de pesquisa - versao dicionario
// Ultima alteracao: 13/05/2018
// -----------------------------------------------------------

// K e o tipo da chave (key) e V o tipo do valor (value)
// O tipo K tem de implementar o interface Comparable
// (ou te-lo herdado de uma super classe).
public class BSTMapNode<K extends Comparable<? super K>, V> {
   private K key;                 // chave
   private V value;               // valor
   private BSTMapNode<K,V> left;  // Filho esquerdo
   private BSTMapNode<K,V> right; // Filho direito

   // Construtor
   BSTMapNode(K k, V v, BSTMapNode<K,V> l, BSTMapNode<K,V> r) {
      key = k;
      value = v;
      left = l;
      right = r;
   }

   // Getters e Setters
   public K getKey() {return key;}
   public V getValue() {return value;}
   public BSTMapNode<K,V> getLeft() {return left;}
   public BSTMapNode<K,V> getRight() {return right;}
   public void setKey(K k) {key = k;}
   public void setValue(V v) {value = v;}
   public void setLeft(BSTMapNode<K,V> l) {left = l;}
   public void setRight(BSTMapNode<K,V> r) {right = r;}   
}

Dicionario (BSTMap.java)

// -----------------------------------------------------------
// Estruturas de Dados 2019/2020 (CC1007) - DCC/FCUP
// http://www.dcc.fc.up.pt/~pribeiro/aulas/edados1920/
// -----------------------------------------------------------
// Arvore binaria de pequisa - versao dicionario
// Ultima alteracao: 13/05/2018
// -----------------------------------------------------------

import java.util.LinkedList;

// K e o tipo da chave (key) e V o tipo do valor (value)
// O tipo K tem de implementar o interface Comparable
// (ou te-lo herdado de uma super classe).
public class BSTMap<K extends Comparable<? super K>,V> {   
   private BSTMapNode<K,V> root; // raiz da arvore

   // Construtor
   BSTMap() {
      root = null;
   }

   // Getter e Setter para a raiz
   public BSTMapNode<K,V> getRoot() {return root;}
   public void setRoot(BSTMapNode<K,V> r) {root = r;}
   
   // Verificar se o dicionario esta vazio
   public boolean isEmpty() {
      return root == null;
   }

   // Limpa o dicionario (torna-o vazia)
   public void clear() {
      root = null;
   }

   // --------------------------------------------------------
   // Tamanho do dicionario (numero de chaves guardadas)
   public int size() {
      return size(root);
   }

   private int size(BSTMapNode<K,V> n) {
      if (n == null) return 0;
      return 1 + size(n.getLeft()) + size(n.getRight());
   }
   
   // --------------------------------------------------------
   // Devolver o valor associado a uma chave (ou null caso nao exista)
   public V get(K key) {
      return get(root, key);
   }

   private V get(BSTMapNode<K,V> n, K key) {
      if (n==null) return null;
      if (key.compareTo(n.getKey()) < 0) return get(n.getLeft(), key);
      if (key.compareTo(n.getKey()) > 0) return get(n.getRight(), key);
      return n.getValue(); // se nao e menor ou maior, e porque e igual
   }

   // --------------------------------------------------------
   // Adicionar par (chave,valor) ao dicionario
   // Se chave ja existir, substitui o valor antigo pelo novo
   public void put(K key, V value) {
      root = put(root, key, value);
   }

   private BSTMapNode<K,V> put(BSTMapNode<K,V> n, K key, V value) {
      if (n==null)
         return new BSTMapNode<K,V>(key, value, null, null);
      else if (key.compareTo(n.getKey()) < 0) 
         n.setLeft(put(n.getLeft(), key, value));
      else if (key.compareTo(n.getKey()) > 0)
         n.setRight(put(n.getRight(), key, value));
      else
         n.setValue(value);
      return n;
   }
   
   // --------------------------------------------------------
   // Remover uma chave do dicionario
   // Devolve true se conseguiu remover, false caso contrario
   public boolean remove(K key) {
      if (get(key)==null) return false;
      root = remove(root, key);
      return true;
   }

   // Assume-se que elemento existe (foi verificado antes)
   private BSTMapNode<K,V> remove(BSTMapNode<K,V> n, K key) {
      if (key.compareTo(n.getKey()) < 0)
         n.setLeft(remove(n.getLeft(), key));
      else if (key.compareTo(n.getKey()) > 0)
         n.setRight(remove(n.getRight(), key));
      else if (n.getLeft() == null) // Nao tem filho esquerdo
         n = n.getRight();
      else if (n.getRight() == null) // Nao tem filho direito
         n = n.getLeft();
      else { // Dois fihos: ir buscar maximo do lado esquerdo
         BSTMapNode<K,V> max = n.getLeft();
         while (max.getRight() != null) max = max.getRight();
         n.setKey(max.getKey());     // Substituir chave removida
         n.setValue(max.getValue()); // Substituir valor removido
         // Apagar valor que foi para lugar do removido
         n.setLeft(remove(n.getLeft(), max.getKey()));
      }
      return n;
   }

   // --------------------------------------------------------
   // Devolver lista ligada das chaves (usando listas do Java)
   public LinkedList<K> keys() {
      LinkedList<K> list = new LinkedList<K>();
      keys(root, list);
      return list;
   }

   private void keys(BSTMapNode<K,V> n, LinkedList<K> l) {
      if (n==null) return;
      keys(n.getLeft(), l);
      l.addLast(n.getKey());
      keys(n.getRight(), l);
   }
   
}

Exemplo de teste dos dicionarios (TestBSTMap.java)

// -----------------------------------------------------------
// Estruturas de Dados 2019/2020 (CC1007) - DCC/FCUP
// http://www.dcc.fc.up.pt/~pribeiro/aulas/edados1920/
// -----------------------------------------------------------
// Exemplo de utilizacao da um dicionario
// Ultima alteracao: 13/05/2018
// -----------------------------------------------------------

import java.util.LinkedList;

public class TestBSTMap {
   
   public static void main(String[] args) {
      
      // Criacao de um dicionario     
      BSTMap<String,Integer> map = new BSTMap<String,Integer>();
      
      // Inserindo alguns pares (chave,valor)
      map.put("Life", 42);
      map.put("Zero", 0);
      map.put("Infinity", 999);
      
      // Tamanho e conteudo
      System.out.println("size = " + map.size());
      System.out.println("Value of \"Life\" = " + map.get("Life"));
      System.out.println("Value of \"Data\" = " + map.get("Data"));

      // Imprimindo todas chaves      
      LinkedList<String> keys = map.keys();
      System.out.println("keys = " + keys);
      
      // Percorrendo todas as chaves para imprimir os pares (chave,valor)
      System.out.println("All (key,value) pairs:");
      for (String k : map.keys())
         System.out.println("- (" + k + "," + map.get(k) + ")");
      
      // Modificando um valor
      map.put("Life", 22);
      System.out.println("Value of \"Life\" = " + map.get("Life"));
      
      // Apagando um valor
      map.remove("Life");
      System.out.println("Value of \"Life\" = " + map.get("Life"));
   }
}