Anda di halaman 1dari 6

BinarySearchTree.

java
package bst;

public class BinarySearchTree<E extends Comparable<E>> {


// Inner class
private static class Node<E> {
E item;
int count;
Node<E> left, right;
Node(E e) {
this.item = e;
count = 1;
}
}
// Referência para a raiz da árvore
private Node<E> root;
private static<E extends Comparable<E>> boolean less(E e1, E e2) {
return e1.compareTo(e2) < 0;
}
private static<E extends Comparable<E>> boolean equals(E e1, E e2) {
return e1.compareTo(e2) == 0;
}

// Actualiza count
private static<E> void updateCount(Node<E> h) {
h.count = count(h.left) + count(h.right) + 1;
}
////////////////// Contagem de nós da árvore /////////////////////////
private static<E> int countR(Node<E> h) {
if (h == null)
return 0;
return countR(h.left) + countR(h.right) + 1;
}
public int count() { return countR(root); }
private static<E> int count(Node<E> h) {
if (h == null)
return 0;
return h.count;
}
////////////////// Altura da árvore /////////////////////////
private static<E> int height(Node<E> h) {
if (h == null)
return -1;
int u = height(h.left), v = height(h.right);
if (u > v)
return u+1;
else
return v+1;
}
public int height() { return height(root); }

////////////////// Imprimir a árvore na horizontal


/////////////////////////
private static<E> void printNode(E e, int level) {
for (int i = 0; i < level; ++i)
System.out.print("\t");
System.out.println(e);
}
Página 1
BinarySearchTree.java
private static<E> void printR(Node<E> t, int level) {
if (t == null)
return;
printR(t.right, level+1);
printNode(t.item, level);
printR(t.left, level+1);
}
public void print() { printR(root, 0); }

////////////////// Percursos /////////////////////////


/* Percurso prefixo.
* Para implementar os percursos infixo ou posfixo,
* é necessário apenas mudar a impressão do nó raiz
* para ser realizada entre ou após as chamadas
* recorrentes, respectivamente.
*/
private static<E> void prefix(Node<E> h) {
if (h == null)
return;
// Imprime raiz
System.out.println(h.item);
// Imprime sub-árvore esquerda
prefix(h.left);
// Imprime sub-árvore direita
prefix(h.right);
}
public void traverse() {
prefix(root);
}
////////////////// Pesquisa em profundidade ////////////////////
public void depthFirst() {
prefix(root);
}
////////////////// Pesquisa em largura ////////////////////
private static<E> void breadthFirstR(Queue<Node<E>> queue){
if (queue.isEmpty()) return;
else {
Node<E> aux = queue.get();
System.out.println(aux.item);
if (aux.left != null) queue.put(aux.left);
if (aux.right != null) queue.put(aux.right);
breadthFirstR(queue);
}
}
public void breadthFirst() {
Queue<Node<E>> queue = new Queue<Node<E>>();
queue.put(root);
breadthFirstR(queue);
}

////////////////// Procura /////////////////////////


// Algoritmo recorrente
private static<E extends Comparable<E>> Node<E> searchR(Node<E> h, E e) {
if (h == null)
return null;
if (equals(e, h.item))
return h;
if (less(e, h.item))
Página 2
BinarySearchTree.java
return searchR(h.left, e);
else
return searchR(h.right, e);
}
// Algoritmo iterativo
private static<E extends Comparable<E>> Node<E> searchIterative(Node<E> h,
E e) {
while (h != null) {
if (equals(e, h.item))
break;
if (less(e, h.item))
h = h.left;
else
h = h.right;
}
return h;
}
public Node<E> search(E e) {
return searchR(root, e);
}

////////////////// Inserção /////////////////////////


// Algoritmo recorrente
private static<E extends Comparable<E>> Node<E> insertR(Node<E> h, E e) {
if (h == null)
return new Node<E>(e);
if (less(e, h.item))
h.left = insertR(h.left, e);
else
h.right = insertR(h.right, e);
// Actualiza count
updateCount(h);
return h;
}
// Algoritmo iterativo
private void insertIterative(E e) {
if (root == null) {
root = new Node<E>(e);
// Actualiza count
updateCount(root);
return;
}
Node<E> parent = root, child = parent;
while (child != null) {
parent = child;
if (less(e, child.item))
child = child.left;
else
child = child.right;
}

if (less(e, parent.item))
parent.left = new Node<E>(e);
else
parent.right = new Node<E>(e);

// Actualiza count
updateCount(parent);
Página 3
BinarySearchTree.java
}
public void insert(E e) {
root = insertR(root, e);
//insertIterative(v);
}
////////////////// Rotação /////////////////////////

private static<E> Node<E> rotRight(Node<E> x) {


Node<E> aux = x.left;
x.left = aux.right;
aux.right = x;
// Actualiza count
updateCount(x);
updateCount(aux);
return aux;
}
private static<E> Node<E> rotLeft(Node<E> y) {
Node<E> aux = y.right;
y.right = aux.left;
aux.left = y;

// Actualiza count
updateCount(y);
updateCount(aux);
return aux;
}
////////////////// Inserção na raiz /////////////////////////
private static<E extends Comparable<E>> Node<E> insertRootR(Node<E> h, E e)
{
if (h == null)
return new Node<E>(e);
if (less(e, h.item)) {
h.left = insertRootR(h.left, e);
h = rotRight(h);
}
else {
h.right = insertRootR(h.right, e);
h = rotLeft(h);
}
return h;
}
public void insertRoot(E e) {
root = insertRootR(root, e);
}
////////////////// Selecção /////////////////////////
private static<E> E selectR(Node<E> h, int k) {
if (h == null)
return null;
int t = count(h.left);
if (t > k)
return selectR(h.left, k);
if (t < k)
return selectR(h.right, k-t-1);
return h.item;
}
// Assume que índice k é válido
Página 4
BinarySearchTree.java
public E select(int k) {
return selectR(root, k);
}
////////////////// Partição /////////////////////////
private static<E> Node<E> partR(Node<E> h, int k) {
if (h == null)
return null;
int t = count(h.left);
if (t > k) {
h.left = partR(h.left, k);
h = rotRight(h);
}
if (t < k) {
h.right = partR(h.right, k-t-1);
h = rotLeft(h);
}
return h;
}

////////////////// Remoção /////////////////////////


private static<E> Node<E> joinSubtrees(Node<E> left, Node<E> right) {
if (left == null)
return right;
if (right == null)
return left;
right = partR(right, 0);
right.left = left;
// Actualiza count
updateCount(right);
return right;
}
private static<E extends Comparable<E>> Node<E> removeR(Node<E> h, E e) {
if (h == null)
return null;
if (less(e, h.item))
h.left = removeR(h.left, e);
else if (less(h.item, e))
h.right = removeR(h.right, e);
else // equals(e, h.item) == true
h = joinSubtrees(h.left, h.right);
// Actualiza count
updateCount(h);
return h;
}
public void remove(E e) {
root = removeR(root, e);
}
////////////////// Junção /////////////////////////
private static<E extends Comparable<E>> Node<E> joinR(Node<E> a, Node<E> b)
{
if (b == null)
return a;
if (a == null)
return b;
b = insertRootR(b, a.item);
b.left = joinR(a.left, b.left);
Página 5
BinarySearchTree.java
b.right = joinR(a.right, b.right);
// Actualiza count
updateCount(b);
return b;
}
public void join(BinarySearchTree<E> b) {
root = joinR(root, b.root);
}

////////////////// Main method ////////////////////


public static void main(String[] args) {
BinarySearchTree<Integer> bst = new BinarySearchTree<Integer>();
//int[] values = {12, 5, 2, 8, 6, 19, 17, 18, 16};
//int[] values = {12, 5, 2, 19, 17, 18, 16};
int[] values = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
// Inserção
for (int i = 0; i < values.length; ++i) {
bst.insert(values[i]);
}
// Imprime árvore
bst.print();

// Remoção
int rem = 5;
//int rem = 2;
//int rem = 12;
//int rem = 17;
bst.remove(rem);

// Remoção
System.out.println("Apos remocao de " + rem);
bst.print();

// Selecção
System.out.println("[Seleccao] k=0: " + bst.select(0));
System.out.println("[Seleccao] k=mediana: " +
bst.select(bst.count()/2));
/*
// Percurso
System.out.println("Percurso prefixo");
bst.traverse();
// Percurso em profundidade
System.out.println("Percurso em profundidade");
bst.depthFirst();

// Percurso em largura
System.out.println("Percurso em largura");
bst.breadthFirst();
*/
}
}
Página 6

Anda mungkin juga menyukai