// ----------------------------------------------------------- // 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,V> { private BSTMapNode root; // raiz da arvore // Construtor BSTMap() { root = null; } // Getter e Setter para a raiz public BSTMapNode getRoot() {return root;} public void setRoot(BSTMapNode 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 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 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 put(BSTMapNode n, K key, V value) { if (n==null) return new BSTMapNode(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 remove(BSTMapNode 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 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 keys() { LinkedList list = new LinkedList(); keys(root, list); return list; } private void keys(BSTMapNode n, LinkedList l) { if (n==null) return; keys(n.getLeft(), l); l.addLast(n.getKey()); keys(n.getRight(), l); } }