Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- / Árvore AVL com Iteração e Comparação
- /
- / Especialidades:
- / -Auto balanceamento;
- / -É tipável;
- / -Possui um Comparator como atributo, ou seja, você decide como os elementos serão ordenados;
- / -Caso haja uma mudança no tipo de comparação, a árvore se re-ordena pelo novo comparador;
- / -É possível fazer busca por índice de posição;
- / -É possível fazer remoção por índice de posição;
- / -Guarda o número de nós adicionados;
- */
- public class Link<E> {
- private E content;
- private int balancing;
- private Link left;
- private Link right;
- private Link father;
- public Link(E content) {
- this.content = content;
- this.balancing = 0;
- this.left = null;
- this.right = null;
- }
- public E getContent() {
- return content;
- }
- public void setContent(E content) {
- this.content = content;
- }
- public int getBalancing() {
- return balancing;
- }
- public void setBalancing(int balancing) {
- this.balancing = balancing;
- }
- public Link getLeft() {
- return left;
- }
- public void setLeft(Link left) {
- this.left = left;
- }
- public Link getRight() {
- return right;
- }
- public void setRight(Link right) {
- this.right = right;
- }
- public Link getFather() {
- return father;
- }
- public void setFather(Link father) {
- this.father = father;
- }
- }
- public class TreeIterator implements Iterator{
- private Stack<Link> stack = new Stack<>();
- public TreeIterator(Link root) {
- push(root);
- }
- @Override
- public boolean hasNext() {
- return !stack.isEmpty();
- }
- @Override
- public Link next() {
- Link node = stack.pop();
- push(node.getRight());
- return node;
- }
- private void push(Link node) {
- while (node != null) {
- stack.push(node);
- node = node.getLeft();
- }
- }
- }
- public class TreeLink<Generic> {
- private Link<Generic> root;
- private int size;
- private Comparator comparator;
- public TreeLink(Comparator comparator) {
- this.comparator = comparator;
- }
- public void addInTree(Generic content) {
- if(isEmpty()) addInRoot(content);
- else {
- Link<Generic> newLink = new Link<>(content);
- addInBranch(root, newLink);
- }
- size++;
- }
- public Generic removeByContent(Generic content) {
- Link<Generic> find = search(content);
- removeFoundLink(find);
- size--;
- return find.getContent();
- }
- public Generic removeByPosition(int index) {
- if(index > size || index < 0) return null;
- else {
- return removeByContent(getByPosition(index));
- }
- }
- public Link search(Generic content) {
- Link aux = root;
- if(aux != null) {
- while(aux != null) {
- if(comparator.compare(content, aux.getContent()) == 0) {
- return aux;
- }
- else if(comparator.compare(content, aux.getContent()) > 0) aux = aux.getRight();
- else aux = aux.getLeft();
- }
- }
- return null;
- }
- public void removeAll() {
- for(int i = 0; i < size; i++)
- removeByContent(getByPosition(i));
- }
- public Generic getByPosition(int index) {
- if(index > size || index < 0) return null;
- else {
- Iterator it = iterator();
- for(int i = 0; i < index; i++)
- it.next();
- return (Generic) ((Link)it.next()).getContent();
- }
- }
- public boolean isEmpty() {
- return size == 0;
- }
- public int size() {
- return size;
- }
- public Link getRoot() {
- return root;
- }
- public void display() {
- inOrder(root);
- }
- public void setComparator(Comparator comparator) {
- this.comparator = comparator;
- TreeLink newTree = new TreeLink(comparator);
- for(int i = 0; i < size; i++)
- newTree.addInTree(removeByPosition(i));
- root = newTree.getRoot();
- }
- private void addInRoot(Generic content) {
- root = new Link<>(content);
- }
- private void addInBranch(Link current, Link newLink) {
- if(comparator.compare(newLink.getContent(), current.getContent()) < 0) {
- if(current.getLeft() == null) {
- current.setLeft(newLink);
- newLink.setFather(current);
- checkBalance(current);
- }
- else {
- addInBranch(current.getLeft(), newLink);
- }
- }
- else if(comparator.compare(newLink.getContent(), current.getContent()) > 0) {
- if(current.getRight() == null) {
- current.setRight(newLink);
- newLink.setFather(current);
- checkBalance(current);
- }
- else {
- addInBranch(current.getRight(), newLink);
- }
- }
- }
- private void checkBalance(Link anyLink) {
- setBalancing(anyLink);
- int balancing = anyLink.getBalancing();
- if(balancing == -2) {
- if(height(anyLink.getLeft().getLeft()) >= height(anyLink.getLeft().getRight())) {
- anyLink = singleRotationRight(anyLink);
- }
- else {
- anyLink = doubleRotationRight(anyLink);
- }
- }
- else if(balancing == 2) {
- if(height(anyLink.getRight().getRight()) >= height(anyLink.getRight().getLeft())) {
- anyLink = singleRotationLeft(anyLink);
- }
- else {
- anyLink = doubleRotationLeft(anyLink);
- }
- }
- if(anyLink.getFather() != null) {
- checkBalance(anyLink.getFather());
- }
- else {
- this.root = anyLink;
- }
- }
- private void removeFoundLink(Link find) {
- Link aux1;
- if(find.getLeft() == null || find.getRight() == null) {
- if(find.getFather() == null) {
- root = null;
- find = null;
- return;
- }
- aux1 = find;
- }
- else {
- aux1 = nextLink(find);
- find.setContent(aux1.getContent());
- }
- Link aux2;
- if(aux1.getLeft() != null) {
- aux2 = aux1.getLeft();
- }
- else {
- aux2 = aux1.getRight();
- }
- if(aux2 != null) {
- aux2.setFather(aux1.getFather());
- }
- if(aux1.getFather() == null) {
- root = aux2;
- }
- else {
- if(aux1 == aux1.getFather().getLeft()) {
- aux1.getFather().setLeft(aux2);
- }
- else {
- aux1.getFather().setRight(aux2);
- }
- checkBalance(aux1.getFather());
- }
- aux1 = null;
- }
- private Link singleRotationLeft(Link anyLink) {
- Link linkRight = anyLink.getRight();
- linkRight.setFather(anyLink.getFather());
- anyLink.setRight(linkRight.getLeft());
- if(anyLink.getRight() != null) {
- anyLink.getRight().setFather(anyLink);
- }
- linkRight.setLeft(anyLink);
- anyLink.setFather(linkRight);
- if(linkRight.getFather() != null) {
- if(linkRight.getFather().getRight() == anyLink) {
- linkRight.getFather().setRight(linkRight);
- }
- else if(linkRight.getFather().getLeft() == anyLink) {
- linkRight.getFather().setLeft(linkRight);
- }
- }
- setBalancing(anyLink);
- setBalancing(linkRight);
- return linkRight;
- }
- private Link singleRotationRight(Link anyLink) {
- Link linkLeft = anyLink.getLeft();
- linkLeft.setFather(anyLink.getFather());
- anyLink.setLeft(linkLeft.getRight());
- if(anyLink.getLeft() != null) {
- anyLink.getLeft().setFather(anyLink);
- }
- linkLeft.setRight(anyLink);
- anyLink.setFather(linkLeft);
- if(linkLeft.getFather() != null) {
- if(linkLeft.getFather().getRight() == anyLink) {
- linkLeft.getFather().setRight(linkLeft);
- }
- else if(linkLeft.getFather().getLeft() == anyLink) {
- linkLeft.getFather().setLeft(linkLeft);
- }
- }
- setBalancing(anyLink);
- setBalancing(linkLeft);
- return linkLeft;
- }
- private Link doubleRotationRight(Link anyLink) {
- anyLink.setLeft(singleRotationLeft(anyLink.getLeft()));
- return singleRotationRight(anyLink);
- }
- private Link doubleRotationLeft(Link anyLink) {
- anyLink.setRight(singleRotationRight(anyLink.getRight()));
- return singleRotationLeft(anyLink);
- }
- private Link nextLink(Link anyLink) {
- if (anyLink.getRight() != null) {
- Link aux = anyLink.getRight();
- while (aux.getLeft() != null)
- aux = aux.getLeft();
- return aux;
- }
- else {
- Link aux = anyLink.getFather();
- while (aux != null && anyLink == aux.getRight()) {
- anyLink = aux;
- aux = anyLink.getFather();
- }
- return aux;
- }
- }
- private int height(Link anyLink) {
- if (anyLink == null) {
- return -1;
- }
- if (anyLink.getLeft() == null && anyLink.getRight() == null) {
- return 0;
- }
- else if (anyLink.getLeft() == null) {
- return 1 + height(anyLink.getRight());
- }
- else if (anyLink.getRight() == null) {
- return 1 + height(anyLink.getLeft());
- }
- else {
- return 1 + Math.max(height(anyLink.getLeft()), height(anyLink.getRight()));
- }
- }
- private void setBalancing(Link anyLink) {
- anyLink.setBalancing(height(anyLink.getRight()) - height(anyLink.getLeft()));
- }
- private void inOrder(Link anyLink) {
- if (anyLink == null) {
- return;
- }
- inOrder(anyLink.getLeft());
- System.out.println(anyLink.getContent());
- inOrder(anyLink.getRight());
- }
- private Iterator iterator() {
- return new TreeIterator(root);
- }
- }
Add Comment
Please, Sign In to add comment